- Home /
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.
If inactive means the gameobjects that aren't moved then possibly you can check if the gameobject's present transform is equal to it's transform when the scene started . If yes then Find the gameobject with it's tag else ignore.
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.
Answer by Windud · Jan 29, 2018 at 11:39 AM
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];
}
That's got to be a real wrong name choice here. I would never expect to look into that class. Resources tells me it deals with resources folder, so how come this find them in the scene??!! Is that another intern job at Unity? Anyway, it does the job indeed.
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.
Can't agree more. Be very careful with this method!
I got confused when tweaking a scene object preview tool for designers. My approach is storing all objects that need to preview in a single parent object so that I can use GetComponentsInChildren to get them.
don't use this method. it has permanent effect on your assets. find another solution.
Answer by fafase · Feb 01, 2015 at 09:40 AM
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:
https://docs.unity3d.com/ScriptReference/Resources.FindObjectsOfTypeAll.html
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, ins$$anonymous$$d 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.
"[...] setting it or create your own method since you have them all under the same parent object you can use GetComponentsInChildren". Sometimes, OP asks for something that could have been done easier in a different manner. So it is common to give an answer that does not answer the question but more likely provide a different (sometimes more suitable) solution to the problem. In this case, 3 years ago (time goes by so fast), I was saying that there is this or there is an answer.
Answer by DrtyDee · Sep 19, 2015 at 03:32 AM
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.
Answer by Projectile_Entertainment · Feb 15, 2018 at 05:32 AM
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: https://docs.unity3d.com/ScriptReference/Resources.FindObjectsOfTypeAll.html 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
Answer by MariuszKowalczyk · Jun 17, 2019 at 09:13 PM
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;
}