Search Unity

Healthy Alternative to GameObject.Find

Discussion in 'Scripting' started by Nigey, Sep 3, 2015.

  1. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    Hi Guys,

    I'm planning to make a collaborative project, which will need to be extensible after release. With that I want to make a slightly more strict formula for how to contact other GameObjects in a scene. Now there's loads of ways to do this, but I want to pick one that is the most professionally practiced, and healthy for longevity in a team.

    Here's the ways I can think of:

    1. GameObject.Find() - The issue being it's dependancy of the name of the object. Another person changes it's name breaks the link. Plus it's processor cost.

    2. GameObject.FindByTag() - Can get messy when needed for many single instance, or multiple unique instances.

    3. Interfaces - Handy, but still must use a GameObject.FindAllOfSomething to find them, and run through a call on whichever one you want, or all.

    4. Public Variable - Codewise pretty dangerous, as can be changed by accident by another coder.

    5. [SerialiseField] Private Variable - Closer, but means each instance must be drag and dropped in the editor. If there's a scene that crashes and loses it's meta for it's references, you'd need to do it all again.

    6. GameObject.SendMessage - Stops the need for .GetComponent(), which is nice, but still needs to find the GameObject first. Without direct association (collision, Physics.Raycast), there's no healthy way.

    7. Singleton with static reference - Only useful as a singleton pattern. Don't want to over use it for anything else. For that instance it's handy.

    8. Event (Delegate) - Sounds more promising, but need to find out more.

    9. Instantiate in AsyncOperation before scene load and keep reference - Handy, but will only give script it was instantiated by it's reference. Without the New GameObject with Constructor parameters, will be difficult to create other references to it without using another above method (is that right?).
    They are the ways I can think of. What's the proper or most popular method, if there is one?

    (P.S I might have a few of them slightly wrong)

    Thanks!
     
    anrizald and ETGgames like this.
  2. shaderop

    shaderop

    Joined:
    Nov 24, 2010
    Posts:
    942
    I think what you're eluding to here is maximizing decoupling between game objects, which should in theory make it a lot easier to, e.g., move implementation of certain behaviors to different objects/classes without breaking objects/classes that depend on said behavior.

    The methods you've listed don't really help in that regard. I don't know what counts as "the most professionally practiced, and healthy for longevity in a team", but what has always worked for me are two approaches: message hubs and Inversion of Control (IoC). You should be able to find plenty of information on IoC, but message hubs are a bit trickier (and the term "message hub" is far from de facto).

    The gist of it is that you want a system that allows you to define messages as classes, and have other to listen to those message without knowing or caring for who is raising them, and to raise messages without knowing or caring who raised them.

    There's a decent .NET library called TinyMessenger that implements this concept quite well and is compatible with Unity. It might be worth taking a look at it for examples and inspiration.
     
    Nigey likes this.
  3. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
    Yeah I think that's exactly what I'm after! Thanks shaderop :)
     
  4. Nigey

    Nigey

    Joined:
    Sep 29, 2013
    Posts:
    1,129
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I don't think there's any magic bullet for all situations. But, I think you'll find my video on UnityEvent to be quite applicable.

    HTH,
    - Joe
     
    Nigey likes this.