Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
39
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@megane42

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

疑問

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 をローカル変数に入れて使い回せるなら、それがもちろん最速

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
39
Help us understand the problem. What are the problem?