Access GameObjects and Components Elegantly

17 Nov 2010
Posted by xeophin

Yes, this is yet another C#-in-Unity3D post. I hope you will forgive me ;)

Up until now, I would usually reference other GameObjects or components like this:

public class Foo : MonoBehaviour {
 
    public Bar b;
 
    void Start () {
        b = GameObject.FindObjectByTag("Player").GetComponent<Bar>();
    }
}

This works fine until you suddenly want to access a GameObject without knowing if it is already there.

My first solution would have been to rewrite the whole thing as a property:

public class Foo : MonoBehaviour {
 
    public Bar b {
        get {
            return GameObject.FindObjectByTag("Player").GetComponent<Bar>();
        }
    }
}

Of course, since there is no caching mechanism on the compiler level, this "solution" comes at a huge performance cost. The real solution: adding our own caching mechanism.

public class Foo : MonoBehaviour {
 
    private Bar _b;
    public Bar b {
        get {
            if (_b == null) { 
                _b = GameObject.FindObjectByTag("Player").GetComponent<Bar>();
            }
            return _b;
        }
    }
}

Of course, this pattern allows for even more sophisticated mechanisms, like fetching new data once the underlying object has changed, but getting the cached version in all other cases.

Thanks to UnityAnswers, that got me that answer so fast.

[1]: http://answers.unity3d.com/questions/27493/performance-of-properties-vs-setting-fields-in-startYes, this is yet another C#-in-Unity3D post. I hope you will forgive me ;)Up until now, I would usually reference other `GameObjects` or components like this:public class Foo : MonoBehaviour { public Bar b; void Start () { b = GameObject.FindObjectByTag("Player").GetComponent(); }}This works fine until you suddenly want to access a `GameObject` without knowing if it is already there.My first solution would have been to rewrite the whole thing as a property:public class Foo : MonoBehaviour { public Bar b { get { return GameObject.FindObjectByTag("Player").GetComponent(); } }}Of course, since there is no caching mechanism on the compiler level, this "solution" comes at a huge performance cost. The real solution: adding our own caching mechanism.public class Foo : MonoBehaviour { private Bar _b; public Bar b { get { if (_b == null) { _b = GameObject.FindObjectByTag("Player").GetComponent(); } return _b; } }}Of course, this pattern allows for even more sophisticated mechanisms, like fetching new data once the underlying object has changed, but getting the cached version in all other cases.Thanks to [UnityAnswers][1], that got me that answer so fast.

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account associated with the e-mail address you provide, it will be used to display your avatar.
By submitting this form, you accept the Mollom privacy policy.


Navigation



Languages