ドキュメント

Unity Engine

Unity Engine

Domain Reload

Understand how disabling domain reload on enter Play mode affects your application state and how you can compensate for these effects in your code.
読み終わるまでの所要時間 10 分最終更新 1ヶ月前

Domain Reload を選択すると、スクリプト状態がリセットされ、デフォルトで有効になります。完全に新しいスクリプト状態が指定され、再生モードに切り替えるたびにすべての静的フィールドと登録されたハンドラーがリセットされます。つまり、Unity エディターで再生モードに切り替えるたびに、ビルドで最初に起動したときと非常に類似した方法でプロジェクトが再生を開始します。
Domain Reload の処理には時間がかかり、この時間はプロジェクト内のスクリプトの数と複雑さに応じて増加します。再生モードに切り替えるのに長い時間がかかると、プロジェクトで素早く反復処理を行うことが難しくなります。このため、Unity には Domain Reload を無効にするためのオプションが用意されています。

Reload Domain を無効にする

詳細については、再生モードの設定方法を参照してください。
Reload Domain を無効にすると、Unity は毎回スクリプトの状態をリセットしないため、再生モードへの移行がより速くなります。ただし、再生モードにしたときにスクリプトの状態をリセットするかどうかは、ユーザーが決定します。これを行うには、再生モードの開始時にスクリプトの状態をリセットするコードを追加する必要があります。
Reload Domain を無効にするには以下を行います。
  1. Edit > Project Settings の順に選択して Project Settings ウィンドウを開きます。
  2. Editor タブをクリックします。
  3. Enter Play Mode Settings セクションの When entering play mode ドロップダウンメニューで、以下のいずれかを行います。
    • Domain Reload を無効にしつつ、シーンのリロードを有効にするには、Reload Scene only を選択します。
    • ドメインのリロードとシーンのリロードの両方を無効にするには、Do not reload Domain or Scene を選択します。
ノート: Enter Play モードでの Domain Reload が無効になっていても、Unity はアセットデータベースの自動または手動更新を実行するときにスクリプトの状態を更新します。これらの更新のタイミングと実行方法の詳細については、アセットデータベースの更新を参照してください。

Reload Domain が無効の場合にスクリプトが正しく実行されるように変更

再生モードでスクリプティングの状態が正しく再生モードをリセットするには、スクリプトの静的フィールドと静的イベントハンドラーを調整する必要があります。

静的フィールド

ドメインのリロードが無効になっている場合、コードの静的フィールドの値は自動的に元の値にリセットされません。これを明示的に行うコードを追加する必要があります。
以下のコード例には、ユーザーが Jump ボタンを押すと増加する静的カウンターフィールドがあります。Reload Domain が有効になっている場合は、Play Mode に切り替えるとカウンターは自動的に 0 にリセットされます。Reload Domain が無効になっている場合、カウンターはリセットされず、Play Mode の開始と終了時点の値が保持されます。つまり、エディターでプロジェクトを 2 回実行したときに、前回の実行でカウンターが変更された場合は、カウンターが 0 にならない可能性があります。
using UnityEngine;public class StaticCounterExample : MonoBehaviour{// this counter will not reset to zero when Domain Reloading is disabled static int counter = 0; // Update is called once per frame void Update() { if (Input.GetButtonDown("Jump")) { counter++; Debug.Log("Counter: " + counter); } }}
Reload Domain が無効な場合でもカウンターが確実にリセットされるようにするには、[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] 属性を使用し、値を明示的にリセットする必要があります。
using UnityEngine;public class StaticCounterExampleFixed : MonoBehaviour{ static int counter = 0; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] static void Init() { Debug.Log("Counter reset."); counter = 0; } // Update is called once per frame void Update() { if (Input.GetButtonDown("Jump")) { counter++; Debug.Log("Counter: " + counter); } }}

静的イベントハンドラー

Reload Domain を無効にすると、再生モードを終了しても、静的イベントハンドラーからメソッドの登録が解除されません。静的イベントハンドラーでメソッドを登録するコードがある場合は、問題になる可能性があります。例えば、エディターでプロジェクトを最初に再生したとき、メソッドは通常どおり登録されます。ただし、プロジェクトの 2 回目の再生では、これらのメソッドは最初の再生に加えて 2 回目の登録がされ、イベントが発生すると 2 回呼び出されます。
例えば、このコードは、Reload Domain を有効にした静的イベントハンドラー
Application.quitting
を使用してメソッドを登録します。再生モードが開始されると、Unity は自動的にイベントハンドラーをリセットするため、メソッドは 1 回のみ登録されます。ただし、Domain Reload を無効にすると、イベントハンドラーは消去されません。そのため、エディターにおけるプロジェクトの 2 回目の実行時にメソッドの 2 回目の登録が実行され、イベントが発生したときに 2 回呼び出されます。通常、これは望ましくない動作です。
using UnityEngine;public class StaticEventExample : MonoBehaviour{ void Start() { Debug.Log("Registering quit function"); Application.quitting += Quit; } static void Quit() { Debug.Log("Quitting!"); }}
Reload Domain が無効になっている場合、上記の例では、再生モードに入るたびに
Quit
メソッドが再度追加されます。これにより、再生モードを終了するたびに "Quitting!" というメッセージが表示されます。
Reload Domain が無効な場合でもイベントハンドラーが確実にリセットされるようにするには、[RuntimeInitializeOnLoadMethod] 属性を使用し、メソッドを明示的に登録解除して、2 回追加されないようにする必要があります。
using UnityEngine;public class StaticEventExampleFixed : MonoBehaviour{ [RuntimeInitializeOnLoadMethod] static void RunOnStart() { Debug.Log("Unregistering quit function"); Application.quitting -= Quit; } void Start() { Debug.Log("Registering quit function"); Application.quitting += Quit; } static void Quit() { Debug.Log("Quitting the Player"); }}
ランタイムスクリプトの場合は、
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
属性を使用して静的フィールドとイベントハンドラーをリセットする必要があります。
静的を使用するカスタムエディターウィンドウやインスペクターなどのエディタースクリプトでは、静的フィールドとイベントハンドラーをリセットするために
[InitializeOnEnterPlayMode]
属性を使用する必要があります。

追加リソース