Unityで Instance 直後のメソッドの呼び出しによるエラー

Unity
Andrew MartinによるPixabayからの画像

Unityで開発をする中につまづいてしまったポイントを紹介していきます.
今回は Instance 後のメソッドの呼び出しについて解説していきます.
今回のポイントは関数の呼び出し順序なので,Unity 公式の呼び出し順序表を貼っておきます.

イベント関数の実行順序 - Unity マニュアル
Unity スクリプトを実行すると、既定の順序で多くのイベント関数が実行されます。このページでは、これらのイベント関数について説明し、それらがどのように実行シーケンスに収まるかを説明します。

Unity では Prefab を元にオブジェクトを生成する時に Instance() という関数を呼び出します.この時,A というコンポーネントを持ったオブジェクトが作られたとすると,A のメソッドは次の順序で呼び出されます.

  1. Awake() : Instance 直後
  2. Start() : Instance 後に最初に呼ばれるフレームの直前
  3. Update() : 各フレーム

ここで,B というコンポーネントが B::Start() の中で A を持ったオブジェクトを Instance したと考えます.そして,B::Start()の中で A のメソッドである A::Hello() を呼び出したとします.

void B::Start(){
  var obj = Instance(pf) as GameObject;
  var a = obj.GetComponent<A>() as A;
  if(a != null){
    a.Hello();
  }
}

この場合 A::Hello() を呼び出した時に,A::Awake() は実行された後ですが,A::Start() は呼び出されていません.そのため,A::Hello()の中で A::Start() で設定するはずのパラメータを使用している場合,想定外の挙動をすることになります.

対処方法としては次のものが考えられます.

  • パラメータの設定を A::Awake() で行う
  • A::Hello() を 最初の B::Update() で行う

コメント