Creating Modular Powerup Systems.

Michel Besnard
3 min readJun 24, 2021

--

Objective: create a modular system to identify and process randomly spawned “powerup” game objects in Unity.

The approach to creating a modular system to handle your game powerups stems from the idea that they all share a similar logic. While the SpawnManager will look after spawning the powerups at various times, there are other common features these powerups will share. They all need to travel across the Game Scene, generally in the same manner. They need to be collectible when intercepted by the Player, and upon collection need to trigger a specific effect. Once collected, or after leaving the Game Scene, they need to be destroyed.

Since they all share so many common elements, it makes no sense to rewrite the same code to define the behavior for each powerup, even if how they affect the gameplay will vary.

The question then becomes: how do we modularize the powerup script? Instead of hard coding in the OnTriggerEnter2D method what happens when a powerup collides with other.tag == “Player’, we need to write the code in such a way as to detect which powerup collides, and only then set specific values in order to trigger a behavior associated to that unique powerup.

Let’s take this hard coded example and turn it into a more modular snippet.

How can we uniquely identify the powerup to which this script is attached? In my case, I am currently setting up three powerups. The first one is called TripleShot and it allows me to fire a volley of three laser shot over a period of five seconds. The second powerup temporarily increases the speed of my Player. While my third powerup activates a protective force field around my Player until a collision with an Enemy is detected.

Three powerups…How do we tell them apart upon detecting a collision?

It makes sense then to use an interger system to identify each powerup. So let’s create an ID for these powerups. in the example below, I’ve defined the type of variable as a private int, named it _powerupID, and serialized the field so I can see it and modify it in the Inspector. Attach the script to each powerup prefab and set its “Power Up ID” to a unique interger.

Let’s create a variable to store that unique ID.
Set the Power Up ID for each powerup prefab to its own unique ID. “0” for TripleShot, “1” for Speed, and “2” for Shields.

So now, when a collision is detected between a powerup and the game object tagged as “Player” (and the PlayerScript is not null), we can run through the Power Up IDs using a Switch statement. If the _powerUpID equals zero (case 0:), then we run the TripleShotActivate() method in the PlayerScript script. If it’s one (case 1:), we run the SpeedBoostActivate() method. And finally, if it’s two (case 2:), the ShieldActivate() method is called.

We could have used IF-ELSE statements, but SWITCH allows for much cleaner code.

Using this approach of setting a unique ID value to each powerup allows us to easily differentiate between these game objects, which in turn ensures we call the correct function. We are left with a single script that can be easily modified to handle expansion by simply adding another case x: to the Switch statement.

--

--

Michel Besnard
Michel Besnard

Written by Michel Besnard

Military member with 35+ years of service, undertaking an apprenticeship with GameDevHQ with the objective of developing solid software engineering skills.

No responses yet