- Home /
Sort Items Based on distance to Camera
Hi, I've been stuck on this problem for a week now and I can't figure out what I'm doing wrong. Can anybody help?
The situation
The player is able to move the camera around the game field. When the player presses 'fire', the tower closest (or second-closest) to the camera should fire.
The towers are held in a list. When the player presses 'fire', the list is sorted. A delegate is used for sorting. The delegate finds the distance from one tower to the camera and compares it to the distance of another tower to the camera. This should put the list of towers in order from nearest to farthest from the camera. At this point, either index 0 or 1 is selected.
What's happening / what I don't understand
Regardless if the player moves the camera, the list is sorted differently every time 'fire' is pressed. Strangely, the sort order alternates between 2 specific orders. The tower list starts out with tower ID's in this order: 0,1,2,3,4,5 and after firing, the order changes to 3, 4, 5, 0, 1, 2. Firing again returns to 0,1,2,3,4,5. Then back to 3,4,5,0,1,2. So it alternates between these two orders.
Following is my code. What do I have wrong, or what do I need to change, to make it do what I want it to do?
This is the sorting delegate:
public static int TowerComparison (TowerWeapon a, TowerWeapon b) {
Vector3 camPosition = Camera.main.transform.position;
float distA = Vector3.SqrMagnitude(a.transform.position - camPosition);
float distB = Vector3.SqrMagnitude(a.transform.position - camPosition);
if (distA > distB) return 1;
if (distA < distB) return -1;
return 0;
}
This is the 'fire' code:
// listen for player input to fire
void Update () {
// no point in going further if the player hasn't tried to fire
if (!Input.GetMouseButtonDown(0)) return;
// order the weapons from closest to furthest from the camera
// "weapons" type is List<TowerWeapons>
weapons.Sort (GameUtilityMethods.TowerComparison);
// solution attempt #3 -- using for loop
// "numTowersAvailable" is a constant > 0 and < "weapons" length
for (int i = 0 ; i < numTowersAvailable ; i++) {
if (weapons[i].IsReady()) {
weapons[i].Fire (target);
break;
}
}
}
Thanks for any insight you can offer!
can you please provide the definition of Sort function as well.
Also explain GameUtility$$anonymous$$ethods.TowerComparison.
what is TowerComparison ?
You have a function named TowerComparison which takes 2 TowerWeapon arguments and in your call above, it doesn't take any arguments.
I think better you post the whole thing or at least what related in order to get help.
Answer by rageingnonsense · Feb 17, 2015 at 10:33 PM
float distA = Vector3.SqrMagnitude(a.transform.position - camPosition);
float distB = Vector3.SqrMagnitude(a.transform.position - camPosition);
Did you really mean to use "a" twice? distA and distB will always be the same, and as such your function always returns 0.
Correct code would be:
float distA = Vector3.SqrMagnitude(a.transform.position - camPosition);
float distB = Vector3.SqrMagnitude(b.transform.position - camPosition);
Your answer
![](https://koobas.hobune.stream/wayback/20220613183535im_/https://answers.unity.com/themes/thub/images/avi.jpg)