yotiky Tech Blog

とあるエンジニアの備忘録

Scriptのイベント関数の実行順と実行可否

Unity 基礎シリーズ 目次

編集履歴

目次

検証環境

Unity:2017.4.5f1

主な関数の順番

  1. Awake : one time
  2. OnEnable : each time object is enabled
  3. Start : one time
  4. Update : iteration
  5. OnDisable : each time object is disabled
  6. OnDestroy : one time

GameObjectとComponentがactive/non-activeの時に呼ばれる関数

Awake/OnDestroyは、GameObjectに紐づき、他はComponentに紐づくっぽい。
AwakeはGameObjectが有効になった時に最初に1度だけ呼ばれる。Componentに紐づくその他の関数は、GameObjectの初期化であるAwakeをトリガーに呼ばれるようになる。
activeかどうかは自身のGameObject(activeSelf)に加え、親の影響(activeInHierarchy )も受ける。

    bool isActiveFirst;
    void Awake()
    {
        Debug.Log("Awake");
    }
    void OnEnable()
    {
        isActiveFirst = true;
        Debug.Log("OnEnable");
    }
    void Start()
    {
        Debug.Log("Start");
    }
    void Update()
    {
        if (isActiveFirst)
        {
            isActiveFirst = false;
            Debug.Log("Update");
        }
    }
    void OnDisable()
    {
        Debug.Log("OnDisable");
    }
    void OnDestroy()
    {
        Debug.Log("OnDestroy");
    }

Initial state

  • GameObject : non-active / Component : non-active
    • not called
  • GameObject : non-active / Component : active
    • not called
  • GameObject : active / Component : non-active
    1. Awake
  • GameObject : active / Component : active
    1. Awake
    2. OnEnable
    3. Start
    4. Update

Activate

  1. GameObject : non-active / Component : non-active
    • not called
  2. GameObject : active / Component : non-active
    1. Awake
  3. GameObject : active / Component : active
    1. OnEnable
    2. Start
    3. Update

Disable/Enable

  1. GameObject : active / Component : active
    1. Awake
    2. OnEnable
    3. Start
    4. Update
  2. GameObject : active / Component : non-active | GameObject : non-active / Component : active
    1. OnDisable
  3. GameObject : active / Component : active
    1. OnEnable
    2. Update

Destroy

  1. GameObject : active / Component : active
    1. Awake
    2. OnEnable
    3. Start
    4. Update
  2. GameObject : destroy
    1. OnDisable
    2. OnDestroy

StartのCoroutine(コルーチン)を使った場合に呼ばれる順番

Coroutineの再開はUpdateが呼ばれた後に実行される。

    IEnumerator Start()
    {
        Debug.Log("Start1");
        yield return null;
        Debug.Log("Start2");
    }

    int counter = 0;
    void Update()
    {
        if (counter < 3)
        {
            counter++;
            Debug.Log("Update" + counter);
        }
    }
  1. Start1
  2. Update1
  3. Update2
  4. Start2
  5. Update3

StartのCoroutine(コルーチン)完了後にUpdateを開始する

CoroutineはGameObjectが有効な時に実行され、Coroutineが開始された後GameObjectが無効になるとCoroutineも無効になる。CoroutineはUpdateと異なり、1度開始されるとComponentの有効/無効とは関係なく動作する。

    IEnumerator Start()
    {
        var i = 1;
        Debug.Log("Start" + i);
        enabled = false;
        foreach (var x in Enumerable.Range(0, 3))
        {
            i++;
            Debug.Log("Start" + i);
            yield return null;
        }

        enabled = true;
        i++;
        Debug.Log("Start" + i);
    }

    int counter = 0;
    void Update()
    {
        if (counter < 3)
        {
            counter++;
            Debug.Log("Update" + counter);
        }
    }
  1. Start1
  2. Start2
  3. Start3
  4. Start4
  5. Start5
  6. Update1
  7. Update2
  8. Update3

イベント関数以外の関数

独自に実装したメソッドの呼び出しは、GameObject/Component の有効/無効とは関係なく実行できる。これはAwakeが呼ばれていないGameObjectやComponentでもメソッドの呼び出しは可能であることも意味する。

f:id:yotiky:20181120132303p:plain

    public Script4Sub script;
    bool done;
    void Update()
    {
        if (!done)
        {
            done = true;
            Debug.Log("Update");
            script.WriteLog();

            Debug.Log("- GameObject : non-active / Component : active");
            script.gameObject.SetActive(false);
            script.WriteLog();

            Debug.Log("- GameObject : non-active / Component : non-active");
            script.enabled = false;
            script.WriteLog();
        }
    }
    public void WriteLog()
    {
        Debug.Log("GameObject is active ? :" + gameObject.activeSelf);
        Debug.Log("Component is active ? :" + enabled);
    }
  • GameObject : active / Component : active
    • GameObject is active ? : True
    • Component is active ? : True
  • GameObject : non-active / Component : active
    • GameObject is active ? : False
    • Component is active ? : True
  • GameObject : non-active / Component : non-active
    • GameObject is active ? : False
    • Component is active ? : False

参考