Determining Which GameObject Is Closer To An Object.

I have an array of AI cars and a checkpoint.

What I’m trying to do is get which car is closer to that checkpoint in order.

I’ve calculated the distance from the checkpoint to the cars and I have a List that sorts the distances in order but I can’t figure out a way to get which car is closer to the checkpoint.

Here’s my code :

#pragma strict
import System.Collections.Generic;

var ai : GameObject[];
var myList = new List.<float>();

function Start () {
ai = GameObject.FindGameObjectsWithTag("AI");
}

function Update () {
for(var i : int = 0; i < ai.Length; i++){
myList[i] = ai[i].GetComponent(CarRank).distance;
}
myList.Sort();
}

Any help would be a relief, I’ve been trying to get this to work for hours.

If I’m understanding your problem right you could use your current list of Vector3.Distances (Unity - Scripting API: Vector3.Distance) then sort them based on the smallest value first, largest value last. Something really simple such as bubble sort (Bubble sort - Wikipedia) would be pretty ideal for sorting this kind of data.

Basically you want to store the gameObject for the car closest to the checkpoint then check all subsequent distances against that value, if another car is closer replace the gameObject for the closest car to the new closest one.

@Chambers Thanks for your reply.

My list already sorts the distances in order from the smallest. What I can’t manage to do is arrange my “AI” array according to my list.

For example, in the picture “Car1” corresponds to myList[0], “Car2” corresponds to myList[1] & “Car3” corresponds to myList[2]. How would I arrange my AI array in that order?

If I can figure this out then I’ll be able to get the rank of the cars (1st, 2nd, 3rd, etc) which is my goal.

I’m not sure I’m following your request, so in this example what order would you assign the cars in the list? Would you want it to be Car1 is the closest or something else? I think you may be overcomplicating this slightly. If you want to keep a reference of the gameObject and the distance from the checkpoint for that gameObject in the list, you could always make a list of structs rather than floats.

#pragma strict
var ai : GameObject[];
function Start () {
   ai = GameObject.FindGameObjectsWithTag("AI");
}
function Update () {
   var closest : GameObject = ai[0];
   var closestDistance : float = closest.GetComponent(CarRank).distance;
   for (var i : int = 1; i < ai.Length; i++)
   {
     var distance : float = ai[i].GetComponent(CarRank).distance;
     if (distance < closestDistance)
     {
       closestDistance = distance;
       closest = ai[i];
     }
   }
   //closest = the GameObject that is closest
   //closestDistance = how close
}

~
Another walk in the park.

@Chambers I want to arrange the cars according to which one is ahead so I can say something like :

ai[0].GetComponent(CarRank).rank = 1;
ai[1].GetComponent(CarRank).rank = 2;
ai[2].GetComponent(CarRank).rank = 3;

I want to use the distances in the list to determine which gameObject is ahead but I can’t figure out a way to do this. I might be over-complicating this but I really don’t know any other way to create a ranking system.

@TwixEmma Your code works perfectly! Thanks a lot.

The only thing is that It only gives me the gameObject that is closest (1st place), I’m looking for a way to make it give me who’s in 2nd, 3rd, 4th etc… Any ideas?

I’ve been going at this for a whole day now and I still cant get it to work the way I want it to.

@TwixEmma 's code could be extended to use a list as in your initial post, you just need to modify the line where the check if AI distance is closer than the closestDistance is performed. A nested loop that checks the AI list distances against the current closest distances then sets values accordingly would work.

#pragma strict
import System.Collections.Generic;
var ai : GameObject[];
var myList = new List.<GameObject>();
function Start () {
    ai = GameObject.FindGameObjectsWithTag("AI");
}
function Update () {
    myList.Clear();
    var closest : GameObject = ai[0];
    var closestDistance : float = closest.GetComponent(CarRank).distance;
    myList.Add(closest);
    for (var i : int = 1; i < ai.Length; i++)
    {
        var distance : float = ai[i].GetComponent(CarRank).distance;
        if (distance < closestDistance)
        {
            closestDistance = distance;
            closest = ai[i];
            myList.Insert(0, closest);
        }
        else
        {
            myList.Add(ai[i]);
        }
    }
    ai = myList.ToArray();
    //closest = the GameObject that is closest
    //closestDistance = how close
}

~
Another walk in the park.

1 Like

@TwixEmma You’re a life saver!

Your code did the trick. Thank you so much! :smile:

You’re welcome!

~
Another walk in the park.