[Unity] InstantiateしたGameObjectにつけたスクリプトのGetComponentで取得した変数がNullになる時の原因と改善方法

Unity

InstantiateしたGameObjectにつけたスクリプトのGetComponentで取得した変数がNullになる時の原因と改善方法について紹介します。

広告

先程、以下のようなコードでエラーが発生しました。これは、InstantiateしたGameObjectについているスクリプトです。

public class Arrow : MonoBehaviour
{
    private Rigidbody2D rb2d;

    void Start()
    {
        rb2d = GetComponent<Rigidbody2D>();
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        rb2d.velocity = Vector2.zero; //ここでNullReferenceExceptionのエラーが発生
    }
}

この例でエラーが発生する原因は、OnTriggerEnter2DがStartより先に実行されるためでした。GetComponentをAwake関数に記述することで改善できます。

public class Arrow : MonoBehaviour
{
    private Rigidbody2D rb2d;

    void Awake()
    {
        rb2d = GetComponent<Rigidbody2D>();
        Debug.Log("Awake");
    }

    void Start()
    {
        Debug.Log("Start");
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        Debug.Log("OnTriggerEnter2D");
        rb2d.velocity = Vector2.zero;
    }
}

/*実行結果
Awake
OnTriggerEnter2D
Start
*/

なお、InstantiateせずにGameObjectをHierarchyに置いている場合は、StartはOnTriggerEnter2Dより先に実行されます。

/*実行結果
Awake
Start
OnTriggerEnter2D
*/

Instantiateで生成した場合とそうでない場合とで、StartとOnTriggerEnter2Dの実行される順番が逆になるのはなぜなのでしょうか…。AwakeとStartの違いについてはっきり理解できていないので、勉強しておきたいと思います。

広告