I want to create Tank2D game (clone of Battle City)

Hello,

Please, help me to know how to set physics for sprites. Need I to use RigideBody? Or need I to use only BoxCollider2D?

This is my first example (project files): Tanks_v1.2.0

You gotta use both. Note to use RigidBody2D with a BoxCollider2D

Thank you! And I need to set “Is Kinematic” = True and the Gravity in zero: “Edit” → “Project Settings” → “Phisics 2D” → set Y to 0.

1 Like

“Is Kinematic” must be False. And I set “Rigidbody 2D” → “Constrains” → “Freeze Rotation: Z” to True for the sprites: Player and Enemy.

Now everything is fine. OnCollisionEnter2D works. Enemy tank rides. I can drive a tank Player. I do not like that I can ram the tanks, that is, I can move them off course. Suggest how to fix it?

You can code something to deal with the collisions like explosions or something in a OnTriggerEnter() event, setting the “Is Trigger” on the BoxCollider2D to true. Otherwise they’ll work like bumping cars.

I made how did you said. After a collision Player and Enemy don’t move:

Enemy.cs

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour
{
    private const float defaultSpeed = 0.1f;
    private float currentSpeed = defaultSpeed;

    //public int currentDirection = (int) Tank.Direction.Down;
  
    // Update is called once per frame
    void Update ()
    {
        transform.Translate(Vector3.down * currentSpeed * Time.deltaTime);
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.gameObject.name == "Player")
        {
            currentSpeed = 0;
        }
    }

    void OnTriggerExit2D(Collider2D other)
    {
        if (other.gameObject.name == "Player")
        {
            currentSpeed = defaultSpeed;
        }
    }
}

Please, show me main mistakes in my project: Tanks_v1.2.1

My question is: The Player moves over the enemy sometimes.

Player.cs

using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour
{
    public AudioSource engineSoundPrefab;
    public AudioSource gasSoundPrefab;

    private AudioSource engineSound;
    private AudioSource gasSound;

    private Tank.Direction currentDirection;
    private Tank.Direction blockDirection = Tank.Direction.None;

    private const float defaultSpeed = 0.5f;
    private float currentSpeed = defaultSpeed;

    private Animator anim;

    // Use this for initialization
    void Start()
    {
        engineSound = Instantiate(engineSoundPrefab);
        gasSound = Instantiate(gasSoundPrefab);

        anim = GetComponent<Animator>();

        currentDirection = Tank.Direction.Up;
    }

    void Move(Tank.Direction dir)
    {
        if (blockDirection != currentDirection)
        {
            blockDirection = Tank.Direction.None;
            currentSpeed = defaultSpeed;
            switch (dir)
            {
                case Tank.Direction.Up:
                    transform.Translate(Vector3.up * currentSpeed * Time.deltaTime);
                    break;
                case Tank.Direction.Down:
                    transform.Translate(Vector3.down * currentSpeed * Time.deltaTime);
                    break;
                case Tank.Direction.Right:
                    transform.Translate(Vector3.right * currentSpeed * Time.deltaTime);
                    break;
                case Tank.Direction.Left:
                    transform.Translate(Vector3.left * currentSpeed * Time.deltaTime);
                    break;
            }
        }
    }

    // Update is called once per frame
    void Update()
    {
        float lh = Input.GetAxisRaw("Horizontal");
        float lv = Input.GetAxisRaw("Vertical");

        if (lv > 0)
        {
            anim.SetInteger("state", (int) Tank.State.MoveUp);
            currentDirection = Tank.Direction.Up;
            Move(currentDirection);
            //transform.Translate(Vector3.up * currentSpeed * Time.deltaTime);
            if (!gasSound.isPlaying)
            {
                gasSound.Play();
            }
        }
        else if (lv < 0)
        {
            anim.SetInteger("state", (int)Tank.State.MoveDown);
            currentDirection = Tank.Direction.Down;
            Move(currentDirection);
            //transform.Translate(Vector3.down * currentSpeed * Time.deltaTime);
            if (!gasSound.isPlaying)
            {
                gasSound.Play();
            }
        }
        else if (lh > 0)
        {
            anim.SetInteger("state", (int)Tank.State.MoveRight);
            currentDirection = Tank.Direction.Right;
            Move(currentDirection);
            //transform.Translate(Vector3.right * currentSpeed * Time.deltaTime);
            if (!gasSound.isPlaying)
            {
                gasSound.Play();
            }
        }
        else if (lh < 0)
        {
            anim.SetInteger("state", (int)Tank.State.MoveLeft);
            currentDirection = Tank.Direction.Left;
            Move(currentDirection);
            //transform.Translate(Vector3.left * currentSpeed * Time.deltaTime);
            if (!gasSound.isPlaying)
            {
                gasSound.Play();
            }
        }
        else
        {
            gasSound.Stop();

            if (currentDirection == Tank.Direction.Up)
            {
                anim.SetInteger("state", (int)Tank.State.IdleUp);
            }
            else if (currentDirection == Tank.Direction.Down)
            {
                anim.SetInteger("state", (int)Tank.State.IdleDown);
            }
            else if (currentDirection == Tank.Direction.Right)
            {
                anim.SetInteger("state", (int)Tank.State.IdleRight);
            }
            else if (currentDirection == Tank.Direction.Left)
            {
                anim.SetInteger("state", (int)Tank.State.IdleLeft);
            }
        }
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.gameObject.name == "Enemy")
        {
            currentSpeed = 0;
            blockDirection = currentDirection;
            //GameObject enemyObj = GameObject.FindWithTag("Enemy");
            //Enemy enemyScript = enemyObj.GetComponent<Enemy>();
            //Debug.Log(enemyScript.currentDirection);
        }
    }

    void OnTriggerExit2D(Collider2D other)
    {
        if (other.gameObject.name == "Enemy")
        {
            currentSpeed = defaultSpeed;
            blockDirection = Tank.Direction.None;
        }
    }

    void OnCollisionEnter2D(Collision2D coll)
    {
        //Debug.Log("Hahaha");
        //if (coll.gameObject.tag == "Enemy")
        //{
        //    Debug.Log("In was an Enemy.");
        //}
    }

    IEnumerator TimeOut()
    {
        while (true)
        {
            yield return new WaitForSeconds(1.0f);
            blockDirection = Tank.Direction.None;
        }
    }

    void OnTriggerStay2D(Collider2D other)
    {
        if (other.gameObject.name == "Enemy")
        {
            //currentSpeed = defaultSpeed;
            //blockDirection = currentDirection;
            //StartCoroutine("TimeOut");
            //GameObject enemyObject = GameObject.FindGameObjectWithTag("Enemy");
            //Debug.Log("Enemy " + enemyObject.transform.position + "; Player " + transform.position);
        //    GameObject enemyObject = GameObject.FindGameObjectWithTag("Enemy");
        //    Enemy enemyScript = enemyObject.GetComponent<Enemy>();
        //    Tank.Direction enemyDir = (Tank.Direction)enemyScript.currentDirection;
           
        //    if (enemyDir == Tank.Direction.Down && currentDirection == Tank.Direction.Up)
        //    {
        //        currentSpeed = 0;
        //    }
        //    else
        //    {
        //        currentSpeed = defaultSpeed;
        //    }

        //    Debug.Log(currentDirection);
        }
    }
}

Tank.cs

public class Tank
{
    public enum State
    {
        IdleUp, IdleDown, IdleRight, IdleLeft,
        MoveUp, MoveDown, MoveRight, MoveLeft
    }

    public enum Direction
    {
        Up, Down, Right, Left, Block, None
    }
}

I solved the problem with the Player. I set the speed in zero and save the blockDirection when I have a collision with the Enemy:

Enter and Exit Triggers

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.gameObject.name == "Enemy")
        {
            currentSpeed = 0;
            blockDirection = currentDirection;
        }
    }

    void OnTriggerExit2D(Collider2D other)
    {
        if (other.gameObject.name == "Enemy")
        {
            currentSpeed = defaultSpeed;
            blockDirection = Tank.Direction.None;
        }
    }

When I press key I check the direction:

Moving by keys

    void Move(Tank.Direction dir)
    {
        if (blockDirection != currentDirection)
        {
            currentSpeed = defaultSpeed;
            switch (dir)
            {
                case Tank.Direction.Up:
                    transform.Translate(Vector3.up * currentSpeed * Time.deltaTime);
                    break;
                case Tank.Direction.Down:
                    transform.Translate(Vector3.down * currentSpeed * Time.deltaTime);
                    break;
                case Tank.Direction.Right:
                    transform.Translate(Vector3.right * currentSpeed * Time.deltaTime);
                    break;
                case Tank.Direction.Left:
                    transform.Translate(Vector3.left * currentSpeed * Time.deltaTime);
                    break;
            }
        }
    }

    // Update is called once per frame
    void Update()
    {
        float lh = Input.GetAxisRaw("Horizontal");
        float lv = Input.GetAxisRaw("Vertical");

        if (lv > 0)
        {
            anim.SetInteger("state", (int) Tank.State.MoveUp);
            currentDirection = Tank.Direction.Up;
            Move(currentDirection);
            //transform.Translate(Vector3.up * currentSpeed * Time.deltaTime);
            if (!gasSound.isPlaying)
            {
                //gasSound.Play();
            }
        }
        else if (lv < 0)
        {
            anim.SetInteger("state", (int)Tank.State.MoveDown);
            currentDirection = Tank.Direction.Down;
            Move(currentDirection);
            //transform.Translate(Vector3.down * currentSpeed * Time.deltaTime);
            if (!gasSound.isPlaying)
            {
                //gasSound.Play();
            }
        }
        else if (lh > 0)
        {
            anim.SetInteger("state", (int)Tank.State.MoveRight);
            currentDirection = Tank.Direction.Right;
            Move(currentDirection);
            //transform.Translate(Vector3.right * currentSpeed * Time.deltaTime);
            if (!gasSound.isPlaying)
            {
                //gasSound.Play();
            }
        }
        else if (lh < 0)
        {
            anim.SetInteger("state", (int)Tank.State.MoveLeft);
            currentDirection = Tank.Direction.Left;
            Move(currentDirection);
            //transform.Translate(Vector3.left * currentSpeed * Time.deltaTime);
            if (!gasSound.isPlaying)
            {
                //gasSound.Play();
            }
        }
        else
        {
            gasSound.Stop();

            if (currentDirection == Tank.Direction.Up)
            {
                anim.SetInteger("state", (int)Tank.State.IdleUp);
            }
            else if (currentDirection == Tank.Direction.Down)
            {
                anim.SetInteger("state", (int)Tank.State.IdleDown);
            }
            else if (currentDirection == Tank.Direction.Right)
            {
                anim.SetInteger("state", (int)Tank.State.IdleRight);
            }
            else if (currentDirection == Tank.Direction.Left)
            {
                anim.SetInteger("state", (int)Tank.State.IdleLeft);
            }
        }
    }