ドキュメント

Unity Engine

Unity Engine

イベント関数の実行順序

Understand the execution order of Unity's built-in event functions so you can respond to events and update the state of your game in the right order.
読み終わるまでの所要時間 28 分最終更新 1ヶ月前

イベント関数は、MonoBehaviour スクリプトが適切なメソッドを実装することで任意でサブスクライブできる一連のビルトインイベントです。コールバックと呼ばれることも多いです。これらのコールバックは、コア Unity サブシステムでのイベント (物理演算、レンダリング、ユーザー入力など) に対応するか、スクリプトのライフサイクルステージ (作成、アクティベーション、フレームに依存する更新、フレームに依存しない更新、破棄など) に対応します。イベントが発生すると、関連するコールバックがスクリプトで呼び出されますので、開発者はイベントに応じてロジックを実装できます。
Unity がこれらのイベントを発生させて、関連する MonoBehaviour コールバックを決められた順序で呼び出します。その順序をここで説明します。実行順序を理解することが重要です。そうすれば、まだ呼び出されていないコールバックを前提とする処理のために、別のコールバックを使用するということがなくなります。ただし、ユーザー入力によってトリガーされるイベント用のコールバックなど、コールバックによってはゲームの実行中にいつでも発生する可能性があることに注意してください。各イベントの意味と制限を完全に理解するには、このページに加えて、MonoBehaviour スクリプトのリファレンスを参照してください (イベントコールバックのリストが Messages セクションにあります)。

スクリプトのライフサイクルの概要

以下の図は、Unity がスクリプトの生存期間中にイベント関数を順序付け、繰り返す方法をまとめたものです。
さまざまなイベント関数の詳細は、以下のセクションを参照してください。

フローチャートの範囲

以下のフローチャートの範囲は、MonoBehaviour スクリプトのリファレンスの Messages セクションに記載されている適切なコールバックを実装することによって任意の MonoBehaviour スクリプトでサブスクライブできるビルトインイベント関数に制限されています。イベントを発生させるサブシステムの内部メソッドも、関連情報としていくつか記載されています。
これらのビルトインイベント関数に加えて、スクリプトでサブスクライブできる可能性のあるイベントがいくつかあります。Application、SceneManager、Camera など、いくつかの主要クラスには、独自のコールバックメソッドを登録できるデリゲートがあります。RuntimeInitializeOnLoadMethodAttribute などのメソッド属性は、シーンの特定のステージでメソッドを実行するためにも使用できます。関心のあるコンポーネントやサブシステムのスクリプトのリファレンスを参照して、サブスクライブできるイベントコールバックとその実行順序の詳細を確認してください。

スクリプトライフサイクルのフローチャート

ノート: 一部のブラウザーでは、SVG 画像ファイルがサポートされていません。画像が正しく表示されない場合 (例えば、テキストが表示されない場合) は、Google Chrome や Mozilla Firefox など、別のブラウザーを試してください。

一般原則

一般論としては、同一イベント関数の呼び出し順序はどのゲームオブジェクトでも同じであるとは限りません。ただし、呼び出し順序が明文化されている場合や設定可能な場合は、その限りではありません。プレイヤーループをより細かく制御する必要がある場合は、PlayerLoop API を使用できます。
MonoBehaviour サブクラスが同じでインスタンスが異なる場合に、インスタンスごとにイベント関数の呼び出し順序を指定することはできません。例えば、ある MonoBehaviour の
Update
関数が、別のゲームオブジェクト (その親/子ゲームオブジェクトを含む) における同じ MonoBehaviour の
Update
関数の前または後に呼び出される可能性があります。
ある MonoBehaviour サブクラスのイベント関数が、別のサブクラスのイベント関数よりも先に呼び出されるように指定するには、Project Settings ウィンドウの Script Execution Order パネルを使用します。例えば、EngineBehaviour と SteeringBehaviour の 2 つのスクリプトがある場合、SteeringBehaviours よりも EngineBehaviours の方が常に先に更新されるように Script Execution Order を設定することができます。複数のシーンを追加で ロードする場合は、設定されたスクリプト実行順序は、複数のシーンを部分的にまたぐのではなく、1 つのシーンごとに完結するため、EngineBehaviours と SteeringBehaviours は、次のシーンで更新される前に、両方とも 1 つのシーンで更新されます。

最初のシーンのロード

これらの関数は、シーンが始まると (シーン内の各オブジェクトに対して 1 度だけ) 呼び出されます。
  • Awake
    : オブジェクトの新しいインスタンスが作成されたときに呼び出される最初のライフサイクル関数。常に
    Start
    関数の前に呼び出されます。起動中にゲームオブジェクトが非アクティブである場合は、そのゲームオブジェクトがアクティブになるまで
    Awake
    は呼び出されません。
  • OnEnable
    : オブジェクトが有効になりアクティブになったときに呼び出されます。常に (同じオブジェクト上の)
    Awake
    の後、
    Start
    の前に呼び出されます。
