3
\$\begingroup\$

I once read (I actually don't remember where, I'm looking for it) that using this.GameObject to call the script owner is a very bad practice.

I believe it has to do with some sort of information hiding, but I couldn't figure out why. What are the disadvantages with this? Is there a best-practice to achieve the result?

\$\endgroup\$
3
  • \$\begingroup\$ This question appears to be opinion based since any developer can have his own idea about what's a bad practice and what isn't. Not to mention what you're asking is also unclear. What alternative to this.gameObject do you know of? \$\endgroup\$
    – user15805
    May 7 2014 at 10:06
  • 1
    \$\begingroup\$ @AlexM. I disagree. There really are some stuff that can be bad practise in terms of memory management and execution speed. For example using LINQ in real-time rendering code, and so on. \$\endgroup\$
    – Lasse
    May 7 2014 at 11:01
  • \$\begingroup\$ I once saw someone write this.transform.gameobject.collider.gameobject (or rather the equivalent to that; the exact chaining was unintentionally obfuscated through several intermediate variables). Now that was stupid code; the stupid part was not using this.gameobject in the first place. \$\endgroup\$
    – jhocking
    May 7 2014 at 12:48
4
\$\begingroup\$

It is not a bad practice.

From a point of view of a component, this.gameObject will always lead to a valid gameObject:

A component is always attached to a game object. - reference

That is, component cannot live without one. With GetComponent<Type>() there could be no component at all, so you should always check it or you could get crash caused by NullPointerReference.

The only bad practises about gameObject/transform/components getters are connected with using them heavily, multiple times on every update. Then you could consider some caching mechanism, for better performance results. See this question.

EDIT: It seems like caching gameObject shouldn't make any improvements, but there is a speed gain by caching components (and yes, transform is a component). However, this stuff was also slower in previous Unity releases.

There is some useful time measured data comparison: link.

\$\endgroup\$
2
\$\begingroup\$

Bad practice, no. However, as with any reference, you have to be careful with it. Even though using it in general isn't bad practice, people can still find a way to use it in a bad practice way. Typically, this.gameObject is going to be a valid reference for as long as the script accessing it exists. Since the script is attached to the GameObject, it is also removed when the GameObject is.

Things to look out for:

  • Expecting the same composition of every gameobject. For example, using this.gameObject.GetComponent to access a component, without testing if the component exists on the gameobject this script is currently attached to. The component based design of Unity means the script you're writing can be attached to any game object.
  • Ensuring that the gameObject isn't missing, this can happen when destroying the game object, and still trying to access it, producing a MissingReferenceException exception. Typically this happens in other scripts keeping references to the gameObject of a different script.
\$\endgroup\$
2
  • \$\begingroup\$ For the first bullet point, can't [RequireComponent (typeof (Rigidbody))] be relied on? \$\endgroup\$
    – Lasse
    May 6 2014 at 19:08
  • 1
    \$\begingroup\$ @Lasse For the most part. However, if the attribute is added after the component has been added to an object, it won't enforce the requirement. That is, the RequireComponent attribute is only enforced when adding a script to a game object. \$\endgroup\$
    – House
    May 6 2014 at 20:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .