6 min read

In this article by Francesco Sapio author of the book Getting Started with Unity 2D Game Development – Second Edition we will see how to create our towers. This is not an easy task, but at the end we will acquire a lot of scripting skills.

(For more resources related to this topic, see here.)

What a cupcake Tower does

First of all, it’s useful to write down what we want to achieve and define what exactly a cupcake tower is supposed to do. The best way is to write down a list, to have clear idea of what we are trying to achieve:

  • A cupcake tower is able to detect pandas within a certain range.
  • A cupcake tower shoots a different kind of projectile according to its typology against the pandas within a certain range. Furthermore, among this range, it uses a policy to decide which panda to shoot.
  • There is a reload time, before the cupcake tower is able to shoot again.
  • The cupcake tower can be upgraded (in a bigger cupcake!), increasing its stats and therefore changing its appearance.

Scripting the cupcake tower

There are a lot of things to implement. Let’s start by creating a new script and naming it CupcakeTowerScript. As we already mentioned for the Projectile Script, in this article, we implement the main logic, but of course there is always space to improve.

Shooting to pandas

Even if we don’t have enemies yet, we can already start to program the behavior of the cupcake towers to shoot to the enemies. In this article we will learn a bit about using Physics to detect objects within a range.

Let’s start by defining four variables. The first three are public, so we can set them in the Inspector, the last one is private, since we only need it to check how much time is elapsed. In particular, the first three variables store the parameters of our tower. So, the projectile prefab, its range and its reload time. We can write the following:

public float rangeRadius;  //Maximum distance that the Cupcake Tower can shoot
    public float reloadTime;   //Time before the Cupcake Tower is able to shoot again
    public GameObject projectilePrefab; //Projectile type that is fired from the Cupcake Tower
    private float elapsedTime; //Time elapsed from the last time the Cupcake Tower has shot

Now, in the Update() function we need to check if enough time has elapsed in order to shoot. This can be easily done by using an if-statement. In any case, at the end, the time elapsed should be increased:

void Update () {
        if (elapsedTime >= reloadTime) {
    //Rest of the code
        }
        elapsedTime += Time.deltaTime;
      }

Within the if statement, we need to reset the elapsed time, so to be able to shoot the next time. Then, we need to check if within its range there are some game objects or not.

if (elapsedTime >= reloadTime) {
         //Reset elapsed Time
       elapsedTime = 0;
         //Find all the gameObjects with a collider within the range of the Cupcake Tower
         Collider2D[] hitColliders = Physics2D.OverlapCircleAll(transform.position, rangeRadius);
//Check if there is at least one gameObject found            if (hitColliders.Length != 0) {
    //Rest of the code
            }
        }

If there are enemies within range, we need to decide a policy about which enemy the tower should be targeted. There are different ways to do this and different strategies that the tower itself could choose. Here, we are going to implement one where the nearest enemy to the tower will be the one targeted.

To implement this policy, we need to loop all all the game objects that we have found in range, check if they actually are enemies, and using distances, pick the nearest one. To achieve this, write the following code inside the previous if statement:

if (hitColliders.Length != 0) {
                //Loop over all the gameObjects to identify the closest to the Cupcake Tower
                float min = int.MaxValue;
                int index = -1;

                for (int i = 0; i < hitColliders.Length; i++) {
                    if (hitColliders[i].tag == "Enemy") {
                        float distance = Vector2.Distance(hitColliders[i].transform.position, transform.position);
                        if (distance < min) {
                            index = i;
                            min = distance;
                        }
                    }
                }
                if (index == -1)
                    return;
       //Rest of the code
            }

Once we got the target, we need to get the direction, that the tower will use to throw the projectile. So, let’s write this:

//Get the direction of the target 
                Transform target = hitColliders[index].transform;
                Vector2 direction = (target.position - transform.position).normalized;

Finally, we need to instantiate a new Projectile, and assign to it the direction of the enemy, as the following:

//Create the Projectile
                GameObject projectile = GameObject.Instantiate(projectilePrefab, transform.position, Quaternion.identity) as GameObject;
                projectile.GetComponent<ProjectileScript>().direction = direction;

Instantiate Game Objects it is usually slow, and it should be avoided. However, for the learning propose we can live with that. And that is it for shooting to the enemies.

Upgrading the cupcake tower, making it even tastier

In order to create a function to upgrade the tower, we first need to define a variable to store the actual level of the tower:

public int upgradeLevel;  //Level of the Cupcake Tower

Then, we need an array with all the Sprites for the different upgrades, like the following:

public Sprite[] upgradeSprites; //Different sprites for the different levels of the Cupcake Tower

Finally, we can create our Upgrade function. We need to upgrade the graphics, and increase the stats. Feel free to tweak this values as you prefer. However, don’t forget to increase the level of the tower as well as to assign the new sprite. At the end, you should have something like the following:

public void Upgrade() {
        rangeRadius += 1f;
        reloadTime -= 0.5f;
        upgradeLevel++;
        GetComponent<SpriteRenderer>().sprite = upgradeSprites[upgradeLevel];
    }

Save the script, and for now we have done with it.

A pre-cooked cupcake tower through Prefabs

As we have done with the Sprinkle, we need to do something similar for the cupcake Tower. In the Prefabs folder in the Project Panel, create a new Prefab by right clicking and then navigate to Create | Prefab. Name it SprinklesCupcakeTower.

Now, drag and drop the Sprinkles_Cupcake_Tower_0 from the Graphics/towers folder (within the cupcake_tower_sheet-01 file) in the Scene View. Attach the CupcakeTowerScript to the object by navigating to Add Component | Script | CupcakeTowerScript. The Inspector should look like the following:

We need to assign the Pink_Sprinkle_Projectile_Prefab to the Projectile Prefab variable. Then, we need to assign the different Sprites for the upgrades. In particular, we can use Sprinkles_Cupcake_Tower_* (replacing the * with the level of the cupcake tower) from the same sheet as before. Don’t worry too much about the other parameters of the tower, like the range radius or the reload time, since we will see how to balance the game later on. At the end, this is what we should see:

The last step is to drag this game object inside the prefab. As a result, our cupcake tower is ready.

Summary

In this article we covered the topic of creating a cupcake tower and scripting it.

Resources for Article:


Further resources on this subject:


Packt

Share
Published by
Packt

Recent Posts

Top life hacks for prepping for your IT certification exam

I remember deciding to pursue my first IT certification, the CompTIA A+. I had signed…

3 years ago

Learn Transformers for Natural Language Processing with Denis Rothman

Key takeaways The transformer architecture has proved to be revolutionary in outperforming the classical RNN…

3 years ago

Learning Essential Linux Commands for Navigating the Shell Effectively

Once we learn how to deploy an Ubuntu server, how to manage users, and how…

3 years ago

Clean Coding in Python with Mariano Anaya

Key-takeaways:   Clean code isn’t just a nice thing to have or a luxury in software projects; it's a necessity. If we…

3 years ago

Exploring Forms in Angular – types, benefits and differences   

While developing a web application, or setting dynamic pages and meta tags we need to deal with…

3 years ago

Gain Practical Expertise with the Latest Edition of Software Architecture with C# 9 and .NET 5

Software architecture is one of the most discussed topics in the software industry today, and…

3 years ago