シーンアセットに含まれる複数のオブジェクトの場合、_すべて_のスクリプトの
Awake
関数と
OnEnable
関数が呼び出されるのは、それらの_いずれか_に対して
Start
と後続の関数が呼び出される前です。ただし、ランタイムにオブジェクトをインスタンス化するときには、これを強制できません。
Awake
が
OnEnable
の前に呼び出されることが確実なのは、各オブジェクトの範囲内に限られます。呼び出し順序は複数のオブジェクトに共通するものではありません。あるオブジェクトの
Awake
が、別のオブジェクトの
OnEnable
の前に呼び出されるとは限りません。シーン内のすべてのオブジェクトに対して
Awake
が呼び出されたことを前提とする処理は、
Start
で実行される必要があります。

シーンのロードとアンロードの前

上の図に示されていない SceneManager.sceneLoaded イベントと SceneManager.sceneUnloaded イベントの場合は、それぞれ、シーンがロードおよびアンロードされたときにコールバックを受け取ることができます。詳細と使用例については、関連するスクリプトのリファレンスページを参照してください。
sceneLoaded
通知は、シーン内のすべてのオブジェクトの
OnEnable
の後、
Start
の前に受け取ることができます。実行フローの一部としてシーンロードを含む図については、ドメインリロードとシーンリロードの無効化の詳細 を参照してください。
RuntimeInitializeOnLoadMethodAttribute と、そのタイプ BeforeSceneLoad または AfterSceneLoad を使用して、それぞれ、シーンロードの前または後にメソッドを実行することもできます。これらのタイプでマークされたメソッドの実行順序については、RuntimeInitializeOnLoadMethodAttribute スクリプトリファレンスのメインページを参照してください。

Editor

  • Reset
    : スクリプトがオブジェクトに最初にアタッチされたときと、Reset コマンドが使用されたときに、スクリプトのプロパティを初期化するために呼び出されます。
  • OnValidate
    : スクリプトのプロパティが設定されるたびに呼び出されます。例えば、オブジェクトがデシリアライズされたときです。これは、エディターでシーンを開いたときや、ドメインがリロードされた後など、さまざまなタイミングで発生します。

最初のフレームを更新する前

  • Start
    : スクリプトのインスタンスが有効な場合にのみ、最初のフレーム更新の前に呼び出されます。
シーンアセットに含まれる複数のオブジェクトの場合、すべてのスクリプトで
Start
関数が呼び出されるのは、それらのいずれかに対して
Update
が呼び出される前です。ただし、ゲームプレイ中にオブジェクトをインスタンス化する場合は、これを強制できません。例えば、別のオブジェクトの
Update
機能からオブジェクトをインスタンス化する場合、元のオブジェクトで
Update
が初めて実行されるまで、インスタンス化されたオブジェクトの
Start
を呼び出すことはできません。

フレーム間

  • OnApplicationPause
    : 一時停止が検出されたフレームの終わり、実質的には通常のフレーム更新と次の更新の間に呼び出されます。一時停止状態を表すグラフィックスを表示できるように、
    OnApplicationPause
    の呼び出し後には追加のフレームが 1 つ作成されます。

アップデートの順番

ゲームロジック、インタラクション、アニメーション、カメラ位置などの追跡に使用できる、さまざまなイベントがあります。共通のパターンは
Update
関数内のほとんどのタスクを実行することですが、使用できるその他の関数もあります。
  • FixedUpdate
    は、フレームごとにではなく、ゲーム内の一定の間隔で発生します。これらの更新は一定で、フレームレートは可変であるため、フレームレートが高いときには 1 つのフレーム内で一定の更新が発生しないことがあり、フレームレートが低いときには 1 つのフレームで一定の更新が複数回発生することもあります。すべての物理演算計算と更新は
    FixedUpdate
    の直後に発生します。フレームレートに依存しないため、
    FixedUpdate
    で移動を計算するときに、値を Time.deltaTime で乗算する必要はありません。一定の更新が発生する間隔は、Time.fixedDeltaTime によって定義されます。これは、スクリプトで直接設定するか、エディターの Time 設定 の Fixed Timestep プロパティで設定できます。
    Update
    と
    FixedUpdate
    のどちらを実行するかを決定する時間計算など、詳しくは Time を参照してください。
  • Update
    は、1 フレームにつき 1 回呼び出されます。これはフレーム更新の主な関数です。
  • LateUpdate
    は
    Update
    の終了後に、1 フレームにつき 1 回呼び出されます。
    Update
    で実行された計算は、
    LateUpdate
    が開始する前に完了します。
    LateUpdate
    の一般的な用途は、三人称視点カメラによる追跡です。
    Update
    内でキャラクターを動かして回転させる場合、すべてのカメラの移動と回転を
    LateUpdate
    で計算できます。これにより、キャラクターが完全に移動してから、カメラがその位置を追跡できます。

アニメーションの更新ループ

