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.

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

UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects()

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);
		}
	}
}

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);
    }
}

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:

UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects().Where(r => (r.hideFlags & HideFlags.HideInHierarchy) == 0);

Transform.root