Basic tower targeting system
When I first released the game, the enemy targeting system for the towers in Hyper Towers was to target whoever had the least displacement to the player's base. Today, I improved it a little bit, but it works a lot better now. I'm not sure how much of a performance impact it causes later in the game but for now, it works.
Each enemy now has an in-built distance variable
public float distanceToBase; // Path distance from this enemy to the base
As the topic suggests, each spawned/instantiated enemy now carries with them a distance-to-base variable. This variable is assigned a value at the start when an enemy is just spawned by adding the distances between all waypoints.
private void Start()
{
// Set starting distance of the enemy towards the base
GameObject waypointContainer = GameObject.Find("Waypoints"); // Find the waypoints container
Vector2 previousWaypointPosition = Vector2.zero; // This variable stores the current waypoint position for the next iteration to access inside the for loop
// Add the distances between each waypoint starting from the spawned position
for (int i = 0; i < waypointContainer.transform.childCount; i++)
{
Transform waypoint = waypointContainer.transform.GetChild(i);
Vector2 waypointPosition = waypoint.position;
// Add distance to base
if (i == 0) // First waypoint
{
distanceToBase = Vector2.Distance(gameObject.transform.position, waypointPosition);
}
else // Rest of the waypoints
{
distanceToBase += Vector2.Distance(waypointPosition, previousWaypointPosition);
}
previousWaypointPosition = waypointPosition;
}
previousPosition = gameObject.transform.position; // Update the enemy's starting position
}
After spawning the enemy, the distance variable of the enemy is updated irrespective to which direction it moves or where the base or waypoints are located in the game.
void Update()
{
// Calculate the distance the enemy moved since the last frame
float distanceMoved = Vector2.Distance(transform.position, previousPosition);
// Update the previous position for the next frame
previousPosition = transform.position;
// Update distance to base based on the distance moved
distanceToBase -= distanceMoved;
}
This function will work as long as there is no ability or tower which pulls the enemy backwards is introduced to the game. I doubt if this new function will be performance efficient since the calculation is carried out each frame for each enemy on the screen.
The towers will then target the enemy by comparing this distance variable.
// Detect all objects within the detectionRadius.
Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, detectionRadius, detectionLayer);
if (colliders.Length == 0) // Do not proceed if no enemies detected in range
{
enemyInRange = false;
return;
}
// Variable to store the shortest distance to the base
float shortestDistance = math.INFINITY; // This is as far as a distance could go, so any enemy in the game is closer than that
// Loop through the detected colliders.
foreach (Collider2D collider in colliders)
{
// Check if the detected collider is not the same as the current object's collider.
if (collider.gameObject != gameObject)
{
TargetDebug("Detected object: " + collider.gameObject.name);
GameObject enemyInView = collider.gameObject; // The current enemy in calculation
// Get the distance from enemy to the base
float distanceToBase = enemyInView.GetComponent<EnemyStats>().distanceToBase;
if (distanceToBase < shortestDistance) // Target this enemy only if it is has the shorter distance out of all enemies in range
{
shortestDistance = distanceToBase;
enemyInRange = true; // Tell the tower to start targeting
targetEnemy = enemyInView; // Set this enemy as the current target
}
}
}