fbpx
Tower Defense in Unity - Part 2 - Cannon and Boundaries

Tower Defense Game in Unity – Part 2

Read Time:7 Minute, 56 Second

After we completed the Tower Defense Game in Unity – Part 1 guide, in which we created our tower and enemies, and made the enemies move and damage the tower, it is time to build a cannon to defend the tower.

To do so, I will build the cannon in unity using multiple game objects. You can either follow me and build the same cannon as I do, build your own cannon, or import one from the asset store or from anywhere else.

Building the cannon

Let’s start by creating an empty game object, naming it “Cannon”, and making sure its location is set to (0, 0, 0).

Create an empty game object, rename it, and reset its position

Right-click on the empty game object we just created and create a new cylinder. Rename it to “CannonBody”, reset its transform component, and put it right above the ground.
Add two more cylinders as wheels and place them accordingly.
Do notice you rotate the cylinder used as the cannon’s body on the X axis. We will later use its forward vector, so it is important.

Notice how in the image below, the cannon’s body is parallel to the Z axis.

The first cannon in our Tower Defense game!

Create another empty game object, name it “CannonballSpawnLocation”, and place it where the cannonball should come out from the cannon.

Setting the cannonball spawn location

Defending the Tower – Shooting from the Cannon

Now that we have a cannon, let’s make it shoot!
Move it a little bit backward by moving the empty game object we created earlier for the cannon on the Z axis. Now let’s create a new script in the scripts folder, call it “Shoot”, and assign it the cannon game object.

Create, name, and assign the Shoot script

Before we start to code anything related to the shooting, we need something to shoot. Let’s create a sphere, rename it to “CannonBall”, reset its transform component, and set its scale to 0.25.

Creating the cannon’s bullet

Now, let’s make our cannonball a prefab by dragging it from the hierarchy view to the prefabs folder in the project view.

Spawning Cannonballs

Now that that’s done, let’s open our Shoot script to start editing it.
We want the cannonball to spawn every few seconds. Create a new public float called “shootInterval” and set it to 1.

As a start, let’s print “Shoot” to the console every second (using the shootInterval float).

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

public class Shoot : MonoBehaviour
{
    public float shootInterval = 1f;
    private float lastShot = 0f;

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

    }

    // Update is called once per frame
    void Update()
    {
        if (Time.time > lastShot + shootInterval)
        {
            lastShot = Time.time;
            Debug.Log("Shoot!");
        }
    }
}

In the above code, we create the public integer called “shootInterval”. This will allow us to easily modify the time between shots in the inspector. We also create the private float “lastShot” so we know when the last shot was fired.

In the update method, we are checking if the time since the game started (Time.time) is greater than when we last fired the cannon plus the time we need to wait before shooting again. If it is, we save the new time and shoot.

Now, let’s actually shoot instead of just printing “Shoot” to the console. To do that, let’s create two new variables in the script.

public GameObject cannonballSpawnLocation;
public GameObject cannonballSpawnPrefab;

save the script and select the Cannon game object. You can see we now have a field in the inspector called “Cannonball Spawn Location”. Inside it, click on the little circle and choose the “CannonBallSpawnLocation” game object. For the “Cannonball Spawn Prefab”, choose the cannonball prefab we created (or the one we imported).

Set the CannonBallSpawnLocation reference

This will allow us to use the game object inside the “Shoot” script and use its position and rotation to spawn a cannonball. To do that, we are going to use the Instantiate method.
Add the following two lines to the “if” in the Update method.

Transform spawnTransform = cannonballSpawn.transform;
Instantiate(cannonballSpawnPrefab, spawnTransform.position, spawnTransform.rotation);

Delete the CannonBall game object from the scene, as we don’t need it anymore (since we made it a prefab) and hit play. You can see cannonballs spawning.

Spawning cannon balls

Making the Cannonballs Move

