学习目标:
看过我前面的文章应该知道怎么制作开头和结尾,这里我简单把效果给大伙看一下
我用的游戏分辨率是4∶3,因此我们要改变Canvas的的Cavans Scale为X1440 Y1080
结束的场景也一样
接着我们编写一个脚本来管理场景的切换,创建一个空物体SceneLoader并将脚本
LoadSceneManage挂载到上面,并在按钮上挂载这些Public函数(我之前的入门文章有教程)
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class LoadSceneManage : MonoBehaviour { public void LoadNextScene() { int currentScene = SceneManager.GetActiveScene().buildIndex; SceneManager.LoadScene(currentScene+1); } public void RestartScene() { SceneManager.LoadScene(0); FindObjectOfType<GameStatus>().ResetGame(); } public void QuitGame() { Application.Quit(); } }
学习内容:
接下来的内容才是重量级,教大家如何搭建好一个关卡场景
我们先创建一个Scene就叫Level1吧
先从Github中下载好素材:Commits · CompleteUnityDeveloper/05-Block-Breaker/CompleteUnityDeveloper/05-Block-Breaker/commits?author=rickdavidson
然后再import把素材导入到Project面板中
别忘了修改Sprite图片的Pixel Per Unit
然后把场景拖进来并Reset改好名字叫Background
创建好板子Paddle和Ball
创建好Paddle.cs脚本挂载在Paddle上
脚本如下:
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class Paddle : MonoBehaviour { [SerializeField] float minX = 1F; [SerializeField] float maxX = 14F; [SerializeField] float screenWidthInUnits = 16f;
GameStatus theGameSession; //管理UI更新(待会用上) Ball theBall; void Start() { theGameSession = FindObjectOfType<GameStatus>(); theBall = FindObjectOfType<Ball>(); } void Update() { Vector2 paddlePos = new Vector2(transform.position.x,transform.position.y); paddlePos.x = Mathf.Clamp(GetXPos(), minX, maxX); //限制板子移动的X范围 transform.position = paddlePos; }
private float GetXPos() { if (theGameSession.IsAutoBackEnabled()) //当系统AI自动操作时 { return theBall.transform.position.x; } else { return Input.mousePosition.x / Screen.width * screenWidthInUnits;//相当于鼠标移动的x轴的坐标乘以整个游戏屏幕的宽度得到它的世界坐标 } } }
给个Polygon Collider2D
然后再编写Ball的脚本
Ball.cs如下:
using UnityEngine;
public class Ball : MonoBehaviour { [SerializeField] Paddle paddle1; //选择你要绑定的板子 [SerializeField] float xPush = 2f; [SerializeField] float yPush = 15f; [SerializeField] bool hasStarted = false;
AudioSource myAudioSource; [SerializeField] AudioClip[] ballSounds;
[SerializeField] float randomFactor = 0.5f;
Rigidbody2D myRigibody2D; Vector2 paddleToBallVector;
void Start() { myRigibody2D = GetComponent<Rigidbody2D>(); myAudioSource = GetComponent<AudioSource>(); paddleToBallVector = transform.position - paddle1.transform.position; //获取球和板子的向量方向 }
void Update() { if (!hasStarted) //当游戏还没有开始时就每帧执行 { LockBallToPaddle(); LaunceOnMouseClick(); } } private void LockBallToPaddle() //游戏刚开始要把球绑到板子中间上面随着板子移动 { Vector2 paddlePos = new Vector2(paddle1.transform.position.x, paddle1.transform.position.y); transform.position = paddlePos + paddleToBallVector; } private void LaunceOnMouseClick() { if (Input.GetMouseButtonDown(0)) //通过点击鼠标左键发射,hasStart设置为true,并给它一个向上的力 { hasStarted = true; GetComponent<Rigidbody2D>().velocity = new Vector2(xPush,yPush); } }
private void OnCollisionEnter2D(Collision2D other) { Vector2 velocityTwek = new Vector2(Random.Range(0, randomFactor), Random.Range(0, randomFactor));//随机的速度 if (hasStarted) { AudioClip clip = ballSounds[Random.Range(0, ballSounds.Length)]; myAudioSource.PlayOneShot(clip); //播放一遍音频 myRigibody2D.velocity += velocityTwek; //为了防止球一直做减速移动,要在给它每次和砖块碰撞的时候添加一个随机速度 } } }
别忘了给它碰撞体和重力,初次之外我们还有一个弹力就用Physice Material 2D
Friction为摩擦力,Bounceness为弹力
我们还要创建一个Audio Source组件让他在发射和碰撞时发出声音,并把素材的音频文件拖到Ball Sounds的数组中