Problem with choosing the closest game object
Hello, i'm kind of new here so i need some help, any hints would be appreciated. :) i have this code that looks for the closest game object tagged with enemy, and sets that as the object closestenem for later use. the problem is, after the code finds the closest object tagged with enemy for the second time, it doesn't update the closestenem object. i tried moving the code to FixedUpdate but it didnt help at all. here is the code i'm using :
void Update () {
enemy = GameObject.FindGameObjectsWithTag ("enemy");
//finding the closest enemy
foreach (GameObject enem in enemy) {
tempdist = Vector3.Distance (transform.position,enem.transform.position);
if (tempdist < distance) {
closestenem = enem;
distance = tempdist;
}
}
}
Answer by flashframe · Sep 03, 2016 at 02:20 PM
You need to reset the distance on each frame, since you're only interested in the closest enemy for this frame, not for all time.
void Update()
{
FindClosestEnemy();
}
void FindClosestEnemy()
{
enemies = GameObject.FindGameObjectsWithTag ("enemy");
float distance = 100f; // Any large number will do as long as it's further than any enemy could be
foreach (GameObject e in enemies) {
float tempdist = Vector3.Distance (transform.position,e.transform.position);
if (tempdist < distance) {
closestEnemy = e;
distance = tempdist;
}
}
}
If the amount of enemies never changes, I'd also recommend only finding them at the start to avoid calling FindObjectsWithTag every frame.
GameObject[] enemies;
GameObject closestEnemy;
void Start()
{
enemies = GameObject.FindGameObjectsWithTag ("enemy");
}
void Update()
{
FindClosestEnemy();
}
void FindClosestEnemy()
{
float distance = 100f; // Any large number will do as long as it's further than any enemy could be
foreach (GameObject e in enemies) {
float tempdist = Vector3.Distance (transform.position,e.transform.position);
if (tempdist < distance) {
closestEnemy = e;
distance = tempdist;
}
}
}
If the number of enemies does change, you could consider creating an object pool. https://unity3d.com/learn/tutorials/topics/scripting/object-pooling
And finally, instead of calling this function in Update, you could run a Coroutine and check for the closest enemy less often. It depends on how precise it needs to be.
IEnumerator FindClosestEnemy()
{
while(true)
{
float distance = 100f; // Any large number will do as long as it's further than any enemy could be
foreach (GameObject e in enemies) {
float tempdist = Vector3.Distance (transform.position,e.transform.position);
if (tempdist < distance) {
closestEnemy = e;
distance = tempdist;
}
}
yield return new WaitForSeconds(0.1f); //update as often as you like
}
}
Thank you so much for your answer it helped a lot ! right now, i fixed the problem thanks to your help while keeping the functions in the Update event. I will try to use the object pool solution soon, as i need some time to learn how to use it, but it looks like a perfect solution ! Thank you!
You're welcome, glad you got it working. Definitely check out object pools when you get the chance :-)