Pilot! Protect Your Flanks!

Michel Besnard
6 min readMar 10

--

Objective: Implement a collectible secondary weapon system to your Unity 2D Space Shooter style game project which allows the player to fire lasers laterally for a limited amount of time.

Let’s set the scenario:…

So far, our little spaceship is equipped with a standard dual laser cannon and has a collectible triple-shot that fires a spread forward. Unfortunately, his flanks are left wide open to potential attacks. Now in his world, there are “Lateral Laser Cannons” available in his arsenal, but they were not fitted to his ship before he departed on his mission to defend the Galaxy.

The Space Battle Watch planning staff have captured this oversight and analyzed the player’s weakness. In order to assist, they’ve managed to beam ahead of the fight some Lateral Laser Cannon (LLC) units with self-contained lithium energy cores, with the hope they will eventually drift within his reach. Once collected, these will offer our player the ability to fire laser shots from his left and right flanks for a limited amount of time.

Let’s begin…

Step 1 ~ Creating the Lateral Laser “shot” and the Cannons.

I took the original laser png file, duplicated it, modified its shape and color, and renamed it “Lateral Laser”. I left the Tag as LaserPlayer to ensure collision detection with the Enemy ships.

Added the Box Collider 2D, Rigidbody 2D, and the Laser script to give it a behavior, before saving it as a Prefab.

Took the original laser.png sprite, and modified its shape so it would fan out on one end. Resaved it as Lateral Laser.png. The right image shows the desired effect.

I now need to create some cannons. After a bit of hunting on the web, I found this free asset and modified it as needed to suit my needs.

Found this image here.
And turned it into this using GIMP 2.10. Voila! I now have a laser cannon!

To create the Lateral Laser Cannon (LLC) Prefab, I started with an empty Game Object, renamed it “LateralLaserPowerUp”, attached my PowerUps script setting its default speed (comes from the Game Manager), Power Up ID to 5, audio clip and explosion prefab, and finally attached a Circle collider 2D and a Rigidbody 2D.

Within this Game Object, I added two children; LateralLaserCanonRight and LateralLaserCanonLeft. I then attached my RotatingObject script (see below) to each and set the values (Rotation Speed -50 & 50) so they would rotate in opposite directions and flipped the “right” sprite along its x-axis.

RotatingObject script ~ This allows the individual Game Object to rotate.

When the LLC Prefab is set in the Game Scene, you now have these two cannons floating together and spinning in opposite directions as they “drift” down the screen.

I added the left and right LLCs to the Player Game Object, turning them off when the Player is not equipped with them. When the Player collects the LLC Power-Up, I switch the SetActive back to True to make them once again visible.

Turning ON/OFF the LLCs.

Now that we have the Game Objects in place, let’s get the code up to speed in order to implement the desired behaviors.

Step 2 ~ Implementing the required logic.

We start by adding a couple of new variables to capture the new Game Objects and the required bool to verify whether or not the Player is equipped with the LLCs.

Player script ~ Adding a couple of game Object variables and a Bool to our script.

I then added an IF statement to the PlayerFireLaser() method. This checks the boolean to see if the Player has collected the LLCs, and if so, rotates the left and right ones as required so they fire laterally once instantiated. The slight offset along the x/y-axis is to ensure the Lateral Laser shot isn’t instantiated from the center of the ship, but rather at the ends of the respective cannons.

Player script ~ If equipped, this allows the Lateral Laser shots to be instantiated at the desired positions and translated away from the ship in the desired directions.

In my version of the game, if my Player has received too much damage, he will lose a life. If he loses that life before time runs out on the LLC collectible, I didn’t want him to respawn with them still attached. These few lines ensure that the boolean is switched back to False and that the Game Objects (LLCs) are turned off.

PlayerScript script ~ Turning off the LLCs when the Player loses a life.

When the Player collects the LLC Power-Up, LateralLaserShotActive() is called. If the Player is not yet equipped with the LLCs, it flips the boolean to True, turns on both LLC Game Objects by turning SetActive to True, then starts the StartLateralLaserTimerCoroutine coroutine. If, on the other hand, the Player was already equipped with LLCs, we call the StopLateralLaserTimerCoroutine() to stop the countdown, then the partially used LLCs get “dropped” by calling the DropLateralLaserCanons(), the new ones get mounted, and the 15-second timer restarts.

StartLateralLaserTimerCoroutine() allows the Player to use the LLCs for up to 15 seconds (while the Player has ammo).

Through trial and error, I found that by caching a reference to the StartLateralLaserTimerCoroutine() into LateralLaserTimer allowed me to smoothly reset the timer if a new LLC PowerUp was collected before the timer ran out.

After 15 seconds, DropLateralLaserCanons() gets called. This “ejects” the LLCs from the Player, leaving them to drift away, destroying them once they are out of the game view. I created this illusion by turning off the left and right LLCs on the Player, instantiating a new set of LLCs at the Player’s transform position, and translating them downwards.

Going back to our PowerUp script, add the new Lateral Laser PowerUp to the Switch statement (remember we gave it a Power Up ID equal to 5 in the Inspector settings above). This will communicate in turn with the Player script and execute the LateralLaserShotActive() method.

In the SpawnManager script, since the power-ups are stored in an array (_playerWeaponsPowerUps[]), there’s no need to hard code changes. The script will automatically adjust for the new weapon and pick one at random from inside the array.

The final result is demonstrated here:

I hope you enjoyed this quick article. Hopefully, it will help you with your own Unity 2D Game Project. Thanks for reading :)

--

--

Michel Besnard

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