Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

GameObject.Find () find inactive objects too

Discussion in 'Wish List' started by Omar Rojo, Jul 13, 2007.

  1. Omar Rojo

    Omar Rojo

    Joined:
    Jan 4, 2007
    Posts:
    494
    Like

    Code (csharp):
    1. GameObject.Find (string object_name, boolean active_only = true)
    So i don't have to have publics the cache variables i have to cache inactive objects.
     
  2. Randy-Edmonds

    Randy-Edmonds

    Joined:
    Oct 10, 2005
    Posts:
    1,122
    Amen, brother.
     
    ridexpl, AP54321, DYGames37 and 2 others like this.
  3. psychicparrot

    psychicparrot

    Joined:
    Dec 10, 2007
    Posts:
    884
    I find it staggering that it STILL isn't possible to find an inactive gameObject! This was posted 3 years ago!

    Hard coding objects through the IDE is a messy and ugly way of doing things.
     
    AP54321, juanitogan, enyllief and 6 others like this.
  4. ColossalDuck

    ColossalDuck

    Joined:
    Jun 6, 2009
    Posts:
    3,246
    This would be awesome.
     
    rakkarage likes this.
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,777
    GameObject.Find has gone way out of style. It's sloooooooow.

    Pass around object references instead. Your game will run faster and your code will be more reliable.

    I think you need to reread your definition of "hard coding". GameObject.Find = hardcoding. Connecting objects via the IDE = not.
     
    BMRG14 and rakkarage like this.
  6. ColossalDuck

    ColossalDuck

    Joined:
    Jun 6, 2009
    Posts:
    3,246
    But its so easy to use :D.
     
    CMDR_Garbage and rakkarage like this.
  7. JohnnyA

    JohnnyA

    Joined:
    Apr 9, 2010
    Posts:
    5,056
    A bit off topic but how do you pass references between scenes?

    I have a control object that controls player/stores player info that is used in each level (not destroyed on load) ... currently for the objects that need reference to it I FindWithTag() on Awake(), what is the alternative?
     
  8. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,777
    Store a reference to it in an object that does not get destroyed when the scene changes.

    If the object being referenced only exists in the new scene, then yeah, you'll have to fall back to something else. GameObject.Find is acceptable here (but store the reference at least! there's no need to call GO.F every frame), alternately you can use, say, a static variable.
    Code (csharp):
    1.  
    2. //on the persistent-between-levels player scores object, say PlayerScoresObject.js
    3. static var myPlayer : GameObject;
    4.  
    5.  
    6. //on the player
    7. PlayerScoresObject.myPlayer = gameObject;
    8.  
     
  9. psychicparrot

    psychicparrot

    Joined:
    Dec 10, 2007
    Posts:
    884
    Dragging and dropping in the IDE isn't hard coding? OK, if you're going to be picky about wording ... sure, it's not putting the name in code, but it is pointing to it in a similar way to hard coding it - if anything, it's WORSE than hard coding it because if you want to use the script elsewhere you have to go through the pain in the ass task of dragging and dropping your objects into it.

    Now, wouldn't it be simpler for everyone if we just had GameObject.Find for inactive objects? Yes. It would.
     
  10. Emon

    Emon

    Joined:
    Aug 27, 2010
    Posts:
    35
    I can't begin to describe how misguided this advice is.

    Yes, if you have to keep track of a handful of objects, references are fine. But if you want to do anything more complex than that, it's a nightmare. In my game, for example, I set objects active/inactive as part of the core gameplay mechanic. Disabling the renderer is NOT an option, they must be removed from the game loop entirely. I also want to save/load the state of the scene. So in addition to finding every object and worrying about persisting those, I also have to go through all of my cached references (possibly hundreds of objects) and persist those as well. I can't do it all in one place. It's a complete mess and it's NOT more reliable. I don't even know why you mentioned reliability...introducing complexity decreases reliability in most cases. Tracking references by yourself is increased complexity.

    It's a complete mess and there's no good reason for it. Unity is marketed as being easy to use and not getting in your way. Forcing people to work around these problems in their own scripts is exactly the opposite.
     
    AP54321, juan-jo, JackofTraes and 6 others like this.
  11. nawash

    nawash

    Joined:
    Jan 29, 2010
    Posts:
    166
    It would be cool to find inactive object by name.
    In my case I need this because :
    the artist sends me new version of object while a create the script. Each time I have to change the model, I must update the public exposed reference of my script.

    As for the fact that it is slow, why not filter by name AND by class (search would be done by class then by name in the Unity code) ?
     
  12. theinfomercial

    theinfomercial

    Joined:
    Sep 9, 2008
    Posts:
    1,000
    I'm bumping this. This should have been handled in Unity 1.0

    But I'm guessing there's a reason for this. Otherwise it probably would have happened.
     
    Fortyseven likes this.
  13. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I agree — I just ran into this myself, much to my great surprise, and it seems silly.

    If anything, Find could have an optional boolean parameter (or overload) that controls whether to search inactive objects too. Make it false by default, so existing code doesn't break. But then those of us who just need an easy way to look up an object by name, even when it's inactive, can do it.

    In case it matters, here's my use case: I have a debugging console, and it needs to be able to turn various stuff on and off. The user can type the name of the stuff he wants to activate or deactivate, at run time. GameObject.Find works great for turning stuff off, easy peasy, but then you can't turn things on again. To work around this, I'm going to have to keep my own dictionary of names of things I've turned off. Certainly doable, but it feels like pointless busywork.
     
    Last edited: Oct 27, 2011
    Psyco92 likes this.
  14. Julien-Lynge

    Julien-Lynge

    Joined:
    Nov 5, 2010
    Posts:
    142
    I agree as well.

    Folks mentioned 'just keep track of it in a script somewhere' but there are many cases where that is either clunky or just won't work. Sure, GameObject.Find is a bit slow and you wouldn't want to use it every frame, but the argument seems to be "it's slow... so we shouldn't make it available at all." We developers aren't stupid, and you don't need to protect us from ourselves. If it's made available, we will use it where it makes sense, and use other methods where they are easier, quicker, or otherwise the better option.
     
  15. Iamdain

    Iamdain

    Joined:
    Feb 3, 2010
    Posts:
    90
    BUMP!
     
  16. zugzwang

    zugzwang

    Joined:
    Jan 12, 2011
    Posts:
    24
  17. LastSipahi

    LastSipahi

    Joined:
    Sep 14, 2011
    Posts:
    21
    After 3 frustrating days, I agree. BTW finding with tags still not working while the object is inactive.
     
  18. Diviner

    Diviner

    Joined:
    May 8, 2010
    Posts:
    677
    You can always roll your own Find() function. Just have each object spawned register itself on a global List, and instead of Find( ), loop through that list to get the object you want.
     
  19. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Just ran into this. Basically our game is all art driven and set up by artists in the unity editor, so respawning things involves sending a message to all objects to call their reset function. After reading this, I've decided to just have a fat array of gameobjects I find when the game runs the first time, then I have references to all game objects to run the SendMessage through.
     
  20. chomp

    chomp

    Joined:
    Dec 6, 2010
    Posts:
    22
    This is just one of many obvious* and rectifiable holes in an otherwise excellent API. Please consider this minuscule feature.

    The "just don't do it that way" attitude seems to be systemic throughout the Unity community, and I think it leads to a number of potentially good features being glossed over carelessly with misguided platitudes and hand-waving.

    It doesn't always matter if it's inefficient. It doesn't matter if we shouldn't call it every frame. It doesn't matter if you would prefer to hard-wire object references in all or most cases. What matters is that this feature would be useful.

    * I say "obvious," because one can reasonably expect this feature to exist, given that:
    1. Object.Find* methods exist and can find Objects by name or type
    2. Objects still exist and can be manipulated when they or their host GameObject is inactive
    3. Transform.Find has no concern for an object's active or inactive state
     
  21. AnXgotta

    AnXgotta

    Joined:
    Nov 25, 2011
    Posts:
    8
    Hey guys,

    A temporary solution to this is to use a GameObject as a container for the object you want to find and set the active value for the child true or false. I know this is a pain but it does work.

    So find the GameObject that has the disabled one you want as a chile and use the transform.getChild() method to do the activating.

    Hopefully this helps.

    I know this thread is about adding the functionality of using Find to get inactive objects, but just thought I would add this.

    Hopefully this gets corrected!
     
  22. ChrisYummi

    ChrisYummi

    Joined:
    Jul 5, 2012
    Posts:
    8
    Agreed. I have script objects that are not active but now I cannot trigger a script element in another Scene as I can't find it with a Find. Please add this or can someone post their own get-around fn!

    Ta
     
  23. StefanoCecere

    StefanoCecere

    Joined:
    Jun 10, 2011
    Posts:
    211
    i would pay the upgrade to 4.x (and i already did) for JUST THIS FEATURE

    i have non-game projects with thousands of objects which now i'm dealing with complex arrays...
    a simple find inactive GO would save me hundreds of lines of code.. and hours of headache
     
    DanVioletSagmiller likes this.
  24. StefanoCecere

    StefanoCecere

    Joined:
    Jun 10, 2011
    Posts:
    211
  25. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    Why would it take hundreds of lines of code?

    Code (csharp):
    1.  
    2. //untested
    3. public class RegisterGO
    4. {
    5.     void Start()
    6.     {
    7.           MyRegistry.Register(this.gameobject);
    8.     }
    9.  
    10.    // void Update()
    11.    // {
    12.    //      if (Input.GetKeyDown(KeyCode.Return)) print(MyRegistry.Find("Cheese").name);
    13.    // }  
    14.  
    15.     void OnDestroy()
    16.     {
    17.           MyRegistry.Unregister(this.gameobject);
    18.     }
    19. }
    20.  
    21. public static class MyRegistry
    22. {
    23.    static List<GameObject> register = new List<GameObject>();
    24.    
    25.    public static void Register(GameObject go)
    26.    {
    27.          register.Add(go);
    28.    }
    29.    
    30.    public static void Register(GameObject go)
    31.    {
    32.          register.Remove(go);
    33.    }
    34.  
    35.    public static GameObject Find(string name)
    36.    {
    37.          return register.Find(x => x.name == name);
    38.     }
    39. }
     
    Last edited: Jul 15, 2012
    Alverik and coward like this.
  26. StefanoCecere

    StefanoCecere

    Joined:
    Jun 10, 2011
    Posts:
    211
    hi npsf3000 ... good idea! but i should attach this script to thousands of GO?
    anyway i'll keep it in mind and maybe test it if really UT won't upgrade the Find function
    thanks!!
     
  27. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    Yep, the first part anyway [RegisterGO].
     
  28. znoey

    znoey

    Joined:
    Oct 27, 2011
    Posts:
    174
    I just wrote this for something similar. The only problem here is that you have to have a game object to start your search from. However i suppose this may be better if you know your containing gameobject first, as it won't search the entire scene. This is basically what AnXgotta mentions.

    Code (csharp):
    1.  
    2.     public static GameObject Find(this GameObject go, string nameToFind, bool bSearchInChildren)
    3.     {
    4.         if (bSearchInChildren)
    5.         {
    6.             var transform = go.transform;
    7.             var childCount = transform.GetChildCount();
    8.             for (int i = 0; i < childCount; ++i)
    9.             {
    10.                 var child = transform.GetChild(i);
    11.                 if (child.gameObject.name == nameToFind)
    12.                     return child.gameObject;
    13.                 GameObject result = child.gameObject.Find(nameToFind, bSearchInChildren);
    14.                 if (result != null) return result;
    15.             }
    16.             return null;
    17.         }
    18.         else
    19.         {
    20.             return GameObject.Find(nameToFind);
    21.         }
    22.     }
     
  29. StefanoCecere

    StefanoCecere

    Joined:
    Jun 10, 2011
    Posts:
    211
    hi znoy!
    i guess yours is all pseudocode, right?
    there is no transform.GetChild() function...
     
  30. Julien-Lynge

    Julien-Lynge

    Joined:
    Nov 5, 2010
    Posts:
    142
    There is in fact a Transform.GetChild(), it's just not in the documentation. If you're using Visual Studio, just type in Transform (within a Monobehaviour class), select it, and hit F12 to pull up the metadata through reflection. You'll see GetChild() in the list of methods.

    For znoey, there are two other functions in there that look promising:
    public Transform Find(string name);
    public Transform FindChild(string name);

    Have you tried looking into those?
     
  31. Novack

    Novack

    Joined:
    Oct 28, 2009
    Posts:
    844
    Hey Julien, pretty nice work there!

    Although if its not in the documentation, Im not sure we should rely on that.

    It is definitvely a very nice option, but in the end, it would be fantastic to have this search in the API, as native option.
     
  32. biohazard2u

    biohazard2u

    Joined:
    Jun 14, 2012
    Posts:
    9
    I dont like this either.
    On the other hand, is this too slow?

    1. Store the obj on a static var as follows:
    public static GameObject anyNameForOurGameObject;
    2. Set it to false (inactive).
    anyNameForOurGameObject.SetActiveRecursively(false);
    3. Call the GameObject and set it back to true (active).
    ScriptName.anyNameForOurGameObject.SetActiveRecursively(true);
     
    Last edited: Aug 23, 2012
  33. Julien-Lynge

    Julien-Lynge

    Joined:
    Nov 5, 2010
    Posts:
    142
    Unity 4.0 beta is now out, so I can finally talk about this :)

    4.0 completely changes the way that active state is handled in GameObjects. Active state is now inherited, meaning that if my parent is inactive, I am inactive too. So no need to use SetActiveRecursively anymore.

    Unfortunately, due to deadlines I haven't yet had a chance to play with the new functionality, but my guess is that it changes how the various find methods work. If there are still issues, I'll try to bring it up with the Unity devs and suggest some changes.
     
  34. StefanoCecere

    StefanoCecere

    Joined:
    Jun 10, 2011
    Posts:
    211
    i checked the 4.0 docs.. and it seems that the Find functions still find active GO only :(

    i like the new "active" behaviours .. really hope for an improved Find!
     
  35. akasurreal

    akasurreal

    Joined:
    Jul 17, 2009
    Posts:
    442
    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.

    Code (csharp):
    1. public class Helpers : System.Object
    2. {
    3.     public static Object Find(string name, System.Type type)
    4.     {
    5.         Object [] objs = Resources.FindObjectsOfTypeAll(type);
    6.  
    7.         foreach (Object obj in objs)
    8.         {
    9.             if (obj.name == name)
    10.             {
    11.                 return obj;
    12.             }
    13.         }
    14.  
    15.         return null;
    16.     }
    17. }
    I use it like this:

    Code (csharp):
    1. UIPanel SelectSongsPanel = (UIPanel)Helpers.Find("Panel (Select Songs)", typeof(UIPanel));
    2. SelectSongsPanel.gameObject.SetActiveRecursively(true);
    3.  
     
    Adamantius, Edy and fuertes503 like this.
  36. Game-Whiz

    Game-Whiz

    Joined:
    Nov 10, 2011
    Posts:
    122
    Just ran into this... and BUMP! Please Unity guys, this is a very useful feature for some scenarios.
     
  37. Acelondoner

    Acelondoner

    Joined:
    Jul 27, 2012
    Posts:
    101
    Bumping.
     
  38. akasurreal

    akasurreal

    Joined:
    Jul 17, 2009
    Posts:
    442
    Just to be clear, FindObjectsOfTypeAll does find inactive, it just may also find prefabs and things you are not looking for, so you have to be careful.
     
    Edy likes this.
  39. souperdavecdn

    souperdavecdn

    Joined:
    Nov 13, 2012
    Posts:
    6
    I know I'm stating the obvious but...

    I agree there should be a more convenient way to Find any object, in the mean time, KISS:

    Code (csharp):
    1. // I want it inactive until it's needed so it's Active in the Hierarchy but deactivates on scene load.
    2. private var goFc : GameObject;
    3. function Awake(){
    4.     goFc = GameObject.Find("Camera-FlyCam");
    5.     goFc.SetActive(false);
    6. }
     
    RaoulWB likes this.
  40. Disastercake

    Disastercake

    Joined:
    Apr 7, 2012
    Posts:
    317
    A thread that is over FIVE YEARS old, and Unity still hasn't spent an hour to plug in an extra overloaded function into Find()? I'd say this has my vote, but I doubt they will ever actually support this.
     
    Zaelot, Fortyseven and awesomedata like this.
  41. jwinn

    jwinn

    Joined:
    Sep 1, 2012
    Posts:
    88
    +1 Bump. All we need is a simple true/false parameter to include disabled GameObjects or not, that can default to false.
     
  42. akutruff

    akutruff

    Joined:
    Jul 24, 2009
    Posts:
    44
    +1 bump. Seriously, infuriating for so many things.

    Almost 6 years old... Unity, come on...
     
    Last edited: Feb 20, 2013
  43. akutruff

    akutruff

    Joined:
    Jul 24, 2009
    Posts:
    44
    Well, my Unity bro's and sisters, here is something that works for editor scripts. It uses the Selection class as a round about filter for excluding Unity internal objects that are returned from FindObjectsOfTypeAll. I'll see how well this works as I try the script on our more complicated scenes. But in the meantime, enjoy.

    Note: Don't forget to add using System.Linq to your usings.

    Code (csharp):
    1.  
    2. public static Transform[] GetAllDisabledSceneObjects()
    3.     {
    4.         var allTransforms = GameObject.FindObjectsOfTypeAll(typeof(Transform));
    5.  
    6.         var previousSelection = Selection.objects;
    7.  
    8.         Selection.objects = allTransforms.Cast<Transform>()
    9.             .Where(x => x != null  x.parent == null)
    10.             .Select(x => x.gameObject)
    11.             .Where(x => x != null  !x.activeSelf)
    12.             .Cast<UnityEngine.Object>().ToArray();
    13.  
    14.        
    15.         var selectedTransforms = Selection.GetTransforms(SelectionMode.TopLevel | SelectionMode.Editable | SelectionMode.ExcludePrefab);
    16.  
    17.         Selection.objects = previousSelection;
    18.        
    19.         return selectedTransforms;
    20.     }
    21.  
     
  44. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,242
    Wow long thread. Incredible that this issue hasn't yet been solved, especially because finding inactive objects is super-useful for editor scripts. *BUMP*

    EDIT: not to mention that FindObjectsOfTypeAll has been deprecated in Unity 4, without proposing a valid alternative :/
     
  45. carmine

    carmine

    Joined:
    Jan 4, 2012
    Posts:
    394
    We still can't do this?
     
  46. Moraleidahgo

    Moraleidahgo

    Joined:
    Mar 3, 2012
    Posts:
    107
    C'mom Unity! C'MOM!