Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Gizmoi · Nov 03, 2014 at 02:05 PM · uitransformsorting

Sort by Sibling Index

I need to sort a list of arbitrary transforms by their sibling index. But it has to be global. Essentially I want them in the order they appear in the hierarchy and are rendered under the new UI system. But the transforms themselves can be from anywhere in the hierarchy.

For example, I might have references to the highlighted children and I need to sort them by the order they will be rendered by the new UI system.

alt text

EDIT: clarified question

capture2.png (5.5 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
4
Best Answer

Answer by troien · Nov 03, 2014 at 03:51 PM

I think the following piece of code does what you want it to do (I didn't fully test it yet, but I believe this should always work).

Note, this solution might be slow if you do it often, especially if your list is very long.

The code of the comparer:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 using System;
 
 
 public class Example : IComparer<Transform>
 {
     public int Compare(Transform x, Transform y)
     {
         if (x == y)
             return 0;
         if (y.IsChildOf(x))
         {
             return -1;
         }
         if (x.IsChildOf(y))
         {
             return 1;
         }
 
         List<Transform> xparentList = GetParents(x);
         List<Transform> yparentList = GetParents(y);
 
         for (int xIndex = 0; xIndex < xparentList.Count; xIndex++)
         {
             if (y.IsChildOf(xparentList[xIndex]))
             {
                 int yIndex = yparentList.IndexOf(xparentList[xIndex]) - 1;
                 xIndex -= 1;
                 return xparentList[xIndex].GetSiblingIndex() - yparentList[yIndex].GetSiblingIndex();
             }
         }
 
         return xparentList[xparentList.Count - 1].GetSiblingIndex() - yparentList[yparentList.Count - 1].GetSiblingIndex();
     }
 
 
     private List<Transform> GetParents(Transform t)
     {
         List<Transform> parents = new List<Transform>();
         parents.Add(t);
 
         while (t.parent != null)
         {
             parents.Add(t.parent);
             t = t.parent;
         }
         return parents;
     }
 }

How you can use it:

 public class Example2 : MonoBehaviour
 {
     public Transform[] list;
 
     public void Start()
     {
         List<Transform> newList = new List<Transform>(list);
 
         newList.Sort(new Example());
         for (int i = 0; i < newList.Count; i++)
         {
             Debug.Log(newList[i].name);
         }
     }
 }

Obviously you should rename the Example class if you use this ;)

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Gizmoi · Nov 04, 2014 at 04:05 PM 0
Share

This is actually twice as fast the answer posted by hu90, and it seems to work much better! Thanks very much! You've restored my faith in Unity Answers :)

avatar image
1
Wiki

Answer by hu90 · Nov 03, 2014 at 02:40 PM

This function returns a list of all the children of the transform provided, in the order they would appear in the Hierarchy panel :

 List<Transform> ChildTransformsSorted(Transform t) {

     List<Transform> sorted = new List<Transform>();

     for (int i = 0; i < t.childCount; i++) {

         Transform child = t.GetChild(i);

         sorted.Add( child );
         sorted.AddRange( ChildTransformsSorted(child) );
     }

     return sorted;
 }

A few highlights :

  • The function works in a recursive way

  • The list does not include the transform passed as a parameter

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Gizmoi · Nov 03, 2014 at 02:59 PM 0
Share

The objects I have are placed arbitrarily in the hierarchy. I've edited the question to clarify.

avatar image hu90 · Nov 03, 2014 at 07:03 PM 0
Share

Thanks for the clarification.

The function GetGlobalIndex will return a float for any transform you pass to it. The further the transform is in the hierarchy list, the bigger that float is.

GetDepthInHierarchy is used by GetGlobalIndex, no need to call it directly.

 float GetGlobalIndex(Transform t) {
     if (t.parent == null)
         return t.GetSiblingIndex();
     else
         return ((float)(t.GetSiblingIndex()+1)/(t.parent.childCount+1)) / $$anonymous$$athf.Pow(10, GetDepthInHierarchy(t)-1) + GetGlobalIndex(t.parent);
 }
 
 int GetDepthInHierarchy(Transform t) {
     if (t.parent == null)
         return 0;
     else
         return 1 + GetDepthInHierarchy(t.parent);
 }

So to sort a collection of transforms, you could write :

 Transform[] mySortedTransformList = myTransformList.OrderBy(t => GetGlobalIndex(t)).ToArray();

I'll add this to the actual answer if it helps.

avatar image Gizmoi · Nov 04, 2014 at 03:31 PM 0
Share

That's exactly that I was looking for, but I wasn't sure how I could it mathematically! I'll test it out now!

avatar image Gizmoi · Nov 04, 2014 at 03:47 PM 0
Share

I tested it and I thought it worked beautifully, but after a child depth of 8, it starts to sort incorrectly :(

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

28 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

m_TransformInfo.localAABB.IsValid() 0 Answers

Converting UI RectTransform to Screen Pixel and vice-versa 5 Answers

Better way to make big 2D Game. UI Canvas, Transform calculation, animation 0 Answers

Get position of specific letter in UI Text 4 Answers

Highest sibling but though not visually not on top 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges