Pick first object during a sort and then stop sorting

I need something like
//Vector3 nearest = PlayerUnits.Sort(delegate(Transform t) { return (transform.position - t.position).sqrMagnitude; }).First();
to exist…
to where it sorts, finds the first answer, and then stops sorting how is this possible? the only way to sort that i know of in c# is:

private IEnumerator DistanceToTarget()
   {
     //Sort so nearest enemy is always Enemies[0]
     PlayerUnits.Sort(delegate( Transform t1, Transform t2){
       return Vector3.Distance(t1.position,transform.position).CompareTo(Vector3.Distance(t2.position,transform.position));
     });
     yield return new WaitForSeconds(1f);
     AlreadyRunning = false;
   }

Which is horrible on performance for many cases i need a better method. The reason for this is i need to be able to have about 1000x1000 for this compareto that is constantly being done. There has to be a way…supreme commander is a good example it can handle 1000’s of units in realtime.

You want to find the closest target? That’s a search, not a sort.

I am sorting to find the nearest target…how else would you do this with so many objects for both the player and the enemy?

Been a while since a response guess no one has an answer to this one :smile:

Going along with what was said above, rather than Sort(), why not use Min() from Linq?

GameObject thing;
IList<GameObject> units;
//...
var myTarget = units.Min (o => (o.transform.position - thing.transform.position).magnitude);

Edit: misunderstood the question. You can use Aggregate similarly from Linq:

GameObject player;
IList<GameObject> units;
// ...
var myTarget = units.Aggregate ((a, b) =>
        {
                return (a.transform.position - player.transform.position).magnitude <
                       (b.transform.position - player.transform.position).magnitude ? a : b;
        });

I’m pretty sure that the implementations of LINQ that’s in Unity’s (very old) Mono implementation had some serious drawbacks. Also, even with the fastest search algorithms, 1000 units looking at the closest of 1000 other units in real time is just not viable; you’ll have to come up with a smarter solution.

You dont need to compare 1000 to 1000 others, you only need a single run through of all 1000. You can also discard magnitude in favor of sqrMagnitude to save on a sqrRoot calculation

float minDistance = float.maxValue;
int minIndex;
for(int i =0; i<list.Count; i++){
  float myDistance = (list[i].position - transform.position).sqrMagnitude;
  if(myDistance < minDistance){
    minDistance = myDistance;
    minIndex = i;
  }
}
return list[minIndex];

Typed here - no guarantee

Interesting, I didn’t know that! I wonder if anyone’s made their own extension library to compensate?

For the OP, I think you might want to look into using a quadtree: