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.
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:
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);
}
}
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.
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)
GameObject p = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects();
This doesnt work, some active objects are not included in the list. One object that im interested in never shows up, even if I duplicate another object of the same time, the duplicated object does not appear in the array returned by that line of code, even though its active in the scene. I think unity has a bug there.
UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects()
Will find all gameobjects in scene (both editor mode and play mode!), so I recommend to do a filter like this: