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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Sorting an array by positions

Discussion in 'Scripting' started by DeanAseraf1, May 9, 2020.

  1. DeanAseraf1

    DeanAseraf1

    Joined:
    Aug 3, 2018
    Posts:
    16
    I have an array of Transforms in 2d that I want to sort by their positions in this way:

    if you pressed right:
    Create a sorted list of the objects from Right to Left.

    if you pressed left:
    Create a sorted list of the objects from Left to Right.

    if you pressed Up:
    Create a sorted list of the objects from Up to Down.

    if you pressed Down:
    Create a sorted list of the objects from Down to Up.


    This is the code I worte:

    Code (CSharp):
    1. void UpdateRobotsOrder(Vector2 movement)
    2.     {
    3.         robotsOrder = new List<iRobotScript>();
    4.         int h = 0;
    5.         float minimax = 0;
    6.         List<Transform> temps = new List<Transform>();
    7.         foreach (Transform rob in allRobots)
    8.         {
    9.             temps.Add(rob);
    10.         }
    11.         //Transform[] news = new Transform[temps.Count];
    12.         if (movement.x > 0)
    13.         {
    14.             minimax = -100;
    15.  
    16.             for (int u = 0; u < allRobots.Length; u++)
    17.             {
    18.                 for (int i = 0; i < temps.Count; i++)
    19.                 {
    20.                     if (temps[i].position.x > minimax)
    21.                     {
    22.                         //news[i] = temps[i];
    23.                         minimax = temps[i].position.x;
    24.                         h = i;
    25.                     }
    26.                 }
    27.  
    28.                 robotsOrder.Add(temps[h].GetComponent<iRobotScript>());
    29.                 temps.Remove(temps[h]);
    30.             }
    31.  
    32.         }
    33.         if (movement.x < 0)
    34.         {
    35.             minimax = 100;
    36.  
    37.             for (int u = 0; u < allRobots.Length; u++)
    38.             {
    39.                 for (int i = 0; i < temps.Count; i++)
    40.                 {
    41.                     if (temps[i].position.x < minimax)
    42.                     {
    43.                         //news[i] = temps[i];
    44.                         minimax = temps[i].position.x;
    45.                         h = i;
    46.                     }
    47.                 }
    48.  
    49.                 robotsOrder.Add(temps[h].GetComponent<iRobotScript>());
    50.                 temps.Remove(temps[h]);
    51.             }
    52.  
    53.         }
    54.         if (movement.y > 0)
    55.         {
    56.             minimax = -100;
    57.  
    58.             for (int u = 0; u < allRobots.Length; u++)
    59.             {
    60.                 for (int i = 0; i < temps.Count; i++)
    61.                 {
    62.                     if (temps[i].position.y > minimax)
    63.                     {
    64.                         //news[i] = temps[i];
    65.                         minimax = temps[i].position.y;
    66.                         h = i;
    67.                     }
    68.                 }
    69.  
    70.                 robotsOrder.Add(temps[h].GetComponent<iRobotScript>());
    71.                 temps.Remove(temps[h]);
    72.             }
    73.  
    74.         }
    75.         if (movement.y < 0)
    76.         {
    77.             minimax = 100;
    78.  
    79.             for (int u = 0; u < allRobots.Length; u++)
    80.             {
    81.                 for (int i = 0; i < temps.Count; i++)
    82.                 {
    83.                     if (temps[i].position.y < minimax)
    84.                     {
    85.                         //news[i] = temps[i];
    86.                         minimax = temps[i].position.y;
    87.                         h = i;
    88.                     }
    89.                 }
    90.  
    91.                 robotsOrder.Add(temps[h].GetComponent<iRobotScript>());
    92.                 temps.Remove(temps[h]);
    93.             }
    94.  
    95.         }
    96.     }
    This dosen't seems to work for me.. it works only if the first transform in the allRobots array is also the first in the robotsOrder list, otherways it debugs an error - Argument is out of range :\

    I actually managed to make it work but not in the best way (I checked all the positions in the grid by specific order instead of just check the objects positions)..

    Also i tried to use Array.OrderBy and list.Sort with no success. please help!
     
  2. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Actually, List.Sort and Array.OrderBy would be the best ways to go about this. Why don't you post the code you tried for that, tell us what did not work (i.e. what you expected to see versus what you got), and we'll go from there?
     
  3. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    First step would be to look into general sorting. You want to sort over one coordinate, for which you can find multiple good examples online, like here: https://forum.unity.com/threads/sorting-a-list-of-vector3-by-x-values.126237/

    Then write yourself 4 helper methods along these lines, using the found examples:
    Code (CSharp):
    1. public void SortRightToLeft(List<Vector2> positions){
    2.    positions.Sort((a, b) => a.x.CompareTo(b.x));
    3. }
    Afterwards simply call the right method for your needs and optionally wrap all of this in one method call which receives the pressed button:
    Code (CSharp):
    1. if(right){
    2.     SortRightToLeft(positions);
    3. }
    4. if(left){
    5.     SortLeftToRight(positions);
    6. }
    7. .
    8. .
    9. .
    Note: Normally i would suggest including the bool right/left into the calculations to save code lines, but in your case right = false does not mean left = true, since only one of the four options is true at a time from what you wrote. So it's probably best to handle the four as separate cases and chose one.
     
  4. DeanAseraf1

    DeanAseraf1

    Joined:
    Aug 3, 2018
    Posts:
    16
    both of them just kept return only one gameojbect, even if i cast them to an array or to a list (like .ToArray()).

    I think i found the solution, all i needed to do was to set the minmax variable in the first for loop and before, like this:
    Code (CSharp):
    1. public Transform[] allRobots;
    2. public List<iRobotScript> robotsOrder;
    3.  
    4. void UpdateRobotsOrder(Vector2 movement)
    5.     {
    6.         robotsOrder = new List<iRobotScript>();
    7.         int h = 0;
    8.         float minimax = 0;
    9.         List<Transform> temps = new List<Transform>();
    10.         foreach (Transform rob in allRobots)
    11.         {
    12.             temps.Add(rob);
    13.         }
    14.  
    15.         if (movement.x > 0)
    16.         {
    17.  
    18.             for (int u = 0; u < allRobots.Length; u++)
    19.             {
    20.                 minimax = -100;
    21.                 for (int i = 0; i < temps.Count; i++)
    22.                 {
    23.                     if (temps[i].position.x > minimax)
    24.                     {
    25.                         minimax = temps[i].position.x;
    26.                         h = i;
    27.                     }
    28.                 }
    29.  
    30.                 robotsOrder.Add(temps[h].GetComponent<iRobotScript>());
    31.                 temps.Remove(temps[h]);
    32.             }
    33.  
    34.         }
    35.         if (movement.x < 0)
    36.         {
    37.             for (int u = 0; u < allRobots.Length; u++)
    38.             {
    39.                 minimax = 100;
    40.                 for (int i = 0; i < temps.Count; i++)
    41.                 {
    42.                     if (temps[i].position.x < minimax)
    43.                     {
    44.                         minimax = temps[i].position.x;
    45.                         h = i;
    46.                     }
    47.                 }
    48.  
    49.                 robotsOrder.Add(temps[h].GetComponent<iRobotScript>());
    50.                 temps.Remove(temps[h]);
    51.             }
    52.  
    53.         }
    54.         if (movement.y > 0)
    55.         {
    56.             for (int u = 0; u < allRobots.Length; u++)
    57.             {
    58.                 minimax = -100;
    59.                 for (int i = 0; i < temps.Count; i++)
    60.                 {
    61.                     if (temps[i].position.y > minimax)
    62.                     {
    63.                         minimax = temps[i].position.y;
    64.                         h = i;
    65.                     }
    66.                 }
    67.  
    68.                 robotsOrder.Add(temps[h].GetComponent<iRobotScript>());
    69.                 temps.Remove(temps[h]);
    70.             }
    71.  
    72.         }
    73.         if (movement.y < 0)
    74.         {
    75.             for (int u = 0; u < allRobots.Length; u++)
    76.             {
    77.                 minimax = 100;
    78.                 for (int i = 0; i < temps.Count; i++)
    79.                 {
    80.                     if (temps[i].position.y < minimax)
    81.                     {
    82.                         minimax = temps[i].position.y;
    83.                         h = i;
    84.                     }
    85.                 }
    86.  
    87.                 robotsOrder.Add(temps[h].GetComponent<iRobotScript>());
    88.                 temps.Remove(temps[h]);
    89.             }
    90.  
    91.         }
    92.         MoveRobots(movement);
    93.     }
     
  5. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    No. By definition, it sorts a list of positions. It doesnt even return anything. So the result is, by definition, a sorted list.
    I mean, in your case you'd probably use a list of gameobjects instead, but the idea is the same, you'd just replace b.x with b.transform.position.x and so on. The result would be a list of sorted gameobjects according to their position on the axis determined by the pressed button (in my example represented by a bool 'right', 'left', ..).

    It certainly works this way, but if you found a solution that works for you that's good as well.