Search Unity

Question Sorting instantiated GameObjects

Discussion in 'Scripting' started by pepperpowermax, Jan 18, 2022.

  1. pepperpowermax

    pepperpowermax

    Joined:
    Dec 26, 2021
    Posts:
    1
    Hi. I'm new to Unity and I've been following a youtube card game tutorial and trying to adapt it to the game I'm trying to make.

    In the tutorial, they create the "Hand" (cards for the player) from the deck of cards by instantiating a GameObject (From this "PlayerDeck" script I'm just posting what I THINK is relevant to the issue):

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerDeck : MonoBehaviour
    6. {
    7.     public GameObject CardToHand;
    8.  
    9.     void Start()
    10.     {
    11.         StartCoroutine(StartGame());
    12.     }
    13.     IEnumerator StartGame()
    14.     {
    15.         for(int i=0; i < 5; i++)
    16.         {
    17.             yield return new WaitForSeconds(0);
    18.             Instantiate(CardToHand, transform.position, transform.rotation);
    19.         }
    20.     }
    21. }
    From the scripts on that GameObject, this is the one I THINK is relevant here:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CardToHand : MonoBehaviour
    6. {
    7.     public GameObject Hand;
    8.     public GameObject It;
    9.     //I ADDED THE NEXT TWO LINES
    10.     public int id;
    11.     public int index;
    12.  
    13.     void Update()
    14.     {
    15.         Hand = GameObject.Find("Hand");
    16.         It.transform.SetParent(Hand.transform);
    17.         It.transform.localScale = Vector3.one;
    18.         It.transform.position = new Vector3(transform.position.x, transform.position.y, -48);
    19.         It.transform.eulerAngles = new Vector3(25, 0, 0);
    20.  
    21.         //I ADDED THE NEXT LINES
    22.         ThisCard thisCard = It.GetComponent<ThisCard>();
    23.         id = thisCard.id;
    24.  
    25.         It.transform.SetSiblingIndex(id);
    26.  
    27.         index = It.transform.GetSiblingIndex();
    28.     }
    29. }
    Now, I want the 5 cards in the hand to be ordered by ascending order according to their "id".

    I tried doing it through SetSiblingIndex, but the problem is that "id" is an int that can be any number from 0 to 19 and there's only 5 cards (sibling index 0 to 4). So, all the cards with an "id" bigger than 4, the sibling index puts them at 4 and they don't really sort in order.

    I also tried, in the PlayerDeck script, instantiating to a list and using the Sort method on that list (https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.sort?view=net-6.0). However, because I'm a noob, I encountered problems with properties. Because it's a list of GameObjects, I don't know how to make it have the same properties as the other lists in the project, that are made from a class, namely the "id" property I need now and the two other properties I know I'll need to use later.

    Can someone help?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    This is certainly an easy way but you need to do a few extra steps:

    - put the
    CardToHand
    items into a temporary array

    - use System.Array.Sort() to sort that array (you would provide a delegate or comparator that sorts based on your
    id
    )

    - iterate that now-sorted array and set the transform sibling index from 0 to 4 for the five cards.

    Remember though, sibling index only reliably changes visible sort order in the UnityEngine.UI space. Are these UnityEngine.UI objects such as Images? Or are they sprites.

    Either way, keep this blurb of knowledge in mind:

    Three (3) different ways that Unity draws / stacks / sorts / layers / overlays stuff:

    https://forum.unity.com/threads/orthographic-camera-rendering-order.1114078/#post-7167037

    In short,

    1. The default 3D Renderers draw stuff according to Z depth - distance from camera.

    2. SpriteRenderers draw according to their Sorting Layer and Sorting Depth properties

    3. UI Canvas Renderers draw in linear transform sequence, like a stack of papers

    If you find that you need to mix and match items using these different ways of rendering, and have them appear in ways they are not initially designed for, you need to:

    - identify what you are using
    - search online for the combination of things you are doing and how to to achieve what you want.

    There may be more than one solution to try.

    Additional reading in the official docs:

    https://docs.unity3d.com/Manual/2DSorting.html
     
    pepperpowermax likes this.