Unity之见缝插针游戏(unity见缝插针游戏代码)
1.UI界面
(1)导入资源
(2)首先这是一个2d游戏,应把模式转化为2d模式,并且调整摄像机的两个属性为SolideColor 和orth0graphic (正交模式),
(3)制作针(针头为针身的子对象),并且创建两个空组,并给两个空组一个颜色,并分别命名为Level,Start,分别表示针生成的位置和针准备射击的位置,并计算针射到圆盘上圆盘中心和和针中心的距离。我这里距离为1.34 (4)拖动针,使其变成一个预制体。并删除地图上现有的针。
2.射击系统
创建一个脚本命名为Shoot,挂载到刚开始创建的Level空组上,并添加以下脚本,然后先暂时跳到子弹处理系统。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Shoot : MonoBehaviour { public Transform GunBullet;//定义一个预制体组件 bool isnoMouse;//定义一个布尔变量判断接收鼠标左键是否按下 void Start() { Creat(); } // Update is called once per frame void Update() { isnoMouse = Input.GetMouseButtonDown(0);//鼠标左键按下一次返回true,否则返回false if (isnoMouse) { Creat();//创建针 } } void Creat() { GunBullet = Instantiate(GunBullet, transform.position, GunBullet.transform.rotation);//初始化针 } } 复制代码
3.子弹处理系统
(1)创建一个脚本命名为GunBullet挂载到UI部分制作的子弹预制体上,并添加以下脚本,
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GunBullet : MonoBehaviour { bool isReach; //用于判断子弹是否准备完毕 bool isFay; //用于判断子弹是否开始飞行 float Speed; //用于控制子弹飞行的速度 Transform Circle;//用于储存圆盘 Vector3 position;//用于储存子弹最终要到达的位置 Transform start;//用于储存start空组 void Start() { Speed = 0.4f; Circle = GameObject.Find("Circle").transform;//获取圆盘 start = GameObject.Find("Start").transform;//获取start空组 //计算子弹最终要到达的位置 position = new Vector3(Circle.position.x, Circle.position.y - 1.34f, Circle.position.z); isReach = false; isFay = false; } void Update() { //当子弹不需要发射时 if (isFay == false) { //且子弹还未准备完毕时 if (isReach == false) { //让子弹移动到准备发射的地方 transform.position = Vector3.MoveTowards(transform.position, start.position, Speed); if (Vector3.Distance(transform.position, start.position) < 0.04f) { //当到达准备发射的地方时,让子弹变为准备完毕的状态 isReach = true; } } } else //当按下鼠标左键将会调用射击系统将会调用StartFay方法使其变为发射状态 { //让子弹移动到最终要到达的位置 transform.position = Vector3.MoveTowards(transform.position, position, Speed); if (Vector3.Distance(transform.position, position) < 0.04f) { //当到达最终要到达的位置时,改变他的状态,此后一直会在 不需要发射且准备完毕状态,也就是一直在33行 isFay = false; //忽略偶然误差带来的不便 transform.position = position; //把子弹的父对象设为圆盘使其和圆盘一起转动(后续会补上圆盘转动的脚本) transform.parent = Circle; } } } /// <summary> /// 改变子弹的状态,使其向最终的点移动 /// </summary> public void StartFay() { isReach = true; isFay = true; } } 复制代码
然后更新Shoot脚本如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Shoot : MonoBehaviour { public GunBullet gunBullet;//定义一个预制体组件 bool isnoMouse;//定义一个布尔变量判断接收鼠标左键是否按下 Transform newgunBullet;//储存由预制体生成的子弹 void Start() { Creat(); //创建第一个子弹 } // Update is called once per frame void Update() { isnoMouse = Input.GetMouseButtonDown(0);//鼠标左键按下一次返回true,否则返回false if (isnoMouse) { //使当前子弹从准备状态变为发射状态,并创建下一个针,注意24行和25行的顺序不能乱, //不然新创建的针永远都只会是发射状态 gunBullet.GetComponent<GunBullet>().StartFay(); Creat(); } } void Creat() { gunBullet = Instantiate(gunBullet, transform.position, gunBullet.transform.rotation);//初始化子弹 } } 复制代码
然后在补齐圆盘转动的脚本,创建脚本名为Rota的脚本并挂到圆盘上。脚本如下
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Rota : MonoBehaviour { public static float Speed;//圆盘旋转速度 public static float direction;//圆盘旋转方向 // Start is called before the first frame update void Start() { direction = 1f; Speed = 3f; } // Update is called once per frame void Update() { transform.Rotate(new Vector3(0, 0, direction) * Speed ); } } 复制代码
4.死亡处理
然后我们发现当针头和针头碰撞时游戏并不会结束,因此新建脚本fail挂载到预制体的针头上,并且我们还要给针头增加2d刚体和2d盒型碰撞器。并把刚体的gravity Scale设置为0,以及盒型碰撞器的is Trigger勾上。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Colllier : MonoBehaviour { private void OnTriggerEnter2D(Collider2D collision) { GameObject.Find("Level").GetComponent<Shoots>().Gameover(); } } 复制代码
注意这个脚本的作用主要是为了触发射击系统的Shoot脚本的Gameover()方法,所以我们应该先更新Shoot脚本。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; public class Shoot : MonoBehaviour { bool isStop;//用于判断是否停止射击 public GunBullet gunBullet;//定义一个预制体组件 bool isnoMouse;//定义一个布尔变量判断接收鼠标左键是否按下 Transform newgunBullet;//储存由预制体生成的子弹 Camera mainCamera; void Start() { isStop = false; mainCamera = Camera.main; Creat(); //创建第一个子弹 } // Update is called once per frame void Update() { if (isStop) { return; } isnoMouse = Input.GetMouseButtonDown(0);//鼠标左键按下一次返回true,否则返回false if (isnoMouse) { //使当前子弹从准备状态变为发射状态,并创建下一个针,注意24行和25行的顺序不能乱, //不然新创建的针永远都只会是发射状态 gunBullet.GetComponent<GunBullet>().StartFay(); Creat(); } } void Creat() { gunBullet = Instantiate(gunBullet, transform.position, gunBullet.transform.rotation);//初始化子弹 } public void GameOver() { //44和49这种结构是为了不让GameOver()重复执行 if (isStop == true) return; GameObject.Find("Circle").GetComponent<Rota>().enabled = false;//让圆盘重复执行 StartCoroutine("GetEnumerator");//使用协程,让背景逐渐变红,屏幕放大(实际上是对摄像机的一些操作) isStop = true; } IEnumerator GetEnumerator() { while (true) { //对摄像机的背景进行插值运算。 mainCamera.backgroundColor = Color.Lerp(mainCamera.backgroundColor, Color.red, 3f * Time.deltaTime); mainCamera.orthographicSize = Mathf.Lerp(mainCamera.orthographicSize, 3.5f, 3f * Time.deltaTime); if (Mathf.Abs(mainCamera.orthographicSize - 3.5f) < 0.04f) { break; } yield return 0;//返回每次插值运算后摄像机的状态。 } yield return new WaitForSeconds(1f);//等待1秒 SceneManager.LoadScene( SceneManager.GetActiveScene().buildIndex);//加载当前场景 } } 复制代码
最后我们增加分数显示。在编辑界面创建一个文本框,注意要调Canvas的模式,调至合适的大小并拖至圆盘中心,然后我们想要的效果是针到圆盘后加分,并且为了增大难度,我们可以设置当针到达圆盘让圆盘加速并随机变向。所以Shoot脚本和Gunbullet脚本更新如下。
伪原创工具 SEO网站优化 https://www.237it.com/
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; public class Shoot : MonoBehaviour { bool isStop;//用于判断是否停止射击 public GunBullet gunBullet;//定义一个预制体组件 bool isnoMouse;//定义一个布尔变量判断接收鼠标左键是否按下 Transform newgunBullet;//储存由预制体生成的子弹 Camera mainCamera; public static int grade; public Text score; void Start() { isStop = false; mainCamera = Camera.main; Creat(); //创建第一个子弹 grade = 0; score.text = grade.ToString(); } // Update is called once per frame void Update() { score.text = grade.ToString(); if (isStop) { return; } isnoMouse = Input.GetMouseButtonDown(0);//鼠标左键按下一次返回true,否则返回false if (isnoMouse) { //使当前子弹从准备状态变为发射状态,并创建下一个针,注意24行和25行的顺序不能乱, //不然新创建的针永远都只会是发射状态 gunBullet.GetComponent<GunBullet>().StartFay(); Creat(); } } void Creat() { gunBullet = Instantiate(gunBullet, transform.position, gunBullet.transform.rotation);//初始化子弹 } public void GameOver() { //44和49这种结构是为了不让GameOver()重复执行 if (isStop == true) return; GameObject.Find("Circle").GetComponent<Rota>().enabled = false;//让圆盘重复执行 StartCoroutine("GetEnumerator");//使用协程,让背景逐渐变红,屏幕放大(实际上是对摄像机的一些操作) isStop = true; } IEnumerator GetEnumerator() { while (true) { //对摄像机的背景进行插值运算。 mainCamera.backgroundColor = Color.Lerp(mainCamera.backgroundColor, Color.red, 3f * Time.deltaTime); mainCamera.orthographicSize = Mathf.Lerp(mainCamera.orthographicSize, 3.5f, 3f * Time.deltaTime); if (Mathf.Abs(mainCamera.orthographicSize - 3.5f) < 0.04f) { break; } yield return 0;//返回每次插值运算后摄像机的状态。 } yield return new WaitForSeconds(1f);//等待1秒 SceneManager.LoadScene( SceneManager.GetActiveScene().buildIndex);//加载当前场景 } } 复制代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GunBullet : MonoBehaviour { bool isReach; //用于判断子弹是否准备完毕 bool isFay; //用于判断子弹是否开始飞行 float Speed; //用于控制子弹飞行的速度 Transform Circle;//用于储存圆盘 Vector3 position;//用于储存子弹最终要到达的位置 Transform start;//用于储存start空组 void Start() { Speed = 0.4f; Circle = GameObject.FindGameObjectWithTag("Player").transform;//获取圆盘 start = GameObject.Find("Start").transform;//获取start空组 //计算子弹最终要到达的位置 position = new Vector3(Circle.position.x, Circle.position.y - 1.34f, Circle.position.z); isReach = false; isFay = false; } void Update() { //当子弹不需要发射时 if (isFay == false) { //且子弹还未准备完毕时 if (isReach == false) { //让子弹移动到准备发射的地方 transform.position = Vector3.MoveTowards(transform.position, start.position, Speed); if (Vector3.Distance(transform.position, start.position) < 0.04f) { //当到达准备发射的地方时,让子弹变为准备完毕的状态 isReach = true; } } } else //当按下鼠标左键将会调用射击系统将会调用StartFay方法使其变为发射状态 { //让子弹移动到最终要到达的位置 transform.position = Vector3.MoveTowards(transform.position, position, Speed); if (Vector3.Distance(transform.position, position) < 0.04f) { //当到达最终要到达的位置时,改变他的状态,此后一直会在 不需要发射且准备完毕状态,也就是一直在33行 isFay = false; //忽略偶然误差带来的不便 transform.position = position; //把子弹的父对象设为圆盘使其和圆盘一起转动(后续会补上圆盘转动的脚本) transform.parent = Circle; Shoot.grade++; if (Random.Range(0, 2) == 0) { Rota.direction = -1f; } else { Rota.direction = 1f; } Rota.Speed += 0.2f; } } } /// <summary> /// 改变子弹的状态,使其向最终的点移动 /// </summary> public void StartFay() { isReach = true; isFay = true; } } 复制代码
最后游戏制作完成。
作者:不动明王
链接:https://juejin.cn/post/7035222598040420359