上記の フローチャート に示されている以下のアニメーションループコールバックは、MonoBehaviour から派生したスクリプトで呼び出されます。
その他のアニメーション関連イベント関数は、StateMachineBehaviour から派生したスクリプトで呼び出されます。
これらのコールバックの意味と制限については、関連するスクリプトのリファレンスページを参照してください。
フローチャートにあるその他のアニメーション関数は、アニメーションシステム内部のものであり、関連情報として記載されています。これらの関数にはプロファイラーマーカーが関連付けられているため、Unity がこれらの関数をフレーム内で呼び出すタイミングを プロファイラー で確認できます。Unity がこれらの関数を呼び出すタイミングを知ることで、呼び出したイベント関数がいつ実行されるかを正確に理解できます。アニメーション関数とプロファイラーマーカーのすべての実行順序については、プロファイラーマーカー を参照してください。

レンダリング

この実行順序は、ビルトインレンダーパイプライン にのみ適用されます。スクリプタブルレンダーパイプライン に基づくレンダーパイプラインの実行順序の詳細は、ユニバーサルレンダーパイプライン または HD レンダーパイプライン のドキュメントで該当するセクションを参照してください。レンダリング直前の処理については、Application.onBeforeRender を参照してください。
  • OnPreCull
    : カメラがシーンをカリングする前に呼び出されます。カリングは、どのオブジェクトがカメラから見えるのかを決定します。
    OnPreCull
    はカリングの実行直前に呼び出されます。
  • OnBecameVisible
    /
    OnBecameInvisible
    : オブジェクトがカメラから見えるようになったとき、または見えなくなったときに呼び出されます。オブジェクトはいつでも見えなくなるため、上記のフローチャートに
    OnBecameInvisible
    は記載されていません。
  • OnWillRenderObject
    : オブジェクトが見える場合に、1 台のカメラにつき 1 回 呼び出されます。
  • OnPreRender
    : カメラがシーンのレンダリングを開始する前に呼び出されます。
  • OnRenderObject
    : すべての通常のシーンレンダリングが終了した後に呼び出されます。この時点で GL クラスまたは Graphics.DrawMeshNow を使用して、カスタムジオメトリを描画できます。
  • OnPostRender
    : カメラがシーンのレンダリングを終了した後に呼び出されます。
  • OnRenderImage
    : シーンのレンダリングが完了した後に呼び出され、画像のポストプロセスが可能になります。ポストプロセスエフェクト を参照してください。
  • OnGUI
    : GUI イベントに応じて、フレームごとに複数回呼び出されます。レイアウトイベントと再描画イベントが最初に処理されてから、各入力イベントのレイアウトイベントとキーボード/マウスイベントが処理されます。
  • OnDrawGizmos
    : 可視化のためにシーンビュー内でギズモの描画に使用されます。
ノート: OnPreCull、OnPreRender、OnPostRender、OnRenderImage は、Unity のビルトインイベント関数であり、それらのスクリプトが有効な Camera コンポーネントとして同じオブジェクトにアタッチされている場合にのみ、MonoBehaviour スクリプトで呼び出されます。別 のオブジェクトにアタッチされた MonoBehaviour で、
OnPreCull
、
OnPreRender
、
OnPostRender
に対する同等のコールバックを受け取るには、同等のデリゲート Camera.onPreCull、Camera.onPreRender、Camera.onPostRender (名前の
on
が小文字であることに注意) を使用する必要があります。それについては、スクリプトリファレンスの関連ページで、サンプルコードを用いて説明されています。

コルーチン

通常のコルーチン更新は、
Update
関数が戻った後に実行されます。コルーチンは、特定の YieldInstruction が終了するまで、その実行 (
yield
) をサスペンドできる関数です。
コルーチンのさまざまな用途:
  • yield
    : 次のフレームで
    Update
    関数がすべて呼び出された後に続行します。
  • yield WaitForSeconds
    : フレームに対して
    Update
    関数がすべて呼び出されてから、指定された時間が経過した後に続行します。
  • yield WaitForFixedUpdate
    : すべてのスクリプトですべての
    FixedUpdate
    が呼び出された後に続行します。コルーチンが
    FixedUpdate
    の前に停止した場合は、現在のフレームで
    FixedUpdate
    の後に再開します。
  • yield WWW
    : WWW ダウンロードの完了後に続行します。
  • yield StartCoroutine
    : コルーチンを連鎖させます。理論上のコルーチン
    coroutineA
    が別の
    coroutineB
    を
    yield StartCoroutine(coroutineB());
    で開始した場合に、
    coroutineA
    は一時停止して、
    coroutineB
    が終了するのを待ってから続行します。例については、MonoBehaviour.StartCoroutine を参照してください。

オブジェクトが破棄される場合

  • OnDestroy
    : オブジェクトが破棄される前の最後のフレームに対するすべてのフレーム更新後に、この関数が呼び出されます (オブジェクトは、Object.Destroy に応じて破棄されるか、シーン終了時に破棄されます)。

終了する場合

これらの関数は、シーン内のすべてのアクティブなオブジェクトで呼び出されます。
  • OnApplicationQuit
    : この関数は、アプリケーションが終了する前に、すべてのゲームオブジェクトで呼び出されます。エディターでは、ユーザーが再生モードを停止したときに呼び出されます。
  • OnDisable
    : この関数は Behaviour が無効または非アクティブになったときに呼び出されます。

追加リソース