Unity primary tank war game implementation (Battle Tank) with engineering source code resource package

Posted by gurechan on Sat, 05 Mar 2022 00:23:49 +0100

Remember to play the game for the third time after learning Unity

The last section finished the script above the enemy and players. This time, let's write the logic of the birth point and other scripts.
First look at the script of the bullet. The bullet should be able to move, launch to a fixed position, and make corresponding operations when it collides with the corresponding object. For example, if you hit a wall, you should destroy the wall and bullets at the same time, and there should be the sound of bullets and the sound of hitting the wall, and so on. So we need to add a collision body, but the bullet can't push away the tank. Just tick the IsTrigger option.

private void OnTriggerEnter2D(Collider2D collision)//Detect what the bullet collided with and what to do after the collision
{
    if (Equals(collision.tag,"Wall"))//It hit the wall
    {
        ControlPlay(NewObject(Resources.Load("GameResource/AudioSource/Hit") as AudioClip));//Play hit sound
        Destroy(collision.gameObject);//Destroy the wall
    }
    if (Equals(collision.tag,"Sea"))
    {
        return;//Go straight across the sea
    }
    if (collision.tag == "Cristal")//Touch crystal
    {
        Instantiate(Resources.Load("Prefabs/BrokenCristal"), collision.gameObject.transform.position, collision.gameObject.transform.rotation);//Instantiate a broken crystal
        ControlPlay(NewObject(Resources.Load("GameResource/AudioSource/HeartDamage") as AudioClip));//Sound
        Instantiate(Resources.Load("Prefabs/Explosion"), collision.gameObject.transform.position, collision.transform.rotation);//Explosion effect
        Destroy(collision.gameObject);//Destroy crystal
        GameObject.Find("Environment").GetComponent<BornAndText>().isCristalDestroyed = true;//Change the bool variable to true and implement the logic of game failure in BornAndText
    }
    if (collision.tag == "Enemy")
    {
        if (gameObject.tag == "EnemyBullet")//When the enemy's bullet hits the enemy, it does nothing
            return;
        ControlPlay(NewObject(Resources.Load("GameResource/AudioSource/Die") as AudioClip));
        Instantiate(Resources.Load("Prefabs/Explosion"), collision.gameObject.transform.position, collision.gameObject.transform.rotation);
        GameObject.Find("Environment").GetComponent<BornAndText>().destroyEnemyNum++;
        Destroy(collision.gameObject);
    }
    Destroy(gameObject);
}
↑ Part of the code in the method
private sbyte GetBulletSpriteIndex()//Gets the current index in the array
private void ChangeBulletDirection(sbyte index)//Change the direction of the bullet according to the index
private GameObject NewObject(AudioClip temp)//Because the sound effect is added to the bullet, there is no sound when shooting against the wall, so create an empty object to carry the AudioSource until it is played
private void ControlPlay(GameObject temp)//Control the playback and life cycle of sound
↑ The methods used in the above methods will not be posted
private void FixedUpdate()
{
    bulletSprite = gameObject.GetComponent<SpriteRenderer>().sprite;
    index = GetBulletSpriteIndex();
    if (index == -1)//Return without finding the index of the bullet
        return;
    if (temp == 1)//The control bullet is subjected to only one application of force
        ChangeBulletDirection(index);//Apply a force in the corresponding direction to the bullet
    temp = 0;
}

Well, the script of the bullet has also been written, and then the script of the birth point. I analyzed it like this. The life cycle of the script of the birth point is very short, which is only suitable for creating enemies and players. If you want to win, lose and realize the UI, you have to write another script to hang on an object that exists from beginning to end, so I wrote a Born to hang on the birth point, I also wrote a BornAndText and put it on the parent object Environment where the map is stored. That's good.

The following is the BornAndText script code
internal void CreateEnemy()
{
    if (destroyEnemyNum == beDestroyNum)//Number of enemies destroyed up to standard
    {
        //victory
        foreach(GameObject temp in Resources.FindObjectsOfTypeAll(typeof(GameObject)))
        {
            if (temp.name == "Victory")
            {
                temp.SetActive(true);//Show victory UI
                foreach(GameObject temp1 in GameObject.FindGameObjectsWithTag("Enemy"))
                {
                    temp1.GetComponent<Enemy>().enabled = false;//Stop enemy movement and fire
                }
                foreach(GameObject temp1 in GameObject.FindGameObjectsWithTag("Born"))
                {
                    if (temp1.GetComponent<Born>() != null)
                    {
                        temp1.GetComponent<Born>().enabled = false;//Stop enemy generation
                    }
                }
                gameObject.GetComponent<BornAndText>().enabled = false;//Stop player generation
                GameObject.FindGameObjectWithTag("Player").GetComponent<Player>().enabled = false;//Prevent players from moving and firing
                Invoke("ToSceneOne", 3);//Return to the start interface in three seconds
            }
        }
    }
    foreach (var temp in born)
    {
        if (temp.name == "Born")//If it is the birth point of the player, then find it
            continue;
        if (temp.activeSelf == true)//If the birth point is activated
        {
            if (temp.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).normalizedTime >= playTimeOfNum+0.1f)//The animation is played after the specified time
            {
                Instantiate(Resources.Load("Prefabs/Enemy"), temp.transform.position, temp.transform.rotation);//Instantiate enemy
                temp.SetActive(false);//Hide birth point
                remainEnemyNum--;
                GameObject.Find("RemainEnemyNum").GetComponent<Text>().text = remainEnemyNum.ToString();
            }
        }
    }
}

