Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Using FindGameobject in "void Start" VS adding gameobjects manually in the inspector

Discussion in 'Scripting' started by Larpushka, Oct 22, 2015.

  1. Larpushka

    Larpushka

    Joined:
    Jan 6, 2015
    Posts:
    214
    Hi guys. I'm finding myself having to add a lot of dragging gameobjects to the inspector often with the same scripts. I was starting to wonder, is the best way to automatically add the gameobjects to a script is not to drag them from the gameobjects hierarchy to the inspector, but rather, use "void Start" in order to find the objects. I understand the "Find" command is very demanding, but since it's on the Start, and not on the Update, I imagine it should be acceptable?

    Moreover, when I copy paste a script that has inspector gameobjects that needs referencing, I don't need to drag them repeatedly, the script itself will reference everything.

    Am I correct in choosing this void Start method?
     
  2. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    I personaly avoid doing as much as possible in both awake and start if there is a way to only do it in editor time. Monobehaviors have the reset method called which you can use instead. If the reset behaviour isnt acceptable I like using a custom editor with a setup button that does what needs to be done.
     
  3. Duugu

    Duugu

    Joined:
    May 23, 2015
    Posts:
    241
    I am doing this stuff in Start() avoiding as much as possible in the Inspector. :)
    For me it provides more overview as I don't have to switch to the Unity window to see which gameobject is assigned to a given variable. Never had any performance problems with this.

    I guess this just depends on your personal preference and there's no "good" and "bad" way.
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    I respectfully disagree; while there's no single "good" way, GameObject.Find is always the bad way (at least for production code; for editor code, it's sometimes useful).

    GameObject.Find is slow, but that's only part of the reason to avoid using it. It's also unreliable - or, more accurately, it's really easy for an insignificant change to unexpectedly break its functionality. For example, if you instantiate something as a prefab, it'll break (because now its name has (Clone) on the end of it). If you later add another object that happens to have the same name, it'll break. A dozen more scenarios that shouldn't break it, but will.

    And it doesn't give you compile errors - it gives you runtime errors. That is, you won't know something is wrong until after you run and test it. Depending on how frequently the objects are referenced, you could easily find out only after the thing has been released that you broke a reference by changing its capitalization a week ago.

    Singletons, GetComponentsInChildren, dragging in references are all better choices. In a pinch, transform.Find is even preferable - at least that has fewer things to search through.

    If you can give a little more information about what you're doing, I might have some more specific advice on what a better way to go would be.
     
  5. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Using Find in Start is not a bad way to go. It is a string based method, and subject to all of string based methods pitfalls.

    I would typically include a null check and a sensible error message in start. Catching null references the moment they occur helps with debugging.
     
  6. Duugu

    Duugu

    Joined:
    May 23, 2015
    Posts:
    241
    That's true. I was assuming that one is using unique names and reliable name conventions/management of names.

    Coming to dynamically created GO I personally don't use GameObject.Find at all. I do store references to any dynamically created GO that is intended for later access.
    Maybe I am mixed up ... but, how could I use the inspector to set references to dynamically created GO?
     
  7. Glurth

    Glurth

    Joined:
    Dec 29, 2014
    Posts:
    109
    "Maybe I am mixed up ... but, how could I use the inspector to set references to dynamically created GO?"

    You can specify references to NON-dynamic objects in: a scene object, a pre-fab of some kind, or even a custom ScriptableObject saved as an asset. Upon instantiate, your dynamically created GO's can reference the data from whichever object you choose to use to store those references.

    I would use a static class to load up that reference-storing-objects at game start. My code can then just ask that static class for whatever reference it needs.

    Now, if you are talking bout referencing a dynamic GO, which I think you are, that you CANNOT do in the editor. But, you CAN record references to every GO you instantiate, and store THAT reference in the static class for future use. This way you an just ask the static class for the reference to the GO, and don't have to use Find.

    Hmm. I think I didn't read the post right first time-around- you know all this already.
     
  8. Larpushka

    Larpushka

    Joined:
    Jan 6, 2015
    Posts:
    214
    StarManta,
    I'm not instantiating any objects nor destroying. I'm using that instead of dragging gameobjects from the inspector. It's much easier since it's automated. And I'm only using it on "Start" not on "Update", so I don't understand how should instantiated or destroyed objects should affect it if it's on "Start".