Unity坦克大战(含其他3种经典小游戏)_菜鸟刘的第一个项目

一、前言

        学完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^

                               

猜你喜欢

转载自blog.csdn.net/qq_57250692/article/details/132164270