LoginSignup
49
41

More than 5 years have passed since last update.

gameObject.GetComponent<Transform>() と transform の違い(または Unity における省略記法について)

Last updated at Posted at 2016-10-26

疑問

transform を取得するために以下のような様々な書き方ができるが、これらの違いは何なのだろうか?

  1. this.gameObject.GetComponent<Transform>()
  2. gameObject.GetComponent<Transform>()
  3. GetComponent<Transform>()
  4. transform

結論

  • 得られるオブジェクトはどれも同じ(当然)
  • スピードが違う
    • 4 >> 3 > 2 = 1

routing.png

前提:Unity におけるクラスの継承関係

  • Object > Component > Behaviour > MonoBehaviour
  • MonoBehaviour クラスは Component クラスを継承している

(1) GetComponent<>() のありか

  • GetComponent<>() は GameObject クラスで 定義されている
  • Component クラスは、自身の属する GameObject への参照をメンバーとして 持っている
  • つまり、それを継承した MonoBehaviour を継承したクラスでは、以下のように Transform を取得可能
1つ目の記法
this.gameObject.GetComponent<Transform>()

(2) this は省略可能

  • C# の仕様で、自身に属するメンバーを参照する場合 this は省略できる
2つ目の記法
gameObject.GetComponent<Transform>()

(3) もうひとつの GetComponent<>()

  • 実は GetComponent<>() は Component クラスにも 定義されている(単純に便利さのため)
  • つまり、それを継承した MonoBehaviour を継承したクラスでは、以下のように Transform を取得可能
    • gameObject を経由しなくて済む分、こちらの方が高速なもよう
3つ目の記法
GetComponent<Transform>()

(4) transform は特別

4つ目の記法
transform

補足:ほかのコンポーネントは「専用の内部関数」で取得できないの?

  • できない
  • Component クラスは tranform 以外にも様々なコンポーネントへのショートカットを持っている
    • camera
    • rigidbody
    • ...
  • しかしこれらは 内部で GetComponent<>() を呼び出している にすぎない
    • それどころか transform 以外のショートカットは最近のバージョンで非推奨になった
  • Transform は特によく使うコンポーネントなので、特別に高速なアクセス手段が用意されたのではないか?

検証

  • 以下のスクリプトを適当なオブジェクトにアタッチしてシーンを実行すれば、速度が検証できる
検証用スクリプト
    using UnityEngine;
    using System.Diagnostics;

    public class NewBehaviourScript : MonoBehaviour {

        // Use this for initialization
        void Start () {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            for (int i = 0; i < 10000000; ++i)
            {
                Transform t = this.gameObject.GetComponent<Transform>(); // => 約 0.73 秒
                // Transform t = gameObject.GetComponent<Transform>();   // => 約 0.73 秒
                // Transform t = GetComponent<Transform>();              // => 約 0.53 秒
                // Transform t = transform;                              // => 約 0.24 秒
            }

            sw.Stop();
            UnityEngine.Debug.Log(sw.Elapsed);
        }
    }

補足: 最速はキャッシュ

  • 一度取得した Transform をローカル変数に入れて使い回せるなら、それがもちろん最速

参考

49
41
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
49
41