Domain Reload を選択すると、スクリプト状態がリセットされ、デフォルトで有効になります。完全に新しいスクリプト状態が指定され、再生モードに切り替えるたびにすべての静的フィールドと登録されたハンドラーがリセットされます。つまり、Unity エディターで再生モードに切り替えるたびに、ビルドで最初に起動したときと非常に類似した方法でプロジェクトが再生を開始します。
Domain Reload の処理には時間がかかり、この時間はプロジェクト内のスクリプトの数と複雑さに応じて増加します。再生モードに切り替えるのに長い時間がかかると、プロジェクトで素早く反復処理を行うことが難しくなります。このため、Unity には Domain Reload を無効にするためのオプションが用意されています。
詳細については、再生モードの設定方法を参照してください。
Reload Domain を無効にすると、Unity は毎回スクリプトの状態をリセットしないため、再生モードへの移行がより速くなります。ただし、再生モードにしたときにスクリプトの状態をリセットするかどうかは、ユーザーが決定します。これを行うには、再生モードの開始時にスクリプトの状態をリセットするコードを追加する必要があります。
Reload Domain を無効にするには以下を行います。
ノート: Enter Play モードでの Domain Reload が無効になっていても、Unity はアセットデータベースの自動または手動更新を実行するときにスクリプトの状態を更新します。これらの更新のタイミングと実行方法の詳細については、アセットデータベースの更新を参照してください。
再生モードでスクリプティングの状態が正しく再生モードをリセットするには、スクリプトの静的フィールドと静的イベントハンドラーを調整する必要があります。
ドメインのリロードが無効になっている場合、コードの静的フィールドの値は自動的に元の値にリセットされません。これを明示的に行うコードを追加する必要があります。
以下のコード例には、ユーザーが 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] 属性を使用する必要があります。