GameObject.Find() work on inactive objects

Does GameObject.Find() work on inactive objects? If not, how do you find and reference inactive objects.

The solution only works if you don’t rely on transform.root anywhere in your game. It also doesn’t work if you need to find objects that are children of objects that don’t get destroyed on load.

Add a GameObject that is the root of all GameObjects in your scene. Then instead of

FindObjectsOfType() 

use

GetComponentsInChildren( typeof(Transform), true );

That should return all transforms of all GameObjects in the scene as they are all a child of the scene root, active or not.

If you can’t or don’t want to create a scene root object then you’ll need to make an array of all the root objects in your scene and all GetCompoenentsInChildren() on all of them separately.

Here’s how you do it.

Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject;

Note this can also return prefabs not just object instances in the scene so be careful when using it at edit time.

This is kind of gross, but it works well:

	public static List<GameObject> GetAllObjectsInScene(bool bOnlyRoot)
	{
		GameObject[] pAllObjects = (GameObject[])Resources.FindObjectsOfTypeAll(typeof(GameObject));

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

		foreach (GameObject pObject in pAllObjects)
		{
			if (bOnlyRoot)
			{
				if (pObject.transform.parent != null)
				{
					continue;
				}
			}

			if (pObject.hideFlags == HideFlags.NotEditable || pObject.hideFlags == HideFlags.HideAndDontSave)
			{
				continue;
			}

			if (Application.isEditor)
			{
				string sAssetPath = AssetDatabase.GetAssetPath(pObject.transform.root.gameObject);
				if (!string.IsNullOrEmpty(sAssetPath))
				{
					continue;
				}
			}
			

			pReturn.Add(pObject);
		}

		return pReturn;
	}

Things that can find inactive gameObjects :

transform.Find() or transform.FindChild()

transform.GetComponentsInChildren(true)

Resources.FindObjectsOfTypeAll()

For more detail you can refer to UnityRealm.com is for sale | HugeDomains

