動機
Updateが呼ばれる順番がたまたま噛み合っていてバグらずにすんでいた状況をみつけた。対応としては片方の処理をLateUpdateに移動させて終わったがそもそもUnityのUpdateが呼ばれる順番は規則性があるのか気になったので調べた。
調べたUnityのバージョンは2018.3.8f1
結果
次のことがわかった。
- Scene上に直接配置する場合は後で配置されたコンポーネントのUpdateが先に呼ばれる
- 動的に生成した場合は生成された順にUpdateが呼ばれる
試したこと
次のUpdateの処理を持つコンポーネントをいくつか作った。
void Update()
{
Debug.Log(this.GetType());
}
作ったコンポーネントをScene上に配置したり、動的に生成したりしてログがでる順序を調べた。
Scene上に直接置く
まず2つのコンポーネントを作った
- Component1
- Component2
この2つをScene上で配置して次のことを試した。
- Component1を配置してComponent2を配置した場合
- Component1とComponent2のHierarchyの順序を入れ替えた場合
- Component1の下にComponent2を配置した場合
- Component2の下にComponent1を配置した場合
- Component2を先に配置して1で試したことを行う場合
- 同じGameObjectにInspector上からAddComponentを行う場合
- Component1を先にAddComponentした場合
- Component2を先にAddComponentした場合
- AddComponentした後にInspector上でMoveUpやMoveDownを行った場合を調べる
Scene上に直接置いた場合の結果
いろいろ試したが、後でScene上に置かれたものが先にUpdateを呼ばれるという挙動になっていたことを確認した。
動的に生成した場合
コード上から動的にコンポーネントを追加した次の場合を調べた
- prefabをInstantiateした場合
- AddComponentを行った場合
- 同じGameObjectにコード上からAddComponentをした場合
- 違うGameObjectにそれぞれAddComponentをした場合
動的に生成した場合の結果
Instantiate、AddComponentを先に行った順序で呼ばれた。
若干罠になりそうな挙動?
Scene上で1つのGameObjectにComponent1, Component2をつけた場合とコード上からAddComponentでつけた場合
Hierarhcy上では同じ見えるがUpdateの呼ばれる順番に違いが出ることに気づいた。
まとめ
調査の結果自体は最初に述べたことが全てになるが、そもそもUpdateの順番でバグるようなコードは書かないようにしたい。UnityのUpdateで挙動が変わるかもしれないし。
(Script Execution Orderもあるが、わかりづらいため保守・管理を考えると極力使用は避けたい)