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の違いについてはっきり理解できていないので、勉強しておきたいと思います。