There are at very least 4 options: GetChild, GetComponentsInChildren, FindObjectsOfType and FindGameObjectsWithTag. We could also use some variations that won’t bring an array, for instance. Listed below in no particular order.

  1. GetChild a method of Transform, it still works even today on Unity4, and it’s still not in the Docs for whatever reason. It will bring the child be it active or not. Probably the cheapest to use, since we have to use in each immediate parent we want to get the inactive GameObject. It will just be a pain to code and maintain.

  2. GetComponentsInChildren needs to have a root object. We could set up the scene with just 1 main root here. Very simple to use, but also very heavy. Apply this in the root object:

    foreach (Transform child in GetComponentsInChildren(true))`
    
  3. FindObjectsOfType doesn’t need a root object. Docs say it won’t return inactive objects, but it does. Since it’s the heaviest listed here and highly unadvised to use, we could do something like:

    foreach ( GameObject root in GameObject.FindObjectsOfType(typeof(GameObject)) ) {
    	if (root.transform.parent == null) { // game object with no parent
    		// here, iterate through each `root` child using your prefered method
    		// or simply remove the 'if' above
    	}
    }
    
  4. FindGameObjectsWithTag my favourite one, way faster and simpler than all others, but we can’t add more than 1 tag per object so it may be prohibitive if we already use tag for something else. It also needs no root, use it from anywhere:

    foreach ( GameObject obj in GameObject.FindGameObjectsWithTag("tag") )
    

Disclaimer: @bdawson actually gave the same solution about FindObjectsOfType and @Antony scratched it, twice. None were specific enough.

Tranquility’s link he posted in the comments contains an easy solution. Just keep an array of the disabled objects that you might want to find again.

In the given code the author was bringing back all the disabled objects at once, whereas you just need to search the array for the desired object and return it.

To put a nice wrapper around it, you could call this array something like SceneTrash, and when you want to deactivate an object call your own PutInTrash method to deactivate an object and store it in the trash can. Then your code can rummaged through the trashed objects whenever it needs to.

Make sure you save a reference to the object before you set it to inactive.

FYI I wrote this and it worked for my purposes, I know it may not work for all. Look up the Unity docs on Resources.FindObjectsOfTypeAll to see some potential pitfalls.

public class Helpers : System.Object
{
    public static Object Find(string name, System.Type type)
    {
        Object [] objs = Resources.FindObjectsOfTypeAll(type);

        foreach (Object obj in objs)
        {
            if (obj.name == name)
            {
                return obj;
            }
        }

        return null;
    }
}

I use it like this:

UIPanel SelectSongsPanel = (UIPanel)Helpers.Find("Panel (Select Songs)", typeof(UIPanel));
SelectSongsPanel.gameObject.SetActiveRecursively(true);

Here I need to find an child inactive object named “CheckPicture” of parent “objectParam”.

objectParam.GetComponentsInChildren<Transform>().FirstOrDefault(component => component.gameObject.name == "CheckPicture");

public static T FindObjectOfTypeIncludeInactivated() where T : Component{
List result = new List();

        foreach( GameObject rootObj in UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects() ) {

            Component[] comps = rootObj.GetComponentsInChildren(typeof(T), true);

            T[] childObject = Array.ConvertAll(comps, (x) => (T)x);

            result.AddRange(childObject);
        }

        return result.ToArray();
    }

In my case this was helpful. (It works on 5.4f +)

Does GameObject.Find() work on
inactive objects? If not, how do you
find and reference inactive objects.

GameObject.Find() is only useful (good) in small scenes. Best practice is to avoid using this for any scene with more than a handful of gameobjects (including children).

I find it is best practice to store a reference to every gameobject you create.

How do you keep track of your gameobjects? By name? UniqueGUID? By type?

You could use Dictionaries for this, sorting them by any way you desire.

By name or UniqueGUID & gameobject

Dictionary<string, GameObject> allObjects;
string myGUID = Guid.NewGuid().ToString();//By Unique GUID

By position & script type

public static Dictionary<Vector2, Tile> allTiles = new Dictionary<Vector2, Tile>(); //Collection of all Tile GameObjects via Tile.cs script

By name/uniqueID & script type

public static Dictionary<string, GameWorldObject> allGameWorldObjects = new Dictionary<string, GameWorldObject>(); //Collection of all GameWorldObjects
public static Dictionary<string, PlayerNetworkingScript> allPlayerObjects = new Dictionary<string, PlayerNetworkingScript>(); //Collection of all PlayerObjects

All objects in array

Gameobject[] AllObjects;

In a list by class

List<GameWorldObject> allGameWorldObjects ; //Holds all GameWorldObjects, PlayerCharacters, & Containers
public class GameWorldObject {}
public class PlayerCharacter : GameWorldObject { }
public class Container : GameWorldObject { }

In a list by gameobject

List<GameObject> allPlayerObjects;
List<GameObject> allGameWorldObjects ;

You Are looking for Resources.FindObjectsOfTypeAll(),
as Noob_vulcan said.

I wrote some test code and found many solutions, I will share 2 of my solutions the first being a broad implementation that is flexible enough for most projects.
I am using the System.Linq namespace in these examples.

Snippet 1:

     var allObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject));

        var inactiveObjects = allObjects.Select(p => p as GameObject)
                                .Where(h => h.activeInHierarchy == true);

        foreach (var inactive in inactiveObjects)
        {
            print(inactive.name); 
        }

This snippet will return a collection of all inactive Game Objects in the scene and if you try this code you will see that your console output will display a few objects under the hood you didn’t know were there.

Snippet 2:

        var allObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject));
        //if you want to find it by your name similar to GameObject.Find("myGameObjectName")
        var myObject = allObjects.Select(p => p as GameObject)
                                 .Where(n => n.name == "myGoName").SingleOrDefault(); //use your gameObjectsName name for your filter predicate
        print(myObject.name);
        myObject.SetActive(true);

This code will return a single gameObject that matches your predicate string you test against:: in this case “myGoName”. When I ran this code I had a tangible reference to my game object that I was able to set back to active which I’m sure means you can manipulate its components and values any way you like.

You might be thinking “this seems suspiciously inefficient”, but I want to just say quickly that linq uses something called deferred execution, and if used properly is tremendously efficient. I will not get into the details of the system.linq namespace because it’s beyond the scope of this question.

  • and can definitely be more efficient than your boilerplate foreach loops.

I hope this helps!

Probably a bit late (6 years late), but for any people viewing this now,
You can do:

UnityEngine.Resources.FindAllObjectsOfType<“object type here”>();

Just replace “object type here” with your object type (i.e. GameObject)

I was looking for a way to use “FindGameObjectWithTag(tag)” with an inactive GameObject and didn’t find any easy alternatives but i came up with this solution:

public GameObject Item;

public float armorAmount;

void Start()
{
    Item = GameObject.FindGameObjectWithTag("Shield1");
    if(Item != null)
    {
        Item.SetActive(false);
    }
}

void OnTriggerEnter2D(Collider2D other) {
if (other.tag == "Player") 
    {
        playerHealth theArmor = other.gameObject.GetComponent<playerHealth>();
        theArmor.addArmor(armorAmount);
        Item.SetActive(true);
        Destroy(gameObject);
    }
}
}

GameObject.Find() only returns active objects.
for unactive objects, use this:

Resources.FindObjectsOfTypeAll(typeof(YOURTYPEHERE));

so, lets say you want to find all of a certain tag, that aren’t active:

foreach (GameObject obj in Resources.FindObjectsOfTypeAll(typeof(GameObject))) {
     if (obj.tag == "Player" && !obj.activeSelf) { //any if statement here
          print(obj.name + " is inactive, and has a tag of 'Player'.");
     }
}

I have confirmed this works in 5.6+, and 2017.1+

GameObject.Find "This function only returns active gameobjects." You can reference inactive objects by using drag'n'drop in the inspector, or by finding active gameobjects and then deactivating them.