Galaxy Shooter 2D — Heat Seeking Lasers
The enemies won’t even know what hit them!
My ship weapon arsenal has been getting a little stale, with just two weapons (if you include the default one). I’ve decided to add Heat Seeking Lasers, only looking for ship targets (the asteroids are ignored, but that doesn’t mean that they can get in the way).
It’s a basic weapon, but one that requires a bit of work to implement and to optimize. That’s why this article is completely focused on explaining how I implemented this.
Preparations
- This weapon is only obtained through a Heat Seek powerup. I added a new sprite and added a new enum to hold the powerup reference.
- I implemented the weapon swap in the Ship script, where it will replace temporarily the default laser prefab for the Heat Seek one.
- I created a “new” laser prefab where the Heat Seek Laser script will be added.
Implementation
Remember, before implementing a feature, you should always design it first. You can design it along the way, but it will take you more time to code as you‘ll think about what the feature should do and how to code it at the same time.
The Heat Seeking Lasers should behave like this:
- The laser needs a method to detect Enemies that surrounds the Laser. Optimally, using a Coroutine to avoid checking every frame for enemies and using Physics2D.OverlapCircleNonAlloc to detect enemies will allow for fast and optimized collision queries.
The Coroutine will be started in the OnEnable() method and will always be active until the laser is destroyed or disabled.
- The laser will chase only one target that has a Enemy script, and is the closest one to the laser in distance (the asteroid is dismissed). That means that, for every enemy detected, the laser will have to check who is the closest one.
- If a target has been selected, the GameObject will be rotated towards the direction between the laser and the chosen target. In any case, the laser will always move upwards in its local axis and with a constant speed.
- A target is deselected when the chosen Enemy has no life left, or a reference to that Enemy has been lost. The laser will lock on to that Enemy until the enemy is destroyed, and we also skip the expensive operation of looking for enemies.
- When the laser makes contact with a Damageable entity, deal damage to that entity and self-destroy (or self-disable).
- If the laser exits the screen in the Horizontal Axis, the laser will wrap around and enter again from the opposite side where it left the screen. Also, if it exits in the Vertical one, it will self-destroy / self-disable.
- As an extra, I want to visualize the radius of that laser for balance / debug purposes. To do that, I use Gizmos.