包含此页的版本:
不含此页的版本:
脚本域,也称为应用程序域,或简称为域,是 Unity 托管脚本环境的核心功能。域是专用于特定应用程序的独立内存部分,其中包含应用程序所需的编译类型,这些类型分组到称为程序集的逻辑单元中。它还包含表示当前应用程序状态的数据,例如托管内存各个部分中的变量和对象引用的值。
默认情况下,Unity 会在进入 Play 模式时重新加载域以重置应用程序状态。通常需要在进入播放模式之前重置状态,以便应用程序像在新生成开始时一样启动。例如,在上一个运行模式会话中递增的静态计数器应在下一个会话中再次从零开始。但是,域重新加载也是一项耗时的作,当您经常在编辑和播放模式之间切换时,它会对迭代时间产生负面影响。为了加快迭代时间,可以在进入播放模式时禁用域重新加载,但必须在代码中手动重置状态。
注意:当 Unity 检测到对脚本一段代码,允许您创建自己的组件、触发游戏事件、随时间修改组件属性以及以您喜欢的任何方式响应用户输入。更多信息
请参阅术语表.即使禁用了进入播放模式时的域重新加载,这种情况仍然会发生。有关资产数据库刷新的时间和方式的更多信息,请参阅刷新资产数据库。
禁用域重新加载时:
OnDisable或OnEnable调用标有[ExecuteInEditMode]或[ExecuteAlways].若要补偿 Play 模式会话之间的这种数据持久性,并以新的应用程序状态进入 Play 模式,必须在代码中重置状态。
有关禁用域和场景场景包含游戏的环境和菜单。将每个唯一的场景文件视为一个独特的关卡。在每个场景中,你放置你的环境、障碍物和装饰品,基本上是将你的游戏设计和构建成碎片。更多信息
请参阅术语表reload,请参阅禁用域和场景重新加载的详细信息。
禁用域重新加载后,静态字段的值和分配给静态事件的处理程序将在播放模式运行之间保留。以下代码示例有一个静态计数器,该计数器在按下任何键盘键时递增。该代码还注册了一个方法来处理静态事件EditorApplication.playModeStateChanged.
启用域重新加载后,Unity 会在进入 Play 模式时重新初始化此代码,擦除上一次 Play 模式运行中的状态,包括计数器值和事件处理程序的注册。禁用域重新加载后,计数器值和事件处理程序注册都将保留上次运行。在下一次运行播放模式时,计数器从上一次运行结束时的值开始,并在一次事件出现时多次调用事件处理程序方法,从而在控制台中生成多个“正在退出播放模式!
// Copy-paste this code into a MonoBehaviour script attached to a GameObject in your project.
// Run it with domain reload enabled and then with domain reload disabled and note the different behavior.
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class StateResetExample : MonoBehaviour
{
// With domain reload disabled this counter won't reset to zero on exiting Play mode
static int counter = 0;
void Start()
{
// Register handler
#if UNITY_EDITOR
EditorApplication.playModeStateChanged += OnExitPlayMode;
#endif
}
void Update()
{
if (Input.anyKeyDown)
{
counter++;
Debug.Log("Counter: " + counter);
}
}
#if UNITY_EDITOR
private static void OnExitPlayMode(PlayModeStateChange state)
{
if(state == PlayModeStateChange.ExitingPlayMode)
{
// With domain reload disabled this message prints multiple times after the first Play mode run
Debug.Log("Exiting Play mode!");
}
}
#endif
}
可以使用显式重置计数器并在播放模式运行之间取消注册事件处理程序的代码来修复问题行为。您可以在进入播放模式或退出播放模式时执行此作。
在退出播放模式时重置状态通常比在进入时重置状态最有效。您可以使用EditorApplication.playModeStateChanged事件及其ExitingPlayMode枚举值来捕获 Play 模式退出事件并重置该点的状态。在以下示例中,Play 模式退出的事件处理程序用于注销自身,但此时您也可以使用此方法注销任何其他静态事件处理程序:
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class StateResetOnExit : MonoBehaviour
{
static int counter = 0;
void Start()
{
#if UNITY_EDITOR
EditorApplication.playModeStateChanged += OnExitPlayMode;
#endif
}
// Update is called once per frame
void Update()
{
if (Input.anyKeyDown)
{
counter++;
Debug.Log("Counter: " + counter);
}
}
#if UNITY_EDITOR
private static void OnExitPlayMode(PlayModeStateChange state)
{
if(state == PlayModeStateChange.ExitingPlayMode)
{
Debug.Log("Exiting Play mode!");
Debug.Log("Unregistering handler.");
// Unregister the handler so it doesn't affect the next Play mode run
EditorApplication.playModeStateChanged -= OnExitPlayMode;
Debug.Log("Resetting counter.");
// Reset the counter so it starts from 0 on the next Play mode run
counter = 0;
}
}
#endif
}
EditorApplication.playModeStateChanged在UnityEditor命名空间,因此它只能在 Unity 编辑器中的 Play 模式下工作,而不适用于独立的 Player 版本。
如果代码在“播放”模式下执行,则在退出“播放”模式时不能依赖重置状态。你的代码可能会在编辑模式下修改静态变量,因此你必须在进入播放模式时重置该变量。
注意:对于在编辑模式下执行的脚本,禁用域重新加载会跳过MonoBehaviour.OnDisable和禁用场景重新加载跳过MonoBehaviour.OnDestroy,这使得这些方法不适合在此类脚本中重置状态。有关更多信息,请参阅禁用域和场景重新加载的详细信息。
您还可以在进入播放模式时重置状态。如果你在捕获退出的播放模式事件时遇到任何特定于平台的问题,或者你的代码也在编辑模式下执行,这可能是一个有用的替代方法。为了说明起见,以下示例演示了在进入播放模式时重置静态变量和取消注册静态事件处理程序。最佳做法是在退出播放模式时始终注销静态事件处理程序。等到下一个播放模式会话可能会导致对象引用问题,从而导致取消注册错误的处理程序。
Unity 在UnityEngine和UnityEditor命名空间,可用于执行初始化工作,包括手动状态重置。应使用哪些属性取决于代码是在编辑模式还是播放模式下运行。要重置播放器(运行时)脚本进入播放模式时的状态,可以使用[RuntimeInitializeOnLoadMethod]属性与RuntimeInitializeLoadType.SubsystemRegistration参数:
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class StateResetOnEnter : MonoBehaviour
{
static int counter = 0;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void Init()
{
Debug.Log("Unregistering handler.");
// Unregister the handler so it doesn't affect the next Play mode run
EditorApplication.playModeStateChanged -= OnExitPlayMode;
Debug.Log("Resetting counter.");
// Reset the counter so it starts from 0 on the next Play mode run
counter = 0;
}
void Start()
{
#if UNITY_EDITOR
EditorApplication.playModeStateChanged += OnExitPlayMode;
#endif
}
// Update is called once per frame
void Update()
{
if (Input.anyKeyDown)
{
counter++;
Debug.Log("Counter: " + counter);
}
}
#if UNITY_EDITOR
private static void OnExitPlayMode(PlayModeStateChange state)
{
if(state == PlayModeStateChange.ExitingPlayMode)
{
Debug.Log("Exiting Play mode!");
}
}
#endif
}
[RuntimeInitializeOnLoadMethod]在UnityEngine命名空间,因此它仅在 Play 模式下可用。对于仅限编辑器的脚本,例如自定义编辑器窗口或检查器一个 Unity 窗口,显示有关当前选定游戏对象、资产或项目设置的信息,允许您检查和编辑值。更多信息
请参阅术语表使用静态的,您可以执行以下作之一:
[InitializeOnLoadAttribute]注册 的处理程序EditorApplication.playModeStateChanged,然后在进入或退出播放模式时执行状态清理。请参阅EditorApplication.playModeStateChangedAPI 参考示例。[InitializeOnEnterPlayMode]属性,专门在进入播放模式时执行清理。注意:虽然前面的代码示例使用 MonoBehaviour 类,但您也可以在任何类型的脚本上使用这些初始化属性,包括继承自 ScriptableObject 或您自己的自定义 C# 类型的脚本。