域重新加载会重置您的脚本状态,并且默认启用。它为您提供了一个全新的脚本状态,并在每次进入播放模式时重置所有静态字段和已注册的处理程序。这意味着每次您在 Unity 编辑器中进入播放模式时,您的项目都以非常类似于第一次在构建中启动时的方式开始播放。
域重新加载需要时间,并且此时间会随着项目中脚本一段代码,允许您创建自己的组件、触发游戏事件、随时间推移修改组件属性以及以任何您喜欢的方式响应用户输入。 更多信息
参见 词汇表的数量和复杂性而增加。当进入播放模式需要很长时间时,快速迭代项目变得更加困难。这就是 Unity 提供关闭域重新加载选项的原因。
有关更多信息,请参阅 如何配置播放模式。
禁用域重新加载后,进入播放模式的速度更快,因为 Unity 不会每次都重置脚本状态。但是,随后您需要确保在进入播放模式时重置脚本状态。为此,您需要添加代码以在播放模式开始时重置脚本状态。
要禁用域重新加载
注意:当在进入播放模式时禁用域重新加载时,Unity 仍然会在执行资源数据库的自动或手动刷新时刷新脚本状态。有关何时以及如何发生这些刷新的更多信息,请参阅 刷新资源数据库。
为了确保脚本状态在播放模式下正确重置,您需要调整脚本中的静态字段和静态事件处理程序。
禁用域重新加载后,代码中静态字段的值不会自动重置为其原始值。您需要添加明确执行此操作的代码。
以下代码示例具有一个静态计数器字段,当用户按下跳跃按钮时,该字段会递增。启用域重新加载时,计数器在进入播放模式时会自动重置为零。禁用域重新加载时,计数器不会重置;它保留其在播放模式内外和之外的值。这意味着在编辑器中第二次运行项目时,如果计数器在上一次运行中发生了更改,则它可能不为零。
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);
}
}
}
为了确保即使在禁用域重新加载时计数器也能重置,您必须使用 [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);
}
}
}
在禁用域重新加载的情况下,当您退出播放模式时,Unity 不会从静态事件处理程序中注销方法。如果您的代码使用静态事件处理程序注册方法,这可能会导致复杂问题。例如,在编辑器中第一次播放项目时,方法将按正常方式注册。但是,在第二次播放项目时,这些方法将再次注册,此外还注册了第一次,导致事件发生时这些方法被调用两次。
例如,此代码使用静态事件处理程序 Application.quitting
注册一个方法。启用域重新加载时,Unity 会在播放模式开始时自动重置事件处理程序,因此该方法仅注册一次。但是,在禁用域重新加载的情况下,事件处理程序不会被清除,因此在编辑器中第二次运行项目时,该方法会再次注册,并在事件发生时被调用两次——这通常是不希望的。
using UnityEngine;
public class StaticEventExample : MonoBehaviour
{
void Start()
{
Debug.Log("Registering quit function");
Application.quitting += Quit;
}
static void Quit()
{
Debug.Log("Quitting!");
}
}
在禁用域重新加载的情况下,上面的示例在每次进入播放模式时都会再次添加 Quit
方法。这会导致每次退出播放模式时都会显示额外的“退出”消息。
为了确保即使在禁用域重新加载时事件处理程序也能重置,您必须使用 [RuntimeInitializeOnLoadMethod] 属性,并显式注销该方法,以使其不会被添加两次。
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)]
属性来重置静态字段和事件处理程序。
对于使用静态值的编辑器脚本(例如自定义编辑器窗口或检查器一个 Unity 窗口,显示有关当前选定的游戏对象、资源或项目设置的信息,允许您检查和编辑值。 更多信息
参见 词汇表),您必须使用 [InitializeOnEnterPlayMode]
属性来重置静态字段和事件处理程序。