Space Shooter: Firing a Laser
In this article I’ll be going over how to fire a laser. I’ll quickly skim over the old input system implementation and then dig a little into the New Input System implementation. Disregard some of the functionality I show in this article, for example, firing the triple shot. I’ll get into that later. I’ve gone ahead and implemented more things before writing this article to give myself a head start on developing this project. Lets go!
So to fire a laser, I’m going to be Instantiating it. Unity — Scripting API: Object.Instantiate (unity3d.com)
To instantiate a GameObject, it needs to be a prefab. I have created a simple capsule game object, called it laser, and created a folder in the project view called prefabs. I dragged the laser game object into that folder.
As you can see, the laser game object has turned blue in the hierarchy. This means it is now a prefab. I’ll get more into prefabs later. For now, just know, to instantiate an object it has to be a prefab.
Now for the script.
First we need some variables. In the player script, since the player is who handles firing a laser, I made a GameObject type called
laserPrefab, a float type called
_canFireand another float type called
fireRate. There are some other variables here too, but disregard for now.
OLD INPUT SYSTEM:
In the update function, all I want to have happen is when the player presses space bar, the laser instantiates. To do this is pretty straight forward.
If the space bar is pressed, instantiate the laser prefab at the transform.position of the player and ignore the rotation. Dont forget to assign the laser prefab in the inspector! Be sure to assign it from the project view and not the hierarchy. Delete the one in the hierarchy actually. You dont need it anymore.
Run the game, and you’ll see the laser instantiate when space is pressed! (disregard the enemy ships flying down lol I’ll get into that.)
But the laser doesnt move. Its just sitting there. We’ve handled moving objects in the past. So getting that working should be a breeze! Just be sure to destroy the laser after it leaves the screen. (when the y position > = whatgever number is off the screen.
I set the speed in the inspector to a number higher than the player movement speed just to make it look “realistic”. This script lives on the laser prefab.
What is this
OnTriggerEnter2D thing? disregard! We’ll get there. For now, set the speed variable in the inspector of the laser and then run the game! When you fire the laser it should move up!
NEW INPUT SYSTEM:
We have all the logic for the laser to instantiate and move up set up, so all thats left to do is get this to work with the new input system.
I created a new Action in the PlayerControls Action Map called “Fire”.
It is simply bound to the spacebar or the south button on a gamepad. A for Xbox controller, X for Playstation controller Etc. Its being treated like a button on the Action Type.
For this situation I implemented it a certain way. There are a million ways to achieve the same result with the input system, so I found this way to be the most straight forward.
In my Start() I not only enabled the PlayerControls, but I also set the performed action to the function below this screenshot.
Usually when you automatically generate this function the “context” says “obj”. I just chage it to context because it makes more sense to me.
This function is called everytime the space bar is pressed. I wanted to set up a cool down system for this laser so the player cant instantiate lasers as fast as they could press the button. Making the game too easy would in turn make it boring. So I created a bool called
fired. I set it to true as soon as this function happens. The
fireRate variables from earlier come into play now.
Time.time is how many seconds have passed since the game started. More about it here: Unity — Scripting API: Time.time (unity3d.com)
_canFire is set to -1 to begin with. When the laser is fired, _canFire is set to Time.time + the fireRate. This means if 1 second has passed and the player presses space, _canFire = 1.10 because fireRate is 0.1. Then another second passes causing Time.time to be 2 which is greater than _canFire which means you can fire again.
After I called the Fire()
fired = false; This prevents me from being able to call the fire method again until Time.time is greater than _canFire. Then I instantiate the laser.
This seems significantly more complex than a simple check for a button press, and maybe it is, but the ease in which controller support is implemented makes it worth it. Hopefully you were able to get something out of this. In the next few articles I’ll be going over powerups (the triple shot logic you’ve seen sprinkled throughout the code) and spawning enemies with a Spawn Manager.