在Unity 2019.3中更快地进入运行模式
运行模式是Unity使用过程中的核心要素。随着Unity项目变得更加复杂,进入运行模式会需要更多的时间。
进入和退出运行模式的速度越快,意味着开发者进行关卡修改和测试的速度也就越快。我们在Unity 2019.3 Beta版中推出一项实验性功能:Configurable Enter Play Mode运行模式启用可配置化。
当编辑器进入运行模式时,Unity会执行两件事情:重设脚本状态,即进行Domain Reload域重新加载,以及重新加载场景。
这里会花费不少时间,并且项目越复杂,在运行模式中测试新改动的等待时间就更长。在Unity 2019.3 Beta版中,我们可以选择禁用“域重新加载”或“场景重新加载”,也可以同时禁用两者。
根据我们的测试结果,该功能可以节省多达50-90%的等待时间。
我们在一款AA级游戏、FPS示例项目、《Megacity》演示项目和空白项目中,测试了Configurable Enter Play Mode功能的效果。下图展示了在这4个项目中,编辑器进入运行模式的时间,数字越小,代表效果越好。
点击File > Project Settings > Editor,我们找到Enter Play Mode Options(启用运行模式选项),并可以选择是否启用Reload Domain(重新加载域)和Reload Scene(重新加载场景)。
这些选项允许我们在代码没有改动的情况下,从Enter Play Mode进程中禁用域或场景的重新加载。如果想要在进入运行模式前重置游戏状态,我们也可以通过API和回调来启用这项功能。
下图展示了禁用域重新加载和重新加载场景前后,启用运行模式流程的区别。
https://docs.unity3d.com/2019.3/Documentation/Manual/ConfigurableEnterPlayMode.html
了解Unity启用运行模式过程中的更多细节,请访问:
https://docs.unity3d.com/2019.3/Documentation/Manual/ConfigurableEnterPlayModeDetails.html
小提示:该功能仍处于实验阶段,并非所有Unity资源包都可以在禁用域和场景重新加载的情况下继续使用。
禁用域重新加载后,如何正确修改脚本
避免重新加载域非常简单,但也会带来一些问题。我们需要调整静态字段和静态事件处理器,来确保在进入运行模式时脚本状态能够被正确地重置。
下面的代码示例中有一个计数器,当玩家按下跳跃按键时,则计数器的数字会增加。当启用域重新加载时,计数器会在进入运行模式时自动重置为0。
然而当禁用域重新加载后,计数器不会重置。计数器会在进入和退出运行模式时保留当前数值。这意味着在编辑器中第二次运行项目时,如果计数器在前一次运行中有数值改动,那么第二次运行时,计数器可能不会从0开始。
public class StaticCounterExample : MonoBehaviour
{
// 该计数器在禁用域重新加载时不会重置为0
static int counter = 0;
// 每帧都会调用一次Update
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
void Update()
{
if (Input.GetButtonDown("Jump"))
{
counter++;
Debug.Log("Counter: " + counter);
}
}
}
当禁用了域重新加载后,Unity不会在退出运行模式时注销静态事件处理器上的方法。如果代码中将方法注册到静态事件处理器上,这会让情况变得复杂。
例如:在编辑器中第一次运行项目时,方法会被正常注册。然而,在第二次运行项目时,这些方法会在第一次注册的基础上再注册一次,于是在触发事件时,方法会调用两次。
下面的代码会在静态事件处理器Application.quitting上注册一个方法。
using UnityEngine;
public class StaticEventExample : MonoBehaviour
{
void Start()
{
Debug.Log("Registering quit function");
Application.quitting += Quit;
}
static void Quit()
{
Debug.Log("Quitting!");
}
}
当域重新加载被禁用后,每次进入运行模式时,上述示例代码都会添加一次Quit方法,造成每次退出运行模式时,出现额外的“Quitting”信息。
我们可以使用[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");
}
}
了解在禁用域重新加载时,如何正确修改脚本,请访问:
https://docs.unity3d.com/2019.3/Documentation/Manual/DomainReloading.html
Asset Store资源商店
我们希望Asset Store资源商店中高人气的资源包能够在禁用域和场景重新加载的情况下正常运行。
所以,如果你在使用插件资源包中遇见问题,可以将问题反馈给资源的发布者,从而帮助我们完善此功能。
加入Unity 2019.3 Beta版测试
如果你的项目进入运行模式的速度较慢,我们相信该功能可以极大提升速度。欢迎加入Unity 2019.3 Beta版测试,尝试这项新功能。
如果有任何意见或建议,请访问Unity论坛提交你的反馈。这项新功能仍处于实验阶段,你可以根据自己的需求帮助我们改进它。
访问Unity官方论坛:
https://forum.unity.com/threads/configurable-enter-play-mode.768689/
下载Unity Connect APP,请点击此处。 观看更多Unity官方精彩视频,请关注“Unity官方”B站账户。
你可以访问Unity答疑专区留下你的问题,Unity社区和官方团队帮你解答:
Connect.unity.com/g/discussion
推荐阅读
《尘封的记忆》学习课程上线Unity Learn Premium
Unity双十一资源大促 仅限24小时
Unity Asset Store双十一资源大促如期而至~ 近15000件精选资源插件五折优惠, 16件超惠资源插件低至三折![了解详情....]
喜欢本文,请点击“在看”