Final Modular Powerup System

Joseph Youngquist
6 min readJul 24, 2022

--

Objective:

Finalize the modular powerup system with speed and shields.

Backstory:

In yesterday’s article I introduced the powerup system with a Triple Shot powerup and laid the foundation for adding more powerups. Today, I’ll finish the powerup system and implement two more powerups: Speed and Shields.

Adding the Powerup sprites:

Adding the Speed and Shields powerups follow the same exact process as adding the Triple Shot GameObject Clicking and dragging the Speed Powerup Sprite into the Hierarchy window, making the animation and clicking and dragging into the Prefabs window. The same goes for the Shields Powerup.

But that’s where the differences end. There needs to be some updates to the SpawnManager in how we handle the powerups. If you recall, the SpawnManager behavior was in the following state:

What needs to change is how the Prefabs are getting registered with the SpawnManager. Right now, we’d need to make a GameObject for each powerup prefab, which means when a Game Designer comes in and says “Hey! We have this whole new powerup to add! It’s Awesome!” — we’d need to crack open the code and manually add it. This isn’t ideal.

The fix for this is simple:

Making the _powerUpPrefabs into a fixed size array of GameObject's will allow for adding more powerups in the future completely within the Unity Editor, no more code to modify for the SpawnManager. The SpawnManager also has some updates in the SpawnPowerUp()

Here the changes are really only around which powerup to spawn in. We randomize which index to use which is defined on line #71 and then we updated the Instantiate call to use the random prefab that was assigned on line #73. That pretty much wraps up the changes needed for the SpawnManager to be able to handle as many powerups as we can throw it.

There is work that has to be done in the PowerUp.cs behavior script. This script was TripleShot.cs in yesterday’s writeup but renaming it to PowerUp.cs makes more sense now that we have more powerups and their behavior are nearly identical. Below is the updated code, make special note of the public class PowerUp : MonoBehavior change to match the file rename.

The OnTriggerEnter2D() method has been expanded to include the additional powerups for Speed and Shields, calling the player.ActivatePowerUp() method with the appropriate name of the powerup being activated. Using a swtich statement vs if else calls makes the code a little easier to read and always shoot for easier code to read!

The Player.ActivatePowerUp() method has also changed so we can call the appropriate “cooldown” for the powerup that was passed.

The case clauses have been added for the additional powerup types and the call to StartCoroutine() for the appropriate cooldown have been setup. I’ve left the cooldowns as individual cooldowns to keep the code readable but a re-factor in the future does make sense — partly due to the similar code but also since there is an edge case lurking in this code. Namely, when a new powerup is spawned and collected while the same powerup effect is currently on the player, the newly collected powerup doesn’t extend the life of the effect. I’ll probably get around to correcting that in the future!

Shields Up!

The last item we need to address is when the player collects the Shields Powerup, we need to extend the shields around the player’s ship. But how in the world do we do that? It’s not as hard as you think. Unity makes it nearly a breeze!

Clicking on the Shields game art and dragging it over the Player GameObject in the Hierarchy window sets the Player as the Shields parent. What this means is when the player moves, so do the shields with the ship! How simple is that! The next thing is we don’t want the ships shields “active” unless the user has collected a Shields Powerup. Time to hit the Unity Docs. Life as a Software Engineer isn’t about knowing “all teh things”, it’s about being able to ask the right question and then finding the answer. I’m still learning Unity, I’m like on day 7 of a couple of hours each day in learning. What I do know how to do is read documentation and learn how to do something for myself. A quick search for “unity gameobject active” gave me a top result for:
Unity — Scripting API: GameObject.SetActive, exactly what I needed:

Activates/Deactivates the GameObject, depending on the given true or false value.

You actually saw the code implementation to raise and lower the shields in the ShieldsUpCooldown() earlier. _playerShields.SetActive(true) is how the shields go up and I also defined a _areShieldsActive bool so I can test when the player gets hit if the shields were up and if so, kill the shields and the player gets to live for another fight! Here’s the code that handles when the Enemy hits the player and makes a call to player.RemoveLife():

A quick check to see if the shields are active and if so, we deactivate them and return since we don’t need to remove a life from the player. If however, the player doesn’t have shields, then we still remove a life and do the check to see if the player is dead.

So, to recap:

We added new GameObject's for the new powerups, we added the shields and the logic that controls whether they are active or inactive and can spare the player a life if an enemy crashes into the player (or maybe hits the player with one of their own lasers! 🧐). We’ve updated the SpawnManager to be able to grow with more and more powerups as Game Designers come up with them. We could probably refactor some code so we can remove some of the still hardcoded logic needed in order to completely add new powerups but we’re in a pretty good place right now. The code is easy to read. For now, there are no more powerup plans. There are still those edge cases that could be addressed but I’ve not made up my mind on the direction I’d like to go with them. Do we want to just add bonus score points for claiming a powerup that is already active or do we want to extend the cooldown timer?

Next Steps:

In my next article I’ll start to implement the UI for the game. This means showing the player’s lives, score, start menu and game over screen with instructions on how to play again, plus some stats of the player’s gameplay!

--

--

Joseph Youngquist
Joseph Youngquist

Written by Joseph Youngquist

Veteran to Digital Media publishing, Software Engineering and Architecture starting on a pivot to Unity Development

No responses yet