7
\$\begingroup\$

I've been reading some example code and working on my own stuff in Unity. I've been seeing a lot of GetComponent<>(), and often this will be done for the transform as Transform _transform = GetComponent<Transform>().

However, I have already had access to the attached game objects transform, as transform, this.transform or gameObject.transform. I can understand using GetComponent() in most cases, but why would you specifically use the function for GameObject and Transform when the two items are accessible from the script to start with?

\$\endgroup\$
  • 1
    \$\begingroup\$ There is not difference in the end result. \$\endgroup\$ – Savlon May 27 '15 at 3:47
10
\$\begingroup\$

The Speed (fast to slow):

cached _transform >> Component.transform >> Component.GetComponent<Transform>

And If you disassemble a UnityEngine.dll C# binary, you can see transform do not call GetComponent (Component class member), just call internal mono runtime method. Here is the transform code.

// UnityEngine.Component
public Transform transform
{
    get
    {
        return this.InternalGetTransform();
    }
}

[WrapperlessIcall]
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern Transform InternalGetTransform();

And Here is disassembled Component class's GetComponent Method.

public extern Component GetComponent(Type type);
public T GetComponent<T>() where T : Component
{
    return this.GetComponent(typeof(T)) as T;
}
[WrapperlessIcall]
[MethodImpl(MethodImplOptions.InternalCall)]
public extern Component[] GetComponents(Type type);

GetComponent is a kind of Finding function using generics. So it's a little bit slower than caching.


Original Source :

public class Test : MonoBehaviour
{
    Transform _transform;
    void Start()
    {
        _transform = this.transform;
        _transform = gameObject.GetComponent<Transform>();
    }
}

Binary Disassembled:

public class Test : MonoBehaviour
{
    private Transform _transform;
    private void Start()
    {
        // == UnityEngine.Component::get_transform()
        this._transform = base.get_transform(); 

        // == UnityEngine.Component::GetComponent<UnityEngine.Transform>()
        this._transform = base.get_gameObject().GetComponent<Transform>();
    }
}
\$\endgroup\$
8
\$\begingroup\$

As Jinbom said the main difference here is speed.

However it is important to note that this is only the case for the transform property of GameObject. Other properties such as camera and rigidbody are just convenience properties and call GetComponent<> under the hood so the performance is identical. It is for this reason that Unity has deprected these 'helper' properties in Unity as it is not immediately obvious that Unity is going to search for the component rather than returning a cached version.

With the exception of the transform property mentioned in the question, all other components should be cached at the first available opportunity using GetComponent<> and that cached value should be used thereafter.

\$\endgroup\$
0
\$\begingroup\$

Right now you can assume that every game object will have the Transform component due to the this.transform syntax. My guess is that Unity updated its API with the GetComponent<>() syntax was so that in the future you could have GameObjects without "special" components like Transform.

Then you can have a "purer" architecture where your GameObjects don't have to come with Transforms (although the editor might still add them by default as a convention).

\$\endgroup\$
  • \$\begingroup\$ Transform is the only component that acts this way. Regardless, I don't think reliance on future speculation makes for a good answer. Unity have not shown any suggestion towards moving this way, and I am personally doubtful they will (given that having a physical object in your game requires that object to contain information pertinent to its physical state, such as position and size). \$\endgroup\$ – Gnemlock Nov 5 '16 at 23:55
  • \$\begingroup\$ Also, this appears to comment on my question, but does not answer it. \$\endgroup\$ – Gnemlock Nov 5 '16 at 23:56
-1
\$\begingroup\$

The only reason this.transform works at all is because MonoBehavior implements a convenience property for the Transform component on the GameObject the behavior is attached to. ...It's rather misleading. I think gameObject.transform is more semantically correct, but that's splitting hairs. They do the same thing.

\$\endgroup\$
  • \$\begingroup\$ This provides nothing towards answering my actual question. The only reason anything works is because it was set up to, what is your point? I am asking about the difference between this.transform and GetComponent<Transform>(), not this.transform and gameObject.transform. \$\endgroup\$ – Gnemlock Nov 5 '16 at 23:57
  • \$\begingroup\$ Again, they do the same thing. \$\endgroup\$ – greenland Dec 4 '16 at 3:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.