How to find an inactive game object?

I’m working on a parallel worlds 2D platformer. At the start of the game, I set one world to inactive (all of the world’s objects are parented to an empty gameobject). Is there a way to grab the inactive game object and set it to active, for when the player wants to switch worlds? GameObject.Find() does not find a game object that is inactive, so I’m looking for a way to handle this.

I think he meant inactive as SetActive(false).

Right, that's what I meant, inactive as in SetActive(false).

I know its late but i had to post my solution for you as well since i have been struggeling with this to. so my solution was to simply have the objects setactive(true) on awake, get the reference and then SetActive(false) right afterwards.

14 Answers

14

Either a reference to the object before setting it off or create your own method since you have them all under the same parent object you can use GetComponentsInChildre

public static GameObject FindObject(this GameObject parent, string name)
{
    Transform[] trs= parent.GetComponentsInChildren<Transform>(true);
    foreach(Transform t in trs){
        if(t.name == name){
             return t.gameObject;
        }
    }
    return null;
}

this is an extension method that should be stored in a static class. You use it like this:

GameObject obj = parentObject.FindObject("MyObject");

Edit:

It appears Unity had the bright idea to add a clean solution under the Resources class:

Thanks! I ended up just grabbing them on Awake in a levelmanager object and just referencing them before they are destroyed.

Cannot implicitly convert type UnityEngine.Component[]' to UnityEngine.Transform[]'. An explicit conversion exists (are you missing a cast?)

Thanks @fafase this was just the answer I needed. I only needed this a single time so, instead of creating an extension method, I just used a little System.Linq. Transform childTransform = gameObject.transform.GetComponentsInChildren<Transform>(true).FirstOrDefault(t => t.name == "Name Of Child Object");

Perfect; just what I was looking for. I like RareRooster's LINQ fix as well; good stuff.

"Either a reference to the object before setting it" Well that's not finding it then, which is what the OP asked.

Resources.FindObjectsOfTypeAll works on inactive GameObjects as well.

You may be able to use Resources.FindObjectsOfTypeAll() to find all game objects.

Oh my god, I can't believe they didn't support this simple, essential and frequent feature even in 2018...?!?!?! for additional information, see here, it's a tutorial about Resources.FindObjectsOfTypeAll: https://answers.unity.com/questions/158172/findsceneobjectsoftype-ignoring-the-inactive-gameo.html I usually use it like this way for find a unique class: var fooGroup = Resources.FindObjectsOfTypeAll<AnUniqueClass>(); if (fooGroup.Length > 0) { var foo = fooGroup[0]; }

Careful with this approach! If you use it and have prefabs in your scene that get referenced, it will call the method you reference on the prefab itself as well as the object in the scene. That could change it in ways that won't be changed back when you stop running the game.

don't use this method. it has permanent effect on your assets. find another solution.

If the object has a root, you can get a hold of the root and transform.Find the Transform associated with the inactive object by name.

inactiveObject = rootObject.transform.Find( "nameOfInactiveObject" ).gameObject;

I was inadvertently doing this and had to come here just to confirm that this was "supposed" to work. This is a great option in 2020.

its better i m using this method

I’m late to this party, and others, 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<GameObject> objectsInScene = new List<GameObject>();
  
    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

I usually assign inactive GameObject to a public GameObject variableName field in a script, that way I can call it whenever I want without thinking of its status.

Yeah I was thinking that to start with. This other crap just seems a bit too complicated for me.

Here is the proper solution:

public static List<GameObject> FindAllObjectsInScene()
{
    UnityEngine.SceneManagement.Scene activeScene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();

    GameObject[] rootObjects = activeScene.GetRootGameObjects();

    GameObject[] allObjects = Resources.FindObjectsOfTypeAll<GameObject>();

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

    for (int i = 0; i < rootObjects.Length; i++)
    {
        objectsInScene.Add(rootObjects[i]);
    }

    for (int i = 0; i < allObjects.Length; i++)
    {
        if (allObjects[i].transform.root)
        {
            for (int i2 = 0; i2 < rootObjects.Length; i2++)
            {
                if (allObjects[i].transform.root == rootObjects[i2].transform && allObjects[i] != rootObjects[i2])
                {
                    objectsInScene.Add(allObjects[i]);
                    break;
                }
            }
        }
    }

    return objectsInScene;
}

