- Home /
make a gameobject follow an array of targets
I wish to make a specific game object attack a specific target, and after that target is gone (Destroyed), go to the next closest target. As long as all the targets exists, my script works well enough, but once a target is destroyed.. the errors come flying in.
I have a public array of 3 targets (3 exactly, won't change), I calculate which one is closest to the gameobject, and it goes there (the "walking" works perfectly). I believe the issue is that even though the target has been destroyed, the array doesn't update itself (it's an update of transforms) so the function will always return the same transform.
Do you have an idea of how to solve this issue?
using System;
using UnityEngine;
public class attack_target : MonoBehaviour {
public Transform[] hearts;
public float speed = 1f;
private Transform target;
// Use this for initialization
void Start ()
{
target = GetClosestEnemy(hearts);
}
private Transform GetClosestEnemy(Transform[] hearts)
{
Transform bestTarget = null;
float closestDistanceSqr = Mathf.Infinity;
Vector3 currentPosition = this.transform.position;
foreach (Transform potentialTarget in hearts)
{
Vector3 directionToTarget = potentialTarget.position - currentPosition;
float dSqrToTarget = directionToTarget.sqrMagnitude;
if (dSqrToTarget < closestDistanceSqr)
{
closestDistanceSqr = dSqrToTarget;
bestTarget = potentialTarget;
}
}
return bestTarget;
}
// Update is called once per frame
void Update ()
{
while(target != null)
{
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
this.target = GetClosestEnemy(hearts);
}
}
Answer by Nebukam · Apr 21, 2018 at 01:00 AM
Destroying a GameObject does not automatically erase the references to it (in this case, the reference inside your array of Transforms), you need to maintain the array yourself. An easy fix would be to update your GetClosestEnemy function like so :
private Transform GetClosestEnemy(Transform[] hearts)
{
Transform bestTarget = null;
float closestDistanceSqr = Mathf.Infinity;
Vector3 currentPosition = this.transform.position;
foreach (Transform potentialTarget in hearts)
{
if(potentialTarget == null){ continue; }
Vector3 directionToTarget = potentialTarget.position - currentPosition;
float dSqrToTarget = directionToTarget.sqrMagnitude;
if (dSqrToTarget < closestDistanceSqr)
{
closestDistanceSqr = dSqrToTarget;
bestTarget = potentialTarget;
}
}
return bestTarget;
}
the line if(potentialTarget == null){ continue; }
will skip any destroyed Transform.
Note that is not an optimal solution, and rather than using a fixed-size array of transform, you'd be better using a List and just remove Transform from it as they are destroyed.
Edit : note that once all target have been destroyed, GetClosestEnemy() will return a null result, hence I would change the line this.target = GetClosestEnemy(hearts);
by
Transform tempTarget = GetClosestEnemy(hearts);
if(tempTarget != null){ this.target = tempTarget; }
Thank you so much for your help! it works perfectly.
Also, thank you for the explanation and not only for a solution.
Your answer
![](https://koobas.hobune.stream/wayback/20220612161217im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
(C#) Follow target (script) transform target PREFAB 0 Answers
It is not possible to invoke an expression of type 'UnityEngine.Vector3'. 1 Answer
Rotating Y towards X/Z 1 Answer
character controller that follow a target 1 Answer
NullReferenceException when i try to access the transform of the object i collided with 2 Answers