在 Unity 2019.3 中更快地进入播放模式

游戏模式是让 Unity 充满乐趣的核心所在。但随着项目越来越复杂,开始工作可能需要一段时间。进入和退出 "播放 "模式的速度越快,做出和测试更改的速度就越快。因此,我们在Unity 2019.3 测试版中引入了可配置的"进入游戏模式 "实验功能。
目前,当您在编辑器中进入 "播放模式 "时,Unity 会做两件事:重置脚本状态("域重载")和重新加载 "场景"。这需要时间,而且项目越复杂,在 "播放模式 "下测试新更改所需的时间就越长。不过,从 Unity 2019.3 测试版开始,您将可以选择禁用 "域重新加载 "和 "场景重新加载 "操作中的任意一个或两个。
根据我们的测试结果,这可以为您节省多达 50-90% 的等待时间,具体取决于您的项目。

在 "文件">" 项目设置" >"编辑器"中启用 "输入播放模式选项 "后,您将看到 "重新加载域 "和 "重新加载场景 "选项可用。详情请查看文档中的如何配置播放模式。

这些选项允许您在没有代码更改时禁用 "进入播放模式 "过程中的 "域 "和/或 "场景 "重载。如果您想在进入 "游戏模式 "前重置游戏状态,也可以通过API 和回调访问此功能。
下图显示了禁用 "重载域 "和 "重载场景 "前后的 "进入播放模式 "流程:

正如您所看到的,避免 "域名重载 "非常简单,但要付出代价。您需要对脚本中的静态字段和静态事件处理程序进行调整,以确保在进入播放模式时正确重置脚本状态。
下面的代码示例中有一个计数器,当玩家按下 "跳跃 "按钮时,计数器会上升。启用 "网域重载 "后,进入播放模式时计数器会自动重置为零。禁用 "网域重载 "后,计数器不会重置,而是在 "播放模式 "和 "退出模式 "之间保持其值。这意味着,在编辑器中第二次运行项目时,如果计数器在前一次运行中发生变化,则计数器可能不会为零。
public class StaticCounterExample :MonoBehaviour
{
禁用 "域重装 "时,//此计数器不会重置为零
static int counter = 0;
// 每帧调用一次更新
void Update()
{
if (Input.GetButtonDown("Jump"))
{
反++;
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.");
计数器 = 0;
}
// 每帧调用一次更新
void Update()
{
if (Input.GetButtonDown("Jump"))
{
反++;
Debug.Log("Counter: " + counter);
}
}
}
禁用 "域重载 "后,退出 "播放模式 "时,Unity 不会从静态事件处理程序中取消注册方法。如果您的代码使用静态事件处理程序注册方法,这可能会导致复杂问题。例如,在编辑器中第一次播放项目时,方法会正常注册。但是,在项目的第二次播放中,除了第一次之外,这些方法还将被第二次注册,因此,当事件发生时,这些方法将被调用两次。
以下代码向静态事件处理器Application.quitting 注册了一个方法:
using UnityEngine;
public class StaticEventExample :MonoBehaviour
{
void Start()
{
Debug.Log("Registering quit function");
Application.quitting += 退出;
}
static void Quit()
{
Debug.Log("Quitting!");
}
}
如果禁用了 "域重载",则每次进入播放模式时,上述示例都会再次添加 "退出 "方法。这样,每次退出播放模式时都会多出一条 "退出 "信息。
使用[RuntimeInitializeOnLoadMethod]属性,并明确取消注册该方法,以免重复添加:
using UnityEngine;
public class StaticEventExampleFixed :MonoBehaviour
{
[RuntimeInitializeOnLoadMethod]
static void RunOnStart()
{
Debug.Log("Unregistering quit function");
Application.quitting -= 退出;
}
void Start()
{
Debug.Log("Registering quit function");
Application.quitting += 退出;
}
static void Quit()
{
Debug.Log("Quitting the Player");
}
}
有关如何修改脚本以便在禁用 "域重载 "时正确执行的更多详情,请参阅我们的文档。
我们希望确保常用的 "资产商店 "软件包能与禁用的 "域 "和 "场景重载 "一起使用。如果您在项目中遇到任何问题,请向资产包发布者报告,以帮助我们。
我们相信,如果您的项目目前进入 "播放模式 "的速度较慢,该功能将大大加快速度。加入Unity 2019.3 测试版并试用,我们期待在论坛上听到您的意见!由于该功能是试验性的,您仍然可以帮助我们对其进行调整,以满足您的需求。我们特别期待听到您遇到的任何问题。
非常感谢论坛用户 @Sini、@chrisk、@Peter77 和 @Baste 通过测试该功能和提供宝贵的反馈意见为整个社区提供了帮助。