Fixed the code-formatting issue in the topic.

In case someone comes across this page via an internet search for this common problem: the above answers ignore one specific case in which it is possible to use Find() to get an inactive object if (and only if) you give Find() the full path to a specific gameobject so it doesn’t need to do an actual search (e.g. “MyStuff/TheseGuys/ThisSpecificGuy” rather than just “ThisSpecificGuy”) I’ve found this through trial and error. Note that this only works if the object doesn’t have any child objects, since then it tries to search the child objects. But if the inactive object is at the bottom of a path with no child objects underneath, then it’ll return that object even if it’s inactive.

Is the path relative to the heirachy? or some path under the hood somewhere?

A: create for your object an empty parent in the hierarchy.

B: store it like this.

gameObject g = GameObject.Find("name of new parent").transform.GetChild(0).gameObject;

Yep, that's the way I did it too. No fuss. No ?Muss? And you can just go down the "child tree" with more GetChild()'s

There have includeInactive parameter on the FindObjectsOfType,
Just use (GameObject[])FindObjectsOfType(typeof(GameObject), true).

Don’t use Resources.FindObjectsOfTypeAll, which will include all the internal objects and cause the unexpected error!

Build safe version of @Projectile_Entertainment 's work that also requires using System.Linq

private static GameObject FindEvenIfInactive(string name)
{
    return Resources.FindObjectsOfTypeAll(typeof(GameObject))
        .Where(go => go.hideFlags == HideFlags.None && go.name == name
#if UNITY_EDITOR
        && UnityEditor.PrefabUtility.GetPrefabType(go) != UnityEditor.PrefabType.Prefab
        && UnityEditor.PrefabUtility.GetPrefabType(go) != UnityEditor.PrefabType.ModelPrefab
#endif
        ).FirstOrDefault() as GameObject;
}

This does not work since 2017: && UnityEditor.PrefabUtility.GetPrefabType(go) != UnityEditor.PrefabType.Prefab && UnityEditor.PrefabUtility.GetPrefabType(go) != UnityEditor.PrefabType.ModelPrefab

Just wanted to add to the existing answers, tranform.Find(string name) does find inactive children. By default it only searches one layer deep, but you can give it a “path” to look further down the hierarchy.

For example, hotbarSlot.transform.Find("CooldownOverlay/Number").gameObject; will return the GameObject named “Number” that’s a child of the GameObject named “CooldownOverlay” that’s a child of the referenced GameObject hotbarSlot

Extra credit (and thank you @Windud ):

 // Find any game object in scene regardless of active status
 //Usage: FindGameObjectsAll("myGameObject")

    public static GameObject FindGameObjectsAll(string name) => Resources.FindObjectsOfTypeAll<GameObject>().First(x => x.name == name);

This response is awesome!! I did a little modification to it tough: public static GameObject FindGameObjectsAll(string name) { return Resources.FindObjectsOfTypeAll<GameObject>().First(x => x.name == name); } And just to remind it, it uses the LINQ dependency: using System.Linq;

The proper way to do this (in 2022 at least) is using the GameObject.FindObjectOfType<Type>(includeInactive: bool) method overload with the boolean argument. Using types is better than using hardcoded GameObject names since type names probably change less often and type names can be easily refactored via IDE.

Well I do have an roundabout for when you need to access Inactive Objects
First parent it to some empty GameObject.

Then you can access it like this.

/*This works regardless of the object being active or inactive 
but make sure the parent is always active*/
addObjectsButton = GameObject.Find("ParentName").transform.Find("ObjectName").gameObject;

Hope this helps