Unity Tank Battle (including 3 other classic mini-games)_Rookie Liu’s first project

I. Introduction

        After learning the basics of Unity, I planned to start with a simple project, and then I came up with the idea of ​​tank battle. I wrote it for about 4 or 5 days. I also changed some other small games on a whim. There are also many bugs and problems in the project. At the beginning of this article Scholars, don’t criticize if you don’t do well.

2. The project generally includes

        I played this game.

        ​ ​ 2. Tank pushing box game, only one level has been completed

        3. Accurate tank shooting

        4. Rapid tank (although not rapid)

3. Project homepage

This is not difficult, the main thing is to make good use of the jump page.

4. Game 1: Tank Battle

 The core code is as follows:

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;   //时间冻结
    }
}

The main information of the game is accessed and modified through the single instance PlayerManeger. Update monitors the death status and game failure status at all times. Once there is a change, the corresponding continuous jump page will be executed. If you win, jump to the second level. If you lose, jump to the paused state. Go to home page.

Below is an example picture of the second level:

The core of the code is the same as the first level, with an additional jump to victory interface.

5. Game 2: Tank Sokoban

 In this game, I added colliders and rigid bodies to all objects, and the red dots set triggers. Once the pushed box reaches the designated location, +1 will be added to the number of successful cases. If the number reaches 5, the game will be won.

The core code is as follows:

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);
        }
    }
}

This is a bit rough, but I will optimize it later.

6. Game 3: Tank Shooting

        Mainly shoot at fast-moving enemy tanks. If you reach the target number, you will win, if you are hit, you will fail. 

The core code is as follows:

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);
            
        }
    }
}

Here, the steering is done to follow the mouse. Specifically, the angle of rotation is calculated based on the vector obtained from the mouse, and then the follow-up rotation is performed by transform.rotation, and then the shooting method is set.

The enemy's pathfinding is based on two point groups. I wanted to use the navigation system before, but unfortunately I couldn't find a relatively simple 2D navigation tutorial on the Internet, so I used this rude method.

 7. Game 4: Tank Racing (I don’t know what to call it, I just gave it a random name -_-)

 In the moving part, I set up camera movement. Because I couldn’t fix the camera when I started setting up the tank movement, I changed it to the camera moving with the sub-object tank. The single instance is to change the movement speed after picking up the props. The code is as follows

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);
        
    }
}

 The other parts are based on triggers, such as the response to hitting an object, especially picking up a prop.

8. Project Summary

    1. How can I put it this way? When I first started doing this, I just wanted to practice my skills. I’ll treat it as a draft for everyone to read.

     2. Problems encountered:

        ​​​​​1) Window ratio problem: I adjusted the ratio to Free Aspect at the beginning and left it alone. Then after I finished it, I found that whenever I changed the size of the window, it would break directly. Therefore, it is recommended that you must set the ratio size in the future.

        2) UI design problem: I put some objects and objects directly in the root directory, which will cause the subsequent scaling to affect the position. Therefore, it is recommended that when designing in the future, put the UI where possible, so that you can design anchor points and vertices to increase the proportion. Got it

        ​ ​ 3) Code problem: This is also a technical flaw. When encountering many functions that need to be solved, many difficult to solve problems are particularly easy to get stuck, and one lag will last an entire afternoon. . .

        ​ ​ 4) The experience is not particularly good: There is nothing we can do about it. After all, it is just the beginning, but I will slowly optimize it in the future.

    3. I also deeply realize that I still have a lot to master, but I will continue on this path.

   4. If you have any suggestions or ideas, you can send me a private message at qq:3380125833. If Xiaomengxin doesn’t do well, please don’t complain ^v^

                               

 

 

 

Guess you like

Origin blog.csdn.net/qq_57250692/article/details/132164270