2014年6月1日日曜日

【Unity】MonoBehaviourのライフサイクルと呼ばれる順番

UnityでComponentが消えるときに処理をしたくてイベントがどういう順番で処理されてるのか調べた。ついでに複数のオブジェクトがある場合の処理順も軽く調べた。

公式に書かれてるMonoBehaviourのライフサイクルはこんな感じ。
http://docs.unity3d.com/Manual/ExecutionOrder.html
きっとポジションさん(@kitposition)教えてくださってありがとうございます。

この沢山あるイベントの中で知りたかったのは下記5つ。
  • Awake
  • OnEnable
  • Start
  • OnDisable
  • OnDestroy
これらの発生順をみてみた。

環境

・Unity 4.3.4f

調べ方

こんなスクリプトを用意
using UnityEngine;

public class LifeCycle : MonoBehaviour
{
 void Awake(){ Debug.Log(this.gameObject.name+"Awake"); }
 void OnEnable(){ Debug.Log(this.gameObject.name+"OnEnable"); }
 void Start(){ Debug.Log(this.gameObject.name+"Start"); }
 void OnDisable(){ Debug.Log(this.gameObject.name+"OnDisable"); }
 void OnDestroy(){ Debug.Log(this.gameObject.name+"OnDestroy"); }
}

Cubeとかに貼っ付けて実行するだけ。

んじゃ見てみる

1.シンプルに

・Cubeを置いて名前をCube1にする。
・Cube1にさっきのスクリプト付与
・実行し、停止
仕様通り。なるほど。

2.Componentのチェックを外してみる

・1の状態のCube1からLifeCycleコンポーネントのチェックを外す。
・実行し、停止
へぇ、AwakeとDestroyは呼ばれるのかい…

3.AddComponentしてみる

・2の状態を基準にMainCameraに下記スクリプトを付与
using UnityEngine;
using System.Collections;

public class AddComponentButton : MonoBehaviour
{
  public GameObject go;
  void OnGUI ()
  {
    if (GUI.Button (new Rect (100, 100, 100, 20), "Add")) {
      go.AddComponent<LifeCycle> ();
    }
  }
}
・実行し、OnGUIのボタンを押す
・停止
複数のComponent(MonoBehaviour)はそれぞれ個別のライフサイクルを持つ。
当たり前か…

4.GameObjectのチェックを外してみる

・1の状態を基準にCube1のチェックを外す
・実行し、停止
ログ残らず。そらそうだ。

5.2つのコンポーネント

・Cube作って名前をCube1とする
・Cube1に2つのLifeCycleコンポーネントを付ける
・実行し、停止
複数コンポーネントある場合でもAwakeとOnEnableは連続してるんやね。
逆にOnDisableとOnDestroyは個別に走るっぽい。

6.2つのコンポーネント②

・Cube2つ作って名前をCube1、Cube2にする
・それぞれにLifeCycleコンポーネントを付ける
・実行し、停止
あれ、OnDisableとOnDestroyが連続した。
Cube1->Cube2の順番になってるのは偶然か?

7.2つのコンポーネント③

・6の実行前の状態から
・Cube1をCube3にリネーム
・Cube2をCube1にリネーム
・Cube2をCube2にリネーム
・実行し、停止
お、ひっくり返った。
親子関係のない親のいないGameObjectはシーンに追加した順に扱われるのかな?

8.2つのコンポーネント④

・7のシーンを保存してUnity終了
・Unity起動(自動的にシーン回復)
・実行し、終了
再読み込みとかで名前順に並び変わったりするかと思ったけどなんも変わんなかった。
YAMLとかに書かれる順で変化しないのかな。

9.親子にしてみる

・8の状態を基準に、Cube2をCube1の子供にする
・実行し、停止
親→子の順で初期化されるかと思ったけどそうでもないのね。
OnDestroyだけ子→親だな…なんだろ。

10.親子にしてみる②

・9の状態から親子関係を外す
・7の方法と同じくCube1と2の名前を入れ替える
・再度Cube2をCube1の子にする
・実行し、停止
Awake〜Startは9の結果を入れ替わったね。親子関係は関係ないみたい。
でもOnDisable〜OnDestroyは同じ結果だ。子から先に破棄されるのかな。

まとめ

良くわかってないけど箇条書き
・初期化(Awake~OnEnable~Start)はシーンに追加した順
・親子関係は初期化順に影響しない
・破棄(OnDisable~OnDestroy)はシーンに追加した順だが、親子関係がある場合は子→親の順
・InspectorでComponentのチェックを外した場合、OnEnableからOnDisableが呼ばれなくなる。(OnAwake、OnDestroyは呼ばれる)

これ以上詳細はめんどいから調べない。
さがせば公式に書いてあるんだろうなぁ。


他の記事もどうぞ
Unity系記事まとめ

スポンサーリンク

Related Posts Plugin for WordPress, Blogger...