We are now spawning cannonballs, but they are standing still, and nothing happens…
We now need to make the cannonball fly forward and the direction it was shot at. To do that, let’s add a new script called “Cannonball”, assign it to the CannonBall prefab, and open it for editing.

For the cannon to fly, all we need is to add one line of code to the Update method.

transform.position += transform.forward * Time.deltaTime;

Save everything, hit play and you can see the cannon is now shooting, but the cannonballs are flying slow. Let’s fix this by adding a new variable to the Shoot script called “speed”, and multiply the above line of code by it.

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

public class Cannonball : MonoBehaviour
{
    public float speed = 8f;

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

Kill an Enemy

Now that we can shoot from our cannon, let’s make the cannonball kill the enemy when it hits it.
To do that, we will go the other way around. We will make the cannonball a trigger and in the EnemyController script, we will use OnTriggerEnter to detect the collision and destroy both game objects, the enemy and the cannonball.

Let’s start by changing the cannonball prefab to IsTrigger.

Set the cannonball prefab as trigger

Still with the cannonball prefab selected, let’s give it a new tag called “Cannonball”. To do that, we need to create it first. In the inspector, click on the tags dropdown and select “Add Tag…”.

Add a tag

Now, click on the little plus icon and name the tag “Cannonball”.

Create the “Cannonball” tag

After that, select the CannonBall prefab again, click on the tags dropdown and select “Cannonball”.

Add the “Cannonball” tag to the Cannonball prefab

Now, open the EnemyController and edit the OnTriggerAction to the following.

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

Now the cannon shoots cannonballs that kills the enemies, awesome!

Destroying the Cannonball When Out of Bounds

When the cannon is shooting a cannonball, if it does not hit the enemy, it will keep going forever. When the game lasts for a long time, this means we will have a lot of cannonballs the player can’t even see and does not need anymore, flying around in the scene. This could lead to performance issues that will frustrate both you and the player.

To deal with such an issue, we will create boundaries for our map. We will do this by creating walls around our map. If you followed me, we need to create four walls – top, right, bottom and left. After you are done creating the walls, disable the Mesh Renderer component, sot the player won’t see them. Also, add a Rigidbody component to each of them, and in the inspector, disable “Use Gravity”, so the walls won’t just fall. Select all of the walls, and in the hierarchy, right-click, and select “Create Empty Parent”.

The walls for the tower defense game
Disable the Mesh Renderer component, add the Rigidbody component, and disable Use Gravity

Now that we are done creating the boundaries for the map, let’s put them to use. Like we said earlier, we want the walls to destroy cannonballs when the cannonballs hit them. To do that, create a new script called “Boundaries”, assign it to each of the walls, and open the script for editing.

If you followed the guide thus far, you should already have a clue of what the script will look like.
We want to do something when a cannonball hit a wall, and we know the cannonball is a trigger. We also know the wall has a Rigidbody component. This means we can use the OnTriggerEnter method.

Now, what do we want to do when a cannonball hit a wall? To destroy the cannonball of course!
Let’s implement that with the following OnTriggerEnter method inside the Boundaries script.

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

public class Bounderies : MonoBehaviour
{
    private void OnTriggerExit(Collider other)
    {
        if (other.CompareTag("Cannonball"))
        {
            Destroy(other.gameObject);
        }
    }
}

Save everything, hit play, and you can see the cannonballs are now being destroyed either when they hit a wall or when they hit an enemy. When they hit an enemy, they also kill (destroy) it.

What’s Next for the Tower Defense Game in Unity?

In this guide, we added a cannon to our tower defense game, made it shoot, and kill enemies. We also noticed an issue we might have when the game lasts long and learned how to solve it.
In the next guide, we will make the cannon aim at the nearest enemy in range.

If you want to get notified when the next guide in the “Tower Defense Game in Unity” is out, be sure to subscribe to our newsletter. We would love to see you there 🙂

If you have any questions about this guide or want to ask for a specific guide, let us know in the comments below.

Leave a Reply

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