Search Unity

Help Select Objects Closest to Camera, From a List

Discussion in 'Scripting' started by MadRobot, Feb 17, 2015.

  1. MadRobot

    MadRobot

    Joined:
    Jul 12, 2011
    Posts:
    339
    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:
    Even when the player does not move 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:

    Code (csharp):
    1. public static int TowerComparison (TowerWeapon a, TowerWeapon b) {
    2.     Vector3    camPosition = Camera.main.transform.position;
    3.     float distA = Vector3.SqrMagnitude(a.transform.position - camPosition);
    4.     float distB = Vector3.SqrMagnitude(a.transform.position - camPosition);
    5.  
    6.     if (distA > distB) return 1;
    7.     if (distA < distB) return -1;
    8.     return 0;
    9. }
    This is the 'fire' code:

    Code (csharp):
    1. //    listen for player input to fire
    2. void Update () {
    3.  
    4.     //    no point in going further if the player hasn't tried to fire
    5.     if (!Input.GetMouseButtonDown(0)) return;
    6.  
    7.     //    order the weapons from closest to furthest from the camera
    8.     //    "weapons" type is List<TowerWeapons>
    9.     weapons.Sort (GameUtilityMethods.TowerComparison);
    10.  
    11.     //    solution attempt #3 -- using for loop
    12.     //    "numTowersAvailable" is a constant > 0 and < "weapons" length
    13.     for (int i = 0 ; i < numTowersAvailable ; i++) {
    14.         if (weapons[i].IsReady()) {
    15.             weapons[i].Fire (target);
    16.             break;
    17.         }
    18.     }
    19. }
    Thanks for any insight you can offer!
     
  2. Dameon_

    Dameon_

    Joined:
    Apr 11, 2014
    Posts:
    542
    distA and distB will always be equal on lines 3 and 4, since you're setting them the same. Guessing you pasted and forgot to change an a to a b.
     
    JoeStrout likes this.