Search Unity

How to change hierarchy order in layout groups through code

Discussion in 'UGUI & TextMesh Pro' started by itch, Sep 7, 2014.

  1. itch

    itch

    Joined:
    Apr 21, 2014
    Posts:
    5
    I need to be able to change the order of objects in layout groups dynamically. I can change the hierarchy order in the editor while the game runs and the group updates them fine, but I can't figure out how to do this through code.
    I know that hierarchy works with transform z position but in a group the transform of the child objects is driven by the group, and they all have z at 0 anyway...
     
  2. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Check out the api docs for Transform. Look for stuff with "Sibling" in the name, e.g. Transform.SetLastSibling, SetFirstSibling, SetSiblingIndex.
     
  3. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    something like this maybe

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Linq;
    3. public static class GameObjectExtensions
    4. {
    5.     public static void SortChildren(this GameObject gameObject)
    6.     {
    7.         var children = gameObject.GetComponentsInChildren<Transform>(true);
    8.         var sorted = from child in children
    9.                      orderby child.gameObject.activeInHierarchy descending, child.localPosition.z descending
    10.                      where child != gameObject.transform
    11.                      select child;
    12.         for (int i = 0; i < sorted.Count(); i++)
    13.         {
    14.             sorted.ElementAt(i).SetSiblingIndex(i);
    15.         }
    16.     }
    17. }
    18.  
    Code (CSharp):
    1. gameObject.SortChildren();
     
    astracat111 and kevinrodrigues like this.
  4. itch

    itch

    Joined:
    Apr 21, 2014
    Posts:
    5
    Ok that lets me change the order, but the layout group does not update immediately..
    edit: I meant to say, I see the updated order in the layout group only after calling setactive false and true again. There is probably a simple solution to this that I can't find either.
     
    Last edited: Sep 7, 2014
  5. ortin

    ortin

    Joined:
    Jan 13, 2013
    Posts:
    221
    You should submit a bug and use layout.enabled false/true or setActive false/true as a workaround meanwhile.

    Edit: Or setting parent again for element you changed order (element.trasform.parent = element.transform.parent) which is probably more efficient as a workaround. Which also means that unity for some reason doesn't check if parent really changed calling transform "change" callbacks.
     
    Last edited: Sep 7, 2014
  6. Humpparajat

    Humpparajat

    Joined:
    Oct 26, 2016
    Posts:
    1
    I had the problem; the new order of the silbings wasn't instantly reflected by the grid layout. Was able to solve this by using:
    Code (CSharp):
    1. LayoutRebuilder.MarkLayoutForRebuild(silbingGameObject.GetComponent<RectTransform>());