Space Shooter 2D — Part 3
PEW!! PEW!! PEW!! (with a short delay between each)
Today I added a simple laser cannon to the player’s space ship. Pressing the spacebar fires a mock laser bolt from the nose of the player’s ship. Currently there is no limit to the ammo the ship has so I also had to make sure we were not littering the galaxy with random laser bolts!
So here is how I implemented everything:
I made a simple capsule object to be my mock laser bolt. Then scaled it WAY down to about 20% its original size. (We’ll bring in the fancy graphic later once we get everything working just right.) Next, I made this game object a ‘prefab’ (it will show a blue in the Hierarchy) so that I can very easily make copies (and easily make changes to all copies at once if you need to change anything.)
The code for firing the laser logically goes in the player script as it is the player who fire the laser. The script checks for the user input for movement and for firing the weapons. If the user presses the space bar (and the timer delay is met — explained later), the code will bring a copy of the laser bolt prefab and position it just at the upper edge of the player’s spaceship, hence the slight adjustment in its instantiated position in the code.
Also, you might notice a few new items in the initialization section at the top of the image. There are a couple of float values and the GameObject variable.
The GameObject variable actually holds a reference to the prefab (which we can assign in the Inspector). This allows the code to know exactly which game object we want to work with. Make sure to ALWAYS use the objects from the Project window when adding them to the scripts.
Inside the Update method there is an IF statement that continuously checks to see if the user presses the space bar. If they do, then the FireLaser() method is called. Well… That’s how it started working but without any type of cool-down, the user could fire as fast as they could tap the space bar. Not cool.
So the other two new variables help with that. Using the _fireRate added to the current running time of the game (Time.time) I was able to create a 0.2 second delay before the user could actually shoot the laser again.
It sounds complicated, but let’s walk through it. Note: the time stamps were created just for this example. Any resemblance to other time stamps, real or imagined, is purely coincidental.
- [00:00.0] game starts so Time.time is 00:00.0
- [00:00.1] Update() runs and checks for player movement input and firing input (assume player is spamming the space bar at all times). User wants to fire so we to see if the game time is greater that the _canFire time. It is because we initially set _canFire to -1. So the FireLaser() method is called. _canFire is updated to the current game time PLUS 0.2 seconds (the _fireRate delay)
- [00:00.2] The player mercilessly spams the space bar. Update() runs. The IF statement catches the spacebar being pressed but the time check fails. _canFire is 00:00.3, but the current game time is 00:00.2. So no pew pew.
- [00:00.3] Player is still spamming the spacebar. Update() runs. _canFire is equal to the current game time but not less than. So again, no pew pew.
- [00:00.4] Player is hitting the spacebar even faster. Update() runs. But this time, BOTH checks are true so we spawn or ‘instantiate’ a new laser bolt and send it on its merry way.
Okay so now the player is causing a new laser bolt to appear every 0.2 seconds. What happens to them? Well, they last as long as we let them. The game does nothing unless we tell it too. We need to give the laser bolt some instructions. We’ll start with the basics. Movement.
So, I created a script just for the laser bolt. Nothing fancy, just instructions on what to do once it is ‘instantiated’ into the game. This script has a speed variable and movement instructions. We wouldn’t want the laser bolt to just sit in one spot after all. That would be a mine (and those might come later).
I made the _speed variable visible in the inspector (you can see it in the prefab image) so anytime I wanted to try changing the speed, I could do so while working in the editor, even during run time (but remember, changes made during run-time are not saved so write them down if you need them!)
The laser now begins to move upwards at the designated speed as soon as it appears in the game. And it keeps moving upward. For as long as the game is running. See where this is going?? For 5–10 laser bolts this would not be an issue. Even for 100 it might be okay. But eventually the game will slow down and start to lag because there are just too many laser bolts to keep up with — even if we cannot see them they are STILL there. Zooming along.
So, how do we fix that? If you look back at the code, it checks the position of the laser bolt every frame (or update). Once the laser’s position on the Y-axis is above 8.0 (which is just off the top of the screen) the laser destroys itself. This removes the object from the game and frees up resources for other things. Neat huh!?
Now of course we will add more code to the lasers. They need to know if they hit anything and what that thing might be. Friendly fire? Not in my galaxy!
Here is how the final version looks. Notice the cloned prefab laser bolts being removed after they leave the screen.
And now I will PULL-COMMIT-PUSH the changes to Github for tomorrow the enemies arrive! See you there!