Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

FindObjectsOfType order by hierarchy?

Discussion in 'Scripting' started by ldb, Apr 3, 2015.

  1. ldb

    ldb

    Joined:
    Apr 30, 2013
    Posts:
    40
    I'm making a waypoint system. You place GO's on the scene and camera will traverse from one to the next. If I put all waypoint go's in a container object, and loop through it's children, I can get a list of waypoints in order they were added in the hierarchy, which works great.

    I would also like to have the option to not need a container object. So in this instance I find all waypoint objects with FindObjectsOfType. But this list is not in hierarchy order.

    Is there any way to sort FindObjectsOfType by hierarchy? Or an alternative method?

    Thanks
     
  2. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    order is not enforceable.
    You can collect first, then manually sort (eg by name)
    But I'd stick with keeping them parented, otherwise your looking at a great way to get a very messy scene hierarchy very quickly
     
  3. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    I'm not convinced this is true anymore. With 4.6 you can re-order things in the hierarchy and the order controls render depth for UI elements.

    That being said - relying on order for waypoint pathfinding seems like asking for a lot of trouble.
     
  4. ldb

    ldb

    Joined:
    Apr 30, 2013
    Posts:
    40
    It's for a package I will be adding to the asset store. I'd like to avoid ordering by name as I can't guarantee how users will rename objects. I will prompt users to create a container object, but just wanted to cover all bases really.

    I guess I could just throw a warning if no container detected.

    Thanks
     
  5. ldb

    ldb

    Joined:
    Apr 30, 2013
    Posts:
    40
    It's a camera waypoint system, just sends the camera from one object to the next, with a few other options (different LookAt for each, pause/speed/callbacks etc).

    The only alternative I can think of is to set the next waypoint to move to manually, which doesn't feel as intuitive
     
  6. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    I'd set them up as an array in whatever script is handling the movement and use the order of that instead.
     
  7. ldb

    ldb

    Joined:
    Apr 30, 2013
    Posts:
    40
    I do set them up in an array in my handler script... To populate the array I grab the objects from the hierarchy. So, the user adds waypoint prefabs to the scene in editor, and decides what order to go through them by changing their hierarchy order. Then when the game is running it loops through the array.

    How would you go about populating the array? I think I'm misunderstanding you.
     
  8. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Dragging and dropping them into the slots in the Inspector.
     
  9. ldb

    ldb

    Joined:
    Apr 30, 2013
    Posts:
    40
    Ahh I see. Kind of feels like an unnecessary extra step though. What would be the advantage, seeing as the waypoints are added to the scene already anyway?
     
  10. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    FindObjectsOfType doesn't guarantee any order for the results. You have to define it yourself somehow. You could perhaps use Transform.GetSiblingIndex() for sorting.

    --Eric
     
    PraetorBlue, invadererik and ldb like this.
  11. ldb

    ldb

    Joined:
    Apr 30, 2013
    Posts:
    40
    GetSiblingIndex was exactly what I was looking for. Thanks!

    For future reference, just use this in a custom Sort function...

    myList.Sort(delegate(GameObject go1, GameObject go2) {
    return go1.transform.GetSiblingIndex().CompareTo(go2.transform.GetSiblingIndex());
    });
     
  12. ardiawanbagusharisa

    ardiawanbagusharisa

    Joined:
    Oct 26, 2015
    Posts:
    9
    I'm here in 2017, still useful though. I don't know that FindObjectsOfType() doesn't guarantee the ordered result.
     
  13. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
  14. nikix22

    nikix22

    Joined:
    Jan 16, 2015
    Posts:
    25
    This worked for me, for saving all objects into file, always in same order :D
    Code (CSharp):
    1. Transform[] all_transforms = Object.FindObjectsOfType<Transform>().OrderBy(m => m.transform.GetSiblingIndex()).ToArray();
    2.  
    3. // Loop through the transforms in the scene, exporting what is necessary
    4. foreach (Transform t in all_transforms)
    5. {
    6.     //do save etc.
    7. }
     
  15. MaceB

    MaceB

    Joined:
    Jun 26, 2016
    Posts:
    9
    For others who see this and get an error, you have to add this to the top of your code
    Code (CSharp):
    1. using System.Linq;
     
  16. uurha

    uurha

    Joined:
    Nov 15, 2020
    Posts:
    21
    This method will work only for root objects, all other nested objects order will be messed up

    Root1 - SiblingIndex = 0
    -- SubRoot1 - SiblingIndex = 0
    -- SubRoot2 - SiblingIndex = 1
    -- SubRoot3 - SiblingIndex = 2
    Root2 - SiblingIndex = 1

    so it this case order will be:
    SubRoot1 - Root1 - SubRoot2 - Root2 - SubRoot3 
    upload_2022-11-11_18-58-6.png