EditorScript: How to get all GameObject's in scene?

I’m trying to get all gameobjects, enabled and disabled ones, that are listed in the hierarchy/scene inside the editor from an editor script. I found quite a few results on this issue in unity answers and the forum, but actually none of the answers is working as far as my tests go.

I found “Object.FindObjectsOfType” and “Object.FindSceneObjectsOfType” which pretty much do what I’m looking for, but both methods find active gameobjects only, but I also need to get inactive ones.

Another candidate is “Resources.FindObjectsOfTypeAll”. This one finds active and inactive gameobjects, but it also returns objects that have been selected in the project window and are actually not part of the current scene (the documentation says its result may contain internal objects). I thought I could detect and filter these non-scene objects from their hideFlags, I hoped these objects have the “HideFlags.HideInHierarchy” bit set or so, but it’s not the case.

Is there any way to get all (enabled and disabled) gameobjects of the current scene only, from an editor script?

Bump. This seems like something that should be trivially easy to find, but I am also having trouble iterating over inactive gameobjects in the hierarchy. Is there a simple way to get everything in the hierarchy including inactive gameobjects? I don’t want the selection to include anything internal or in the project folders. Thanks.

One trick I read was to have every gameobject a child of a single gameobject, and then you can use that gameobject to get all of its children, including inactive, with this…

GetComponentsInChildren<Transform>(true);

GetComponentInChildren will also include the parent object.

2 Likes

I was in a similar situation where i needed to find all components of a certain type from all active and inactive gameobjects from a scene.
The method below returns all root gameobjects be they active or inactive.

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

If you iterate through the list of root gameobjects with HiddenMonk’s solution you should be able to retrieve all active and inactive gameobjects.

5 Likes

I’m late to this particular party, but I had this question myself, so for others’ sake, here’s what I found:

The docs here: Unity - Scripting API: Resources.FindObjectsOfTypeAll have a pretty good method called GetAllObjectsInScene().

That said, I would personally change it to this:
private static List GetAllObjectsInScene()
{
List objectsInScene = new List();

foreach (GameObject go in Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[ ])
{
if (go.hideFlags != HideFlags.None)
continue;

if (PrefabUtility.GetPrefabType(go) == PrefabType.Prefab || PrefabUtility.GetPrefabType(go) == PrefabType.ModelPrefab)
continue;

objectsInScene.Add(go);
}
return objectsInScene;
}

Works in editor
Gets inactive objects
Doesn’t grab hidden objects
Doesn’t grab prefabs
Doesn’t grab transient objects

4 Likes

You don’t have to use FindObjectOfType in newer Unity versions to get all GameObject’s in a Scene anymore. Unity Technologies added the following method:
https://docs.unity3d.com/ScriptReference/SceneManagement.Scene.GetRootGameObjects.html

Once you have the scene root GameObjects, you can traverse their hierarchy and collect whatever objects you’re interested in. Works in Editor and Runtime.

2 Likes
public static IEnumerable<GameObject> GetAllRootGameObjects()
    {
        for (int i = 0; i < SceneManager.sceneCount; i++)
        {
            GameObject[] rootObjs = SceneManager.GetSceneAt(i).GetRootGameObjects();
            foreach (GameObject obj in rootObjs)
                yield return obj;
        }
    }

    public static IEnumerable<T> FindAllObjectsOfTypeExpensive<T>()
        where T : MonoBehaviour
    {
        foreach (GameObject obj in GetAllRootGameObjects())
        {
            foreach (T child in obj.GetComponentsInChildren<T>(true))
                yield return child;
        }
    }

The solutions above ignore multiple scenes loaded at the same time and will only find objects in the active scene, or will also pull in Resources like prefabs not in the scene.

My code will find all components of a type in every loaded scene, even on disabled and nested-disabled objects.

The only thing it won’t find is objects in the magic DontDestroyOnLoad scene, which is gross and confusing on Unity’s part.

Note: This can be a very expensive operation. Calling it regularly (like every Update frame) can break your game.

2 Likes

The solution is simple and sweet.
just use the following method.

    List<GameObject> GetAllObjectsOnlyInScene()
    {
        List<GameObject> objectsInScene = new List<GameObject>();

        foreach (GameObject go in Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[])
        {
            if (!EditorUtility.IsPersistent(go.transform.root.gameObject) && !(go.hideFlags == HideFlags.NotEditable || go.hideFlags == HideFlags.HideAndDontSave))
                objectsInScene.Add(go);
        }

        return objectsInScene;
    }

if you need a simple GameObject Array instead of List then convert it by ToArray() methods.
ex.

 GameObject[] allObjectTemp = GetAllObjectsOnlyInScene().ToArray();

Just a simpler and easier to read way to do this:

foreach (GameObject go in Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[])
...

is this

foreach (var go in Resources.FindObjectsOfTypeAll<GameObject>())
...

Be careful using Resources.FindObjectsOfTypeAll to find scene objects, because it might return prefabs from the project too. We found out the hard-way, with an issue where our code sometimes picked a prefab in the project instead of an object in the scene.

A more reliable method to find GameObject’s in the hierarchy is Object.FindObjectsOfType:
https://docs.unity3d.com/ScriptReference/Object.FindObjectsOfType.html

In Unity 2020.3 they added the ability to find inactive GameObject’s with Object.FindObjectsOfType, which didn’t work before, thus all the workarounds you find in this thread.

Yes . I’m aware of that. I was just reducing the previous code with a simpler way.
I use this function to gather hidden objects that were marked non editable or hidden in the hierarchy and not-unloadable via de hideFlags and impossible to delete from any scene loaded. This is the only way to get those objects, sadly.