Objective: Implement Homing Projectile, Create a homing projectile that seeks the closest target.
Before doing this we need to make sure we assign all enemies to a tag of the enemy.
In the first step add box collider2D and a c sharp script, and attach it to the homing projectile sprite. Then position it relative to the player where you want it to be fired and record the value of the transform.
Note: After positioning it drag the homing projectile to the prefab folder and delete the projectile from the hierarchy.
Now open the script, create an array of game objects, and name the variable as enemies.
Create another variable for holding the closest enemy name this game object the closestenemy.
Also, create a float variable and name it the closestEnemyDistance and initialize it as an Infinity positive value in the Start method, to set a variable to an infinity positive value we use Mathf.Infinity.
Set closest Enemy as a null game object when the script is enabled in the start method.
In the next step, create a method for calculating the closest enemy name it as GetClosestEnemy.
Inside the closest enemy find all enemies with tag enemy, we do this by assigning the enemies array equal to GameObject dot FindGameObjectsWithTag.
Note: since we have many enemies make sure the method is plural which means it needs to be FindGameObjectsWithTag and not FindGameObjectWithTag.
Create a loop inside this method to iterate to all game objects in the array of enemies.
We need to create a local float variable name it as current distance and then assign it to the calculated distance, between each enemy in the array of enemies with a homing projectile.
We need to check if the current distance, is less than the closest enemy distance, if the condition is true, we set the closest enemy distance to the current distance and the closest enemy to the enemy.
To move the homing projectile, we need to create two variables rigid body and bool variable first.
Also, we need two float variables of speed and rotation speed.
Get the rigid body component in the start and set isClosestEnemyFound to false.
Set is Closest Enemy found to true inside the if condition when we set the closest enemy equal to enemy.
Create another method name it as MoveToClosestEnemy, then check if closestEnemy is not equal to null, and inside check again if isClosestEnemyFound is equal to true.
Find the directionToEnemy which is equal to target(enemy) minus source(Projectile) and normalize it.
Note: we normalize since Vector3.cross need the Vectors which will be passed as parameters to be normalized to work correctly.
Let's find the cross product, we do this by using Vector3 dot cross but to have access to this value we need to assign a float variable. After finding a cross product, make sure to add a dot z since we need the third vector to determine where the target is facing.
Note: cross-product takes two Vectors, direction, and where the projectile is pointing but make sure to use local transform of the object which is transform.up.
Time to make the missile rotate toward the target, we use a rigid body method called AngularVelocity, but since the third vector is always perpendicular to the two vectors of the cross product we set the angular velocity equal to cross value, times minus rotationspeed to make it rotate correctly.
Time to move the homing missile, we use the velocity of the rigid body by set look direction and multiplying the speed.
If we don't have them and don't have the target we want to fire the homing projectile up and then destroy it when reaching a high distance.
When we hit the Enemy we need to destroy ourselves and the enemy, we use OntriggerEnter to do this.
Note: Set the tag of the homing projectile as missile so all enemies will be destroyed when colliding with the projectile.
Last call the GetCloseEnemy to the update since we need to frequently check every frame if we have the target as the closest enemy. And call the MoveToClosestEnemy in the fixed update, since we are working with the physics component so the calculation to work correctly needs to be calculated inside the fixed update.
Note: I won't go through how to turn this into a powerup and how to fire it inside the player script if you want to know how to implement those go check my previous article.
Let's see the final result.