# Issue picking the closest vector in a unique circumstance

I have a list of targets that can be picked depending on the magnitude from the vector created using:

  for(int i = 0; i < targetQueue.Count; i++) //2 loops to cycle through targets
{
for(int j = 0; j < targetQueue.Count; j++)
{   //if two targets are the same, then skip them
if(targetQueue[i] != targetQueue [j])
{
//getting the direction using the source and destination vectors
Vector3 iDir = targetQueue[i].transform.position - transform.position;
Vector3 jDir = targetQueue[j].transform.position - transform.position;

//comparing i with j, if i is less than target at j then match found
if(iDir.magnitude < jDir.magnitude)
{ //LockedTarget is a gameobject to show what target the turret is locked on to
LockedTarget = targetQueue[i]; //if match found then set locked target to target at i
break;
}
}
}
}


This code compares every target to each other, however it does this twice, once on each side( target[i] becomes target[j]). When the magnitude is compared, if the target[i] is smaller, then this is now the locked target as this target is closer to the turret.

This works every time except for one instance and I can't figure out why its happening here:

When both targets are inside the collider, the target on the right should still be highlighted, yet I get the target that is farther away being selected, this also occurs with more than two targets, with even stranger results. These being that the original target chosen for 'DEADLOCK' what i'm calling it, stays locked. Even when I move the other targets above, below, left and to the right of it.

This only occurs with this target, i've tried with 2 other targets (south of the turret) and it works as intended by properly switching based on size of magnitude of the direction vector between the target and the source.

I have ruled out the possibility being that it is an issue to do with adding target's to the gameobject list as it works everywhere else. When measuring the lengths of the magnitudes, the wrong target is chosen as the locked target. It does show that the closest target on the images does actually have the smallest vector magnitude.

UPDATE: the magnitudes of the vectors are increasing and decreasing by tiny amounts, 1 to 2 for a major movement. this makes sense as its worldPos. What doesn't make sense is the target on the right having a magnitude of 49 and the target above having a magnitude of 82, when according to world space they are pretty close to eachother.

Can anyone help me with this issue? its been driving me nuts for days.

It must be to do with the magnitudes of the direction vectors not being calculated properly.

• The issue with magnitudes was to do with the z-axis being different for each target. Silly mistake that is now fixed. i forgot all about it because i wasn't using it – Lonchenzo Jun 8 '20 at 14:06

This looks like a choice of the wrong algorithm for the job.

The code you've written does not find the closest transform in the collection. It does something more complicated. It returns the last transform in the list that's closer than at least one other transform in the list.

So if you have three objects {close, medium, far}, then this will return medium, because it comes after than close in the list, but still wins in its comparison against far.

If you just want the closest target, you can do this much more simply with a single loop:

float closestDistance = float.PositiveInfinity;
Transform closestTarget = null;

foreach (var target in targetQueue) {
// Using sqrMagnitude lets us skip unnecessary square roots.
float distance = (target.position - transform.position).sqrMagnitude;
if (distance > closestDistance)
continue;

closestDistance = distance;
closestTarget = target;
}

if (closestTarget != null) {
// ...Do something with your selected target.
}

• Thank you! very helpful. – Lonchenzo Jun 8 '20 at 14:05