fbpx
Tower Defense in Unity - Part 1 - Basic Enemy Movement

Tower Defense Game in Unity – Part 1

Read Time:7 Minute, 12 Second

This guide is going to be the first one in a series of guides showing how to build a tower defense game in Unity. Some of the most popular tower defense games (or TD for short), are Bloons TD, Minion Masters, Frontline Zed, and Plants VS Zombies. All of which you can find on Steam.

We will start building our tower defense game in Unity by breaking the game into little pieces. As we progress further in the guides series, the game will become more and more functional until we will have a complete game.
In this guide. we will create the tower, enemies, and the lose condition.

Start With the Basics – Create the map

For the map, I am going to use a 3.5×2.5 plane and place the camera right above it, but you can play with it and, for example, place the camera differently. Name the plane “Ground”.
Let’s create a new cube, name it “Enemy”, and ensure its position is (0, 0.5, 0). You can see it’s a bit hard to differentiate the cube from the ground so let’s assign a material to the ground. Create a new folder in our project by right-clicking in the Project view, selecting “Create” and then “Folder”. Name that folder “Materials”.

The ground for the game

Now, in that folder, create a new material. You can do that by opening the folder in the Project view, right-clicking, “Create”, and “Material”. Name the material with the color you are going to use (in my case, “M_Green”), and drag the material on the ground plane.

Giving the ground color for easier differentiation

Let’s create our tower. for the tower, I am going to use a simple cylinder but feel free to use any other game object, including one from the assets store. Name the game object “Tower” and move it to the right of the ground. Notice the tower is still on the plane. Also, move the cube to the left of the plane.

Enemy Controller – Moving and Hitting the Tower

There is no tower defense if we have nothing to defend from, right?
Let’s start moving our enemy toward the tower. To do that, we will create a new folder in our project and call it “Scripts”. Inside that folder, create a new C# script and name it “EnemyController”. Assign the script to the enemy by dragging the script onto the player.

Add the EnemyController script to the enemy game object

We will create a path for the enemy to follow in a later part of the Tower Defense Game in Unity. For now, we will just move our enemy right until he hits the tower. For that, make sure the enemy and the tower both have the same z value in the transform (0 in my case).

Open the EnemyController script by double-clicking it.
Create a new public float called “movementSpeed”. This variable will show up in the Inspector when the enemy game object is selected and we will be able to edit it from there instead of in the code.

public float movementSpeed = 5f;
Enemy movement speed

In the Update method, add the following line:

transform.position += Vector3.right * Time.deltaTime * movementSpeed;

This will move the enemy to the right. The file should now look like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyController : MonoBehaviour
{
    public float movementSpeed = 5f;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.position += Vector3.right * Time.deltaTime * movementSpeed;
    }
}

Enter play mode and you can see the enemy is now moving to the right. If it moves to the left, check your camera’s orientation.
Also, add a Rigidbody component to the enemy by selecting the enemy game object, in the Inspector, click “Add Component”, and look for “Rigidbody”. Then, deselect “Use Gravity”.

Disabling gravity on the enemy game object

Great! now let’s make it hit the tower.
To do that, select the tower game object and set “Is Trigger” to true.

Setting the tower as a trigger

Let’s create a new script and call it “TowerHealth”. Assign the script to the tower game object and open it for editing. For now, we can delete the Start and Update methods in it and create a new public integer called “health”.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TowerHealth : MonoBehaviour
{
    public int health = 3;
}

Now, let’s get back to our EnemyController script and add the following OnTriggerEnter method below the Update method.

private void OnTriggerEnter(Collider other)
    {
        if (other.name == "Tower")
        {
            TowerHealth th = other.GetComponent<TowerHealth>();
            th.health = --th.health;
            Debug.Log(th.health);
        }
    }

The OnTriggerEnter will execute once the enemy hits a game object set to trigger (when the enemy’s collider is overlapping with the collider of a game object set to trigger). It will then check whether the trigger game object’s name is “Tower”. If it is, it will use the TowerHealth component (script) we created earlier to get the current tower’s health, decrease it by one, and then assign the new value to the tower’s health.
For testing purposes, it will then print the new tower’s health value.

Great, now let’s make the enemy disappear when he hits the tower.
To do that, all we need to do is to add to the following line inside the “if” in the OnTriggerEnter method.

Destroy(gameObject);

In the above line of code, the “gameObject” refers to the game object that this script is attached to. The “Destroy” method, well… destroys the game object passed to it.
And our EnemyController script will now look like this.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyController : MonoBehaviour
{
    public float movementSpeed = 5f;

    // Update is called once per frame
    void Update()
    {
        transform.position += Vector3.right * Time.deltaTime * movementSpeed;
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.name == "Tower")
        {
            TowerHealth th = other.GetComponent<TowerHealth>();
            th.health = --th.health;
            Debug.Log(th.health);
            Destroy(gameObject);
        }
    }
}

To have more enemies, we can duplicate our enemy game object. But since in a later guide in this series, we will spawn enemies via a script, it would be best to make a prefab out of our enemy game object. To do that, let’s create a new folder, as we did earlier, and name it “Prefabs”.
Enter the folder and drag the enemy game object from the Hierarchy view to the folder in the Project view.

Making a prefab out of the enemy game object

Now, all we need to do to create more enemies is to drag the prefab we just create into the Hierarchy view or the Scene view and place the enemy where we want.
I will add two more enemies to the scene.

Adding multiple enemies

Hit play, and you can see all the enemies moving right and when they hit the tower, they damage it (decreasing the tower’s health) and are destroyed.

Game Over – Tower Defense Failed!

We can now implement our game’s lose condition. That is, the tower’s health reaches 0.
For now, we will only print “Game Over” in the console.
To do that, let’s get back to the TowerHealth script. Add the Update method back to it, check if health is lower or equal 0, and if it is, print “Game Over”.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TowerHealth : MonoBehaviour
{
    public int health = 3;

    private void Update()
    {
        if (health <= 0)
        {
            Debug.Log("Game Over");
        }
    }
}

Nice! everything works!
One thing that bothers me, is the “Game Over” is being printed with every frame. I would prefer it as if it would only print once. Let’s fix this.
Add a private boolean called isGameOver to the TowerHealth script, set it to false, and once the tower’s health reaches 0, set it to true.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TowerHealth : MonoBehaviour
{
    public int health = 3;
    private bool isGameOver = false;

    private void Update()
    {
        if (!isGameOver && health <= 0)
        {
            isGameOver = true;
            Debug.Log("Game Over");
        }
    }
}

You can now see the “Game Over” is printed only once to the console.

Adding the lose condition to our tower defense game in Unity

Tower Defense Game in Unity – Part 1 – Done!

This concludes the first part of the series.
In the next guide in the series, we will create a canon that will seek the closest enemy and shoot at it. If the bullet hits the enemy, the enemy will die.

If you don’t want to miss the next guide, be sure to subscribe to our newsletter.

Leave a Reply

Your email address will not be published. Required fields are marked *