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脚本更新如下。
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;
}
}
最后游戏制作完成。