2D Space Shooter 3: The Shooter Part

Jeff Minnear
5 min readMar 24, 2021

--

Continued from part 2.

Well, it wouldn’t be much of a shooter if we couldn’t shoot, now would it?

Time to start firing lasers! The easiest way to create something in the game at runtime is to make use of Prefabs and the Instantiate method. Prefabs are just game objects that are meant to be reused. Right click in the hierarchy and create a new 3D Object > Capsule.

Probably a little big…

In the inspector, name the capsule “Laser”. As always, reset its transform and then set its scale to around (0.25, 0.25, 0.25). Once you’re happy with its size relative to the player, go to the Project pane and create a new folder called Prefabs. Drag the Laser from the hierarchy into the Prefabs folder.

Now that we have a prefab of the laser, we need our player to be aware of it. Open the Player script and add the following before your speed variable.

public GameObject Laser;

The type “GameObject” is important, because its what the Instantiate method will be expecting. Save your script and jump back to the Unity editor. It will compile for a moment and then if you highlight your Player object in the hierarchy, you’ll notice its Player component now has a slot called Laser. Drag your Laser prefab from the Project pane into this slot.

Now that we have a reference to the Laser prefab, we can add logic to create a laser every time the player hits the spacebar. To keep controller support, we’ll also map this functionality to button 2 (X on an XBox controller). Add the following code to your Update function.

Input.GetKeyDown checks to see if a particular key was pressed this frame. There’s also an Input.GetKey method which instead checks to see if the key is currently pressed and will continue to trigger as long as it stays pressed, but GetKeyDown is perfect for events that we only want the player to trigger deliberately.

Instantiate takes 3 parameters: the GameObject to instantiate, a Vector3 telling it where to create the object, and a Quaternion rotation. Quaternions are a complicated subject, but most of the time you’ll instantiate objects without any additional rotation, so you can just use Quaternion.identity.

Save your changes, and then run your game. Every time you press spacebar it creates a new Laser!

However, lasers aren’t much use if they don’t move. So let’s add a new script, name it Laser, and add it to our Laser prefab. If you click the Laser item in the Prefabs folder, you can add components just like you could for an item in the hierarchy. Doing this will also add the component to all instances of the prefab in the hierarchy. This is the power of prefabs. Well, some of it anyway.

Open the Laser script and add the following.

This is pretty similar to what we did for the player. The only difference is that we don’t need to capture any user input. The laser always moves straight up. And Unity has a handy constant called Vector3.up that provides that for us.

This is working pretty well, but you may have noticed all those Laser(Clone)s piling up in the hierarchy. We’re never telling Unity to get rid of the lasers after we fire them, so they just keep going. Forever. Imagine we were playing the game for an hour and our computer had to keep track of every single laser we fired in that time and keep calculating their positions. It would start to take up quite a bit of memory. So, lets clean them up after they get off screen.

There are a few new concepts here. We’ve added some additional variables to define how far a laser is allowed to go, and keep track of the distance travelled.

(transform.position - lastPosition).magnitude

This might look a little odd, but it’s just measuring the distance between two points. Subtracting one Vector3 from another returns a third Vector3, and the magnitude property gives its length. If you’re unfamiliar with vectors in general, they are just a way of representing a value with both direction and magnitude. In this case, the direction is up, and the magnitude is the distance the laser moved since the last frame.

Finally, if the total distance travelled exceeds the laser’s range, we Destroy it. This method is pretty self-explanatory, but it literally destroys an existing GameObject. It also takes an optional float that represents the number of seconds to wait before destroying the object, but we don’t need that here.

And there you have it! We fire a laser every time we press the spacebar, it travels upwards, and eventually destroys itself to free up memory. We’re well on our way to making a playable prototype.

Continued in part 4.

--

--

Jeff Minnear

Jeff is a software developer and musician. He’s quite fond of red curry.