Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
12
Question by Ludovic · Sep 20, 2010 at 12:56 PM · gameobjectfindloadleveladditive

Finding the root GameObjects in the scene ?

Hi all, I'm wondering what could be the fastest way to find all the root game objects in the scene ? I currently use the FindSceneObjectsOfType( typeof(GameObject) ) and then taking the root gameobject but is there a faster way to do this ?

Thanks

PS I need this to reference the game objects added when I call the LoadLevelAdditive method.

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

8 Replies

· Add your reply
  • Sort: 
avatar image
27

Answer by DonKanallie · Jan 15, 2016 at 08:40 AM

With a recent Unity version (around 5.3) the preferred way would be

 UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects()
Comment
Add comment · Show 2 · 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 huulong · Sep 01, 2016 at 10:38 AM 0
Share

[CO$$anonymous$$$$anonymous$$ENT EDITED] O$$anonymous$$, I thought that would only worked for objects saved in the scene but it actually works for unsaved scenes and when playing. It also handles multi-scene which is now activated by default and causes the solution with HierarchyProperty to return null elements (as thienhaflash spotted. Thanks!

avatar image martinrhan1 · Dec 15, 2019 at 03:33 AM 0
Share

this function doesn't work properly, it returns only one of the root game objects.

avatar image
15

Answer by Adrian · Feb 25, 2014 at 06:34 PM

In the Unity editor (ONLY) ...

You can use following code to get all the root game objects directly (the same method is used internally by Unity in the hierarchy window):

 public static IEnumerable<GameObject> SceneRoots()
 {
     var prop = new HierarchyProperty(HierarchyType.GameObjects);
     var expanded = new int[0];
     while (prop.Next(expanded)) {
         yield return prop.pptrValue as GameObject;
     }
 }

You can use this method with foreach or query it further using Linq:

 foreach (var root in SceneRoots()) {
     Debug.Log(root);
 }
 
 SceneRoots().Select(g => g.transform).ToList();

And as a bonus, a method to iterate over all scene objects breath-first:

 public static IEnumerable<Transform> AllSceneObjects()
 {
     var queue = new Queue<Transform>();
 
     foreach (var root in SceneRoots()) {
         var tf = root.transform;
         yield return tf;
         queue.Enqueue(tf);
     }
 
     while (queue.Count > 0) {
         foreach (Transform child in queue.Dequeue()) {
             yield return child;
             queue.Enqueue(child);
         }
     }
 }
Comment
Add comment · Show 9 · 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 thienhaflash · Oct 14, 2014 at 12:04 AM 0
Share

Seems to be the most promising answer so far. I will check to see if it works. FindObjectOfTypeAll will works, too, but maybe it's bad for performance.

avatar image ninjanoel · Nov 30, 2014 at 11:08 AM 0
Share

fyi, this script is not suitable for mobile dev, i've tried a 'build to android' and it complains it cant find the unity editor package or something, asked a question about it.

avatar image yoyo · Mar 19, 2015 at 09:26 PM 0
Share

@ninjanoel, this code is only intended for editor use, as the author stated ("In the editor ...")

avatar image yoyo · Mar 19, 2015 at 09:42 PM 0
Share

Very nice, I would call this the correct answer for editor usage. (Not for runtime obviously.)

avatar image yoyo · Mar 23, 2015 at 02:53 PM 1
Share

Note that you can use this approach to find objects at edit time, then tag them (from code), and at runtime search by tag, which is fairly efficient.

Show more comments
avatar image
7

Answer by yoyo · Dec 30, 2010 at 11:55 PM

You can find a single root object like this (C#):

Transform xform = UnityEngine.Object.FindObjectOfType<Transform>();
GameObject rootObject = xform.root.gameObject;

Note that this calls FindObjectOfType rather than FindObjectsOfType, so it's faster [EDIT: Or so you would expect, however FindObjectOfType actually calls FindObjectsOfType behind the scenes, so it's actually just as slow]. However if your scene has more than one root object it will only find one of them.

So ... anyone know how to find all the root objects efficiently?

This works, but uses FindObjectsOfType, which the docs warn is slow, plus it needs to allocate an array big enough to hold all the transforms in the scene. I would like to know if there's a better way:

List<GameObject> rootObjects = new List<GameObject>();
foreach (Transform xform in UnityEngine.Object.FindObjectsOfType<Transform>())
{
    if (xform.parent == null)
    {
        rootObjects.Add(xform.gameObject);
    }
}
Comment
Add comment · 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
4

Answer by BinaryCore · Sep 20, 2010 at 08:51 PM

Another way is that you could also use Tags to tag your root game objects with a distinct tag type like "RootGameObject" and then use GameObject.FindGameObjectsWithTag("RootGameObject") to get all the root types.

A nicer way would be to be able to check a GameObject to see if it is a child of any other GameObject, like a GetParent() call. If that is null, then it's a root object. But, using the t.parent on the transform as he described above should do the trick too.

Comment
Add comment · Show 3 · 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 yoyo · Mar 20, 2015 at 04:43 PM 0
Share

It's a good idea, but requires diligence in correctly tagging your root objects.

avatar image yoyo · Mar 23, 2015 at 02:47 PM 0
Share

In the end I used the editor-only method from the other answer to quickly find the roots at edit time, and automatically tag them so they can be found efficiently at runtime.

avatar image ThaiCat · Mar 30, 2017 at 10:49 PM 0
Share

This is the fastest method to do that in my case (<5ms) vs UnityEngine.Scene$$anonymous$$anagement.Scene$$anonymous$$anager.GetActiveScene().GetRootGameObjects() (>6ms) vs FindObjectsOfType(); (>12ms) Anyway, i don't use tags for anything else.

avatar image
3

Answer by Mike 3 · Sep 20, 2010 at 01:19 PM

I'd do it via Transform instead of GameObject, but otherwise no, that'll be pretty much the fastest way

If you use Transform instead of GameObject, you can just check if t.parent is null, if so it's the root (plus you don't have to get go.transform for every object)

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 Ludovic · Sep 20, 2010 at 02:21 PM 0
Share

Thanks for the tip !

  • 1
  • 2
  • ›

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

14 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

Related Questions

I wanna use Gameobject.Find(string name, bool active) 3 Answers

How to find Inactive GameObject 16 Answers

GameObject.Find() work on inactive objects 16 Answers

GameObjet.find give "Missing" 1 Answer

How can I get every other GameObject except for the one I'm using? 1 Answer


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