一、前言
学完unity基础准备从简单项目入手,然后就想到了坦克大战,写了大概4,5天吧,其中也是突发奇想改了些其他小游戏进去了,项目也存在许多Bug和问题,鄙人初学者,做的不好勿喷。
二、项目大体包括
1.经典小游戏(坦克大战):这个小时候都玩过,属于是童年的回忆吧,现在只做了两关,因为那时候后续没时间了,就没有再跟进了
2.坦克推箱子游戏,只做了一关
3.坦克精准射击
4.急速坦克(虽然不急速)
三、项目主页
这个没什么难,主要用好跳转页面就行了。
四、游戏1:坦克大战
核心代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class PlayerManeger : MonoBehaviour
{
//属性值
public int lifeValue = 3;
public int playerScore = 0;
public bool isDead = false;
public bool isDefeat=false;
//敌人迭代数
public int n = 0;
//引用
public GameObject born;
public GameObject Gameoverfab;
public Text PlayerScoretext;
public Text lifeValuetext;
public Text Anykey;
public Image[] Ememynumber;
//单例
private static PlayerManeger instance;
public static PlayerManeger Instance { get => instance; set => instance = value; }
private void Awake()
{
instance = this;
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if(isDead) Recover();
if(isDefeat==true&&Input.anyKey==true) { SceneManager.LoadScene("Main"); }
PlayerScoretext.text=playerScore.ToString();
lifeValuetext.text=lifeValue.ToString();
if (n == 12) Win();
}
//复活
private void Recover()
{
if(lifeValue<=0&&isDead)
{
//游戏失败,返回主界面
GameOver();
isDead = false;
}
else
{
lifeValue--; //生命-1
Instantiate(born,new Vector3(-2,-4.5f,0),Quaternion.identity); //重新生成
isDead = false; //存活
}
}
//游戏结束
public void GameOver()
{
Instantiate(Gameoverfab, transform.position, Quaternion.identity); //播放gameover
Invoke("Timenone", 1.2f); //延迟时间冻结
}
public void Win()
{
if (Application.loadedLevel == 0) //上次是第一关,这次跳转第二关
{
SceneManager.LoadScene(1);
}
else
{
SceneManager.LoadScene(3);//否则就是胜利
}
Debug.Log("下一关");
}
public void Timenone()
{
isDefeat = true; //游戏失败
Anykey.enabled = true; //打开提示信息
Time.timeScale = 0; //时间冻结
}
}
游戏主要信息通过单例PlayerManeger访问并修改, Update时刻监控死亡状态和游戏失败状态,一旦有变化则执行相应的持续进行跳转页面,赢了则跳转到第二关,输了暂停状态再跳转到主页。
下面是第二关示例图:
代码核心和第一关一样,多了个跳转胜利界面
五、游戏2: 坦克推箱子
这个游戏我给所有物体添加了碰撞器和刚体,红点设置了触发器。一旦推的箱子到达指定地点,则给单例的成功数量+1,达到5则游戏胜利。
核心代码如下:
public class Gamemaneger : MonoBehaviour
{
//单例
private static Gamemaneger instance;
public static Gamemaneger Instance { get => instance; set => instance = value; }
//属性
public bool iswin;
public int reach = 0;
// Start is called before the first frame update
void Start()
{
instance = this;
}
// Update is called once per frame
void Update()
{
if (reach==5)
{
SceneManager.LoadScene(3);
}
}
}
这个做的有点粗糙不过,我也会后续优化的。
六、游戏3:坦克射击
主要是射击快速移动的敌方坦克,达到目标数字则胜利,被撞到则失败
核心代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
public class g3player : MonoBehaviour
{
[SerializeField] float rotationSpeed = 6f;
float angle;
private Vector2 direction;
Quaternion rotation;
Vector3 mouseposition;
//引用
public GameObject bullect;
// Start is called before the first frame update
private void OnEnable()
{
StartCoroutine(nameof(GunRotation));
}
private void OnDisable()
{
StopCoroutine(nameof(GunRotation));
}
IEnumerator GunRotation()
{
while (true)
{
mouseposition = Input.mousePosition;
mouseposition.z = 6f; //在坐标转换时,z轴坐标必须不为0,否则只会转换一次,表现上就是转卡住了
direction = Camera.main.ScreenToWorldPoint(mouseposition) - transform.position;
angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg-90;
Debug.Log(angle);
rotation = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, rotationSpeed * Time.deltaTime); Attack();
yield return null;
}
}
private void Attack()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Instantiate(bullect, transform.position,rotation);
}
}
}
这里做了转向跟随鼠标,具体根据获取到鼠标的向量算出该旋转的角度,然后由transform.rotation进行跟随旋转,再设置射击方法。
敌人的寻路是根据两个点组来进行的,之前想用导航系统可惜在网上没找到比较简易的2D导航教程,然后用了这个粗鲁的办法。
七、游戏4:坦克竞速(不知道叫什么随便起的名字-_-)
移动部分我设置的是摄像机移动,因为开始设置坦克移动就无法固定摄像机了,所以改成了摄像机带着子对象坦克移动,其中单例是为了捡到道具后改变移动速度,代码如下
public class Cameramove : MonoBehaviour
{
public float Movespeed;
private static Cameramove instance;
public static Cameramove Instance { get => instance; set => instance = value; }
private void Awake()
{
instance = this;
}
// Update is called once per frame
void Update()
{
Move();
}
//移动
void Move()
{
transform.Translate(new Vector3(0, 1, 0) * Time.deltaTime * Movespeed);
}
}
其他部分就是根据触发器来进行,比如撞到物体的相应,特别是捡到道具就怎么样。
八、项目总结
1.怎么说呢,刚开始做这个就想着练练手,大家看的话当草稿吧
2.遇到的问题:
1)窗口比例问题:比例刚开始调的是Free Aspect就没管了,然后后面做好了发现但凡改动一点窗口大小都直接裂开,所以这里建议之后一定要设置好比例大小
2)Ui设计问题:有些物体和对象我直接放根目录下了,导致后面缩放会影响位置,所以建议以后设计的时候,能放UI就放UI,这样就可以设计锚点和顶点来拉比例了
3)代码问题:这个也是技术的缺陷吧,遇到许多需要解决的功能,许多难解决的特别容易卡死,一卡就一下午。。。
4)体验感不是特别好:这也没办法,毕竟也是刚刚开始,不过后续我也会自己慢慢优化的。
3.我也是深刻的认识到自己需要掌握的还有很多,但我会在这条道路上继续走下去。
4.如有建议和想法的可以私信我qq:3380125833,小萌新做的不好勿喷^v^