Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Sort functions?

Discussion in 'Editor & General Support' started by MosquitoByte, Sep 2, 2020.

  1. MosquitoByte

    MosquitoByte

    Joined:
    Sep 17, 2018
    Posts:
    213
    Hello all, trying to make a script that sorts a bunch of objects based on a variable they have called speed, ordered from highest to lowest, following this part of this tutorial as i've only ever worked with sorting once before, and that was a while ago:


    however unity is unity, so it's giving me an error, that error being: https://i.gyazo.com/9ba9ebdcfda4b720761f4cd14f5a04fe.png

    my code is as such:
    Code (CSharp):
    1.     void Start()
    2.     {
    3.         Turn.AddRange(GameObject.FindGameObjectsWithTag("Player"));
    4.         Turn.AddRange(GameObject.FindGameObjectsWithTag("Enemy"));
    5.         Turn.Sort(SortSpeeds);
    6.     }
    7.  
    8.     int SortSpeeds(UnitMonoBehavior a, UnitMonoBehavior b)
    9.     {
    10.         if(a.SPEED < b.SPEED)
    11.         {
    12.             return -1;
    13.         }
    14.         else if(a.SPEED > b.SPEED)
    15.         {
    16.             return 1;
    17.         }
    18.         return 0;
    19.     }
     
  2. MosquitoByte

    MosquitoByte

    Joined:
    Sep 17, 2018
    Posts:
    213
    the error is gone now that i changed the code to the following:
    Code (CSharp):
    1. public class BattleSystem : MonoBehaviour
    2. {
    3.     public List<UnitMonoBehavior> Turn = new List<UnitMonoBehavior>();
    4.  
    5.     // Start is called before the first frame update
    6.     void Start()
    7.     {
    8.         List<GameObject> TurnGO = new List<GameObject>();
    9.  
    10.         TurnGO.AddRange(GameObject.FindGameObjectsWithTag("Player"));
    11.         TurnGO.AddRange(GameObject.FindGameObjectsWithTag("Enemy"));
    12.  
    13.         for(int i = 0; i < TurnGO.Count; i++)
    14.         {
    15.             Turn.Add(TurnGO[i].GetComponent<UnitMonoBehavior>());
    16.         }
    17.  
    18.  
    19.         Turn.Sort(SortSpeeds);
    20.     }
    21.  
    22.     int SortSpeeds(UnitMonoBehavior a, UnitMonoBehavior b)
    23.     {
    24.         if(a.SPEED < b.SPEED)
    25.         {
    26.             return -1;
    27.         }
    28.         else if(a.SPEED > b.SPEED)
    29.         {
    30.             return 1;
    31.         }
    32.         return 0;
    33.     }
    (turn was previously an array of gameobjects, no duh the sort wouldn't take it, it's meant for a different class.)
    however the sorting thing is still an issue. no matter what i change the speeds to it doesnt seem to actually be sorting them, they show up in the same order in the inspector regardless of speed.
     
  3. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    How is the
    SPEED
    variable declared? How are those values being populated?
     
  4. MosquitoByte

    MosquitoByte

    Joined:
    Sep 17, 2018
    Posts:
    213
    Speed is an int value on the UnitMonoBehavior
     
  5. MosquitoByte

    MosquitoByte

    Joined:
    Sep 17, 2018
    Posts:
    213
    decided to add some logging to try to get an idea of whats up:
    Code (CSharp):
    1.  int SortSpeeds(UnitMonoBehavior a, UnitMonoBehavior b)
    2.     {
    3.         if(a.SPEED < b.SPEED)
    4.         {
    5.             Debug.Log("lessthan");
    6.             return -1;
    7.         }
    8.         else if(a.SPEED > b.SPEED)
    9.         {
    10.             Debug.Log("morethan");
    11.             return 1;
    12.         }
    13.         Debug.Log("equal");
    14.         return 0;
    15.     }
    there are only two Units in the scene, one of them has a speed of -1 and the other a speed of 0.

    However: https://i.gyazo.com/8042e64750705efddd62575ec9f9903a.png

    what gives?
     
  6. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Can you show your UnitMonoBehavior code, and the inspectors of the two objects?
     
  7. MosquitoByte

    MosquitoByte

    Joined:
    Sep 17, 2018
    Posts:
    213
    Code (CSharp):
    1. public class UnitMonoBehavior : MonoBehaviour
    2. {
    3.     public Unit myUnit;
    4.  
    5.     #region stats
    6.     public int MaxHP;
    7.     public int CurrentHP;
    8.     public int MaxMP;
    9.     public int CurrentMP;
    10.     public int ATK;
    11.     public int DEF;
    12.     public int SPEED;
    13.     #endregion
    14.  
    15.     // Start is called before the first frame update
    16.     void Start()
    17.     {
    18.         MaxHP = myUnit.MaxHP;
    19.         CurrentHP = myUnit.CurrentHP;
    20.         MaxMP = myUnit.MaxMP;
    21.         CurrentMP = myUnit.CurrentMP;
    22.         ATK = myUnit.ATK;
    23.         DEF = myUnit.DEF;
    24.         SPEED = myUnit.SPEED;
    25.     }
    26.  
    27. }
    UnitMonoBehavior exists so multiple instances can come from the same ScriptableObject and thus have multiple of the same enemy without, for example, ending up having every enemy of a given type in the scene take damage from an attack to just one of them.

    battle system at runtime
    https://i.gyazo.com/66a1de4bade7cd999404f7314dda8b4c.png

    Player at runtime
    https://i.gyazo.com/a1adc11b80eab8e6da399ed48973d10d.png

    Enemy at runtime
    https://i.gyazo.com/6ce7dee496bbc1f92a2f8bab25624510.png
     
  8. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,495
    Does this work?
    Code (CSharp):
    1. Turn.Sort((x, y) => x.SPEED.CompareTo(y.SPEED)); // use (y, x) for opposite order
     
  9. MosquitoByte

    MosquitoByte

    Joined:
    Sep 17, 2018
    Posts:
    213
    Doesn't seem to, @polemical
    If you don't mind my asking, what's being done there?
     
  10. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    In Start you're overwriting speed with the speed from the Unit ScriptableObject. What are the speeds in those ScriptableObjects set to?
     
  11. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,495
    That's how I've been sorting objects by a .distance, has worked fine for me. Try logging the values of SPEED after sorting and see what's going on, i.e.
    Code (CSharp):
    1. foreach (UnitMonoBehavior obj in Turn)
    2. {
    3.   Debug.Log(obj.name + ": " + obj.SPEED);
    4. }
     
  12. MosquitoByte

    MosquitoByte

    Joined:
    Sep 17, 2018
    Posts:
    213
  13. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,495
    Try changing Start to Awake in UnitMonoBehavior
     
  14. MosquitoByte

    MosquitoByte

    Joined:
    Sep 17, 2018
    Posts:
    213
    that's what i thought of too, and it worked, thank you very much. Still curious as to how those sort parameters work, haven't worked with sort much, so i'm not sure how to work it, but i guess as long as it works.
     
    adamgolden likes this.
  15. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Ah ok so this was just a case of the Start functions running in an unfortunate order.
     
    adamgolden likes this.