private void CreatePlayer()
{
    if (restPlayerLife == 0)//The player is out of life
    {
        //defeat
        foreach (GameObject temp in Resources.FindObjectsOfTypeAll(typeof(GameObject)))
        {
            if (temp.name == "UIGameOver")
            {
                temp.SetActive(true);//Display UI
                gameObject.GetComponent<BornAndText>().enabled = false;//Stop generating players
                Invoke("ToSceneOne", 3);
            }
        }
    }
    foreach (GameObject temp in Resources.FindObjectsOfTypeAll(typeof(GameObject)))
    {
        if (temp.tag == "Born" && temp.name == "Born")//Find the player's birthplace
        {
            temp.SetActive(true);
            if (temp.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).normalizedTime >= playTimeOfNum)//After the animation playback reaches the required time
            {
                Instantiate(Resources.Load("Prefabs/Player1_0"), temp.transform.position, temp.transform.rotation);//Instantiate player
                temp.SetActive(false);//Hide birth point
                restPlayerLife--;//Remaining life - 1
                GameObject.Find("RestPlayerLife").GetComponent<Text>().text = restPlayerLife.ToString();
            }
        }
    }
}
internal void Create()
{
    GameObject[] enemy = GameObject.FindGameObjectsWithTag("Enemy");
    GameObject player = GameObject.FindGameObjectWithTag("Player");
    length = enemy.Length;
    if (player == null)
    {
        CreatePlayer();//Create player
    }
    if (length < 5)
    {
        foreach (var temp in born)
        {
            if (temp.name == "Born")//Skip player birth point
                continue;
            if (temp.activeSelf == true)//The birth point is activated and skipped
            {
                length++;
                continue;
            }
            if (length < 5)//Less than five players
            {
                temp.SetActive(true);//Open a birth point and release the enemy
                length++;
            }
        }
    }
}
private void Update()
{
    Create();
    if (isCristalDestroyed == true)//The crystal was destroyed
    {
        foreach (GameObject temp1 in Resources.FindObjectsOfTypeAll(typeof(GameObject)))
        {
            if (temp1.name == "UIGameOver")//A hidden object named game over was found
            {
                temp1.SetActive(true);
                gameObject.GetComponent<BornAndText>().enabled = false;//Cancels the bornandtext script
                GameObject.FindGameObjectWithTag("Player").GetComponent<Player>().enabled = false;//Cancel Player script
                Invoke("ToSceneOne", 3);//Delay three seconds to return to the start interface
            }
        }
    }
    GameObject.Find("DestroyEnemyNum").GetComponent<Text>().text = destroyEnemyNum.ToString();
}
The following is Born code
private void FixedUpdate()
{
    enemy = GameObject.Find("Environment").GetComponent<BornAndText>();
    enemy.CreateEnemy();//After activation, create the enemy and judge the victory conditions
}
private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.tag == "Enemy" || collision.tag == "Player")//When players and enemies encounter the active birth point, one side is hidden and the other side is open, so it is the state of stop
    {
        gameObject.SetActive(false);
    }
}

Yes, you're right... There are so many if, and I feel that my level is too low after writing... The code is still a long way to go and needs to be fully studied. I declare here that the code is for reference only. After all, my level is too low, and it's a problem to pass my homework (crying and hawing). Let me summarize the problems of my game.

Summary questions:

  1. The generation of controlling the number of enemies is not perfect. At the end of the game, you should generate an appropriate number of enemies instead of an excessive number of enemies
  2. Enemies and players can push each other and have a poor game experience
  3. 2P is not manufactured to realize dual controller play
  4. The game UI is not fully adapted, and it is difficult to directly pass through the narrow slit. It can only be played at a fixed resolution, and the full screen is not achieved
  5. The enemy has not added animation components (this is too lazy to do, and the player can do the enemy quickly), and the reward has not added logic implementation
  6. The code is too lengthy, the allocation of many functions is not very reasonable, and the logic is chaotic. If there is a warning that does not affect the game, it will not be handled
  7. Game logic and objects took two days, and bug correction took three or four days
  8. There is no logic to generate the map. It is troublesome to create the map manually
  9. The enemy's movement method is not very intelligent. It can only realize basic movement and firing, so we have to use quantity to make up for this problem
  10. If the bullet collides with two objects at the same time, it will be destroyed
  11. The generated animation of the enemy and the player should be related to whether it is generated. After the player's life is exhausted, the generated animation of the player still appears, and so does the enemy
  12. There is no half wall concept, that is, the logic that a bullet hitting a wall will only destroy half

No more nonsense. Go directly to the link.

Link: https://pan.baidu.com/s/1NdGG4K_fxEE6udOPl8BJvg
Extraction code: iv54
Unity version 2020.3.2f1c1, and the lower version may not adapt

Topics: C# Unity Game Development Unity3d