Find a Target
Lesson 7 of 18 in Coddy's Unity Game: Tower Defense course.
A tower shoots the enemy nearest to it, as long as that enemy is within the tower's range. To choose, the tower needs every enemy on the board. FindObjectsByType<Enemy> would search the whole scene every frame for every tower, so instead the enemies keep a list of themselves: a static list on the Enemy class, which each enemy joins in OnEnable and leaves in OnDisable. Unity calls OnDisable on an object that is being destroyed, so a dead enemy leaves the list too. Pickups in a game can do the same:
public class Pickup : MonoBehaviour
{
public static readonly List<Pickup> All = new List<Pickup>();
void OnEnable()
{
All.Add(this);
}
void OnDisable()
{
All.Remove(this);
}
}Finding the nearest is a loop that remembers the best so far. A magnet that pulls the nearest pickup within pullRange starts with no pickup and with the range as the best distance, so a pickup further away can never win:
Pickup best = null;
float bestDistance = pullRange;
foreach (Pickup pickup in Pickup.All)
{
// closer than the best so far? keep it, and its distance
}Vector3.Distance(a, b) gives the distance between two points. When nothing is within range, the loop keeps nothing, and the answer is null.Challenge
Medium- In
Enemy, addpublic static readonly List<Enemy> All, a new list. Each enemy adds itself inOnEnableand removes itself inOnDisable. - In
Tower, add a public floatrange(the ArrowTower prefab sets 4.5) and a private Enemytarget. - Every frame, set
targetto the enemy inEnemy.Allnearest to the tower, as long as it is withinrange. With no enemy in range,targetis null.
The tower does nothing with its target yet: the next lesson turns it to face it. Press Play, build a tower beside the path, then Check.
Try it yourself
using UnityEngine;
public class Tower : MonoBehaviour
{
public int cost = 50;
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.