Unity: Implementing ‘seeking’ projectiles
Our basic laser projectile is the default for our game but let’s add an occasional, over-powered projectile that ‘seeks’ an enemy when fired.
First, we add the photon laser (that’s what I’m calling it) power-up collectable in the usual way; duplicating an existing powerup, changing the artwork and the powerup ID, and assigning in the Spawn Manager. I won’t go into detail, I’ve covered this in previous articles.
In our Powerup.cs script, we just need to add another case to our Switch statement to call a new method in our Player.cs script.
In here we need to make a fair few changes, but nothing we haven’t done before. We have a bool to check if the photon lasers are active which alters our fire action. We also have a coroutine to deactivate the photon lasers after the duration is over.
Note that we don’t decrease the ammo for the photon laser; this is by design to make this an extra powerful power-up.
The real detail is in the PhotonLaser.cs script which is attached to our photon laser prefab.
On Start() it populates an array of GameObjects that are tagged ‘Enemy’. We use this to populate an array of Transforms for those GameObjects. Finally we will use this information to get the closest target when the GameObject is instantiated with GetClosestEnemy(); we could do this in Update but doing it once will keep the distance calculations to a minimum for now.
GetClosestEnemy() calculates the closest Transform in _currentEnemies by using the squared distances to targets to make the comparison more efficient. In reality, in a game like this, it won’t make a noticeable difference to perform a square root afterwards, but it’s good to try and save where we can! This method then returns a single target.
In Update(), if the array _currentEnemies is null, the photon laser will just behave like any laser and move up the screen. If there are targets, it will call MoveToTarget().
MoveToTarget() then takes the speed (step) and uses Vector3.MoveTowards() to move the photon laser towards the given target. As this is called every frame while _target is not null, the photon laser will now constantly adjust it’s movement until it reaches the target, at which point it is destroyed. We’ve tagged the photon as a ‘laser’ so the Enemy.cs script will treat it like our existing laser in terms of destroying the enemies.
One final tweak is to change our enemy tags to ‘Untagged’ when destroyed. This will prevent our photon lasers chasing enemies that are already vanquished!
And that’s it! If our player grabs this power-up, their enemies have nowhere to hide! We can potentially break this out from the normal power-ups as well to make it a rare occurrence. We could also make it a delayed power-up with a key-to-activate mechanic. Food for thought for future development!