Version: 2022.3
言語: 日本語
設定可能な再生開始時モード
Reload Scene

Domain Reload

Reload Domain (ドメインの再ロード) はスクリプトの状態をリセットします。これは、デフォルトで有効になっています。完全に新しいスクリプト状態を提供し、再生モードに入るたびにすべての静的フィールドと登録されたハンドラーをリセットします。つまり、Unity エディターで再生モードに入るたびに、プロジェクトはビルドで最初に起動したときと非常によく似た方法で再生を開始します。

Reload Domain には時間がかかります。この時間は、プロジェクト内のスクリプトの数と複雑さに伴い増加します。再生モードに入るのに長い時間がかかると、プロジェクトを素早く繰り返すのが難しくなります。そのため、Unity は Reload Domain を無効にするオプションを提供しています。

Reload Domain を無効にする

Reload Domain を無効にするには以下を行います。

  1. Edit > Project Settings > Editor の順に移動します。
  2. Enter Play Mode Options が有効になっていることを確認してください。
  3. Reload Domain を無効にします。

詳しくは、Play Mode の設定方法 を参照してください。

Reload Domain を無効にすると、Unity は毎回スクリプトの状態をリセットしないため、再生モードへの移行がより速くなります。ただし、再生モードにしたときにスクリプトの状態をリセットするかどうかは、ユーザーが決定します。これを行うには、再生モードの開始時にスクリプトの状態をリセットするコードを追加する必要があります。

Reload Domain が無効になっている場合でも、スクリプトを更新または再インポートすると、自動更新の設定 に基づいて Unity はスクリプトの状態を更新します。

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

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

静的フィールド

Reload Domain が無効になっている場合、 コードの 静的フィールド の値は自動的に元の値にリセットされません。これを明示的に行うコードを追加する必要があります。

次のコード例には、ユーザーが Jump ボタンを押すとインクリメントする静的カウンターフィールドがあります。Reload Domain を有効にすると、再生モードに入るときにカウンターは自動的にゼロにリセットされます。Reload Domain を無効にすると、カウンターはリセットされません。再生モードの内外で値を維持します。これは、エディターでプロジェクトを 2 回目に実行するときに、前回の実行でカウンターが変更された場合、カウンターがゼロにならない場合があることを意味します。

using UnityEngine;

public class StaticCounterExample : MonoBehaviour
{
//  Domain Reloading が無効になっている場合、この counter はゼロにリセットされません
    static int counter = 0; 

        // Update は、フレームごとに1度呼ばれます
    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 は、フレームごとに1度呼ばれます
    void Update()
    {
            if (Input.GetButtonDown("Jump"))
            {
                counter++;
                Debug.Log("Counter: " + counter);
            }
    }
}

静的イベントハンドラー

Reload Domain を無効にすると、再生モードを終了しても、静的イベントハンドラーからメソッドの登録が解除されません。静的イベントハンドラーでメソッドを登録するコードがある場合は、問題になる可能性があります。例えば、エディターでプロジェクトを最初に再生したとき、メソッドは通常通り登録されます。ただし、プロジェクトの 2 回目の再生では、これらのメソッドは最初の再生に加えて 2 回目の登録がされ、イベントが発生すると 2 回呼び出されます。

例えば、このコードはメソッドを、静的イベントハンドラー Application.quitting で登録します。Reload Domain を有効にすると、Unity は再生モードの開始時にイベントハンドラーを自動的にリセットするため、メソッドは一度だけ登録されます。ただし、Reload Domain を無効にすると、イベントハンドラーはクリアされないため、エディターでプロジェクトを 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] 属性を使用する必要があります。

設定可能な再生開始時モード
Reload Scene