[Unity 杂货铺] 禁用 Domain Reload 提高效率
1 概要
- 打开设置
Edit → Project Settings → Editor - 勾选打开
Enter Play Mode Options→ 取消勾选Reload Domain - 使用
[RuntimeInitializeOnLoadMethod]特性,重置静态字段
2 背景
在 Unity 中点击播放 (Play) 按钮运行项目时,或者修改代码保存时,都会开启进度条进行域重新加载:

等待时间从 5 秒至 30 秒不等,卡 Loading 已然成为 Unity 开发者快速迭代之路的梦魇。
关于 域重新加载(domain reloading),可阅读官方文档中相关的四小节内容:https://docs.unity3d.com/6000.3/Documentation/Manual/domain-reloading.html
建议阅读 Unity 英文版本的文档,有中文需求也考虑直接翻译英文版本。
英文文档伴随着 Unity 的升级会有迭代删改,但这些修改似乎并不会重新翻译。即使选择中文文档的最新版本,仍旧可能是落后的翻译版本。
默认情况下,Unity 会在进入 Play 模式时重新加载域以重置应用程序状态,包括所有静态字段,但域重载也是一个耗时的操作。
Unity 编辑器在Project Settings提供了Enter Play Mode Options选项,用以禁用“重新加载域”(Reload Domain) 和“重新加载场景” (Reload Scene) 。
Reload Scene 耗时相对较少,可视情况保留。
而禁用域重载,点击 Play 按钮,此时不再弹出进度条,进入游戏的速度大幅加快。
但后续再点击 Play 按钮进入游戏时,可能会由于静态字段残留,静态事件重复注册等,造成多次回调,导致行为不可预测。所以需要进行手动重置。
3 重置静态字段
其实还是阅读文档即可:
https://docs.unity3d.com/6000.3/Documentation/Manual/domain-reloading.html
编写类似这样的代码,会在加载第一个场景之前被调用:
using UnityEngine;
public static class GlobalReset
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void ResetAll()
{
GameState.Reset();
EventManager.Clear();
ServiceLocator.Clear();
}
}
另外可使用到的有:EditorApplication.playModeStateChanged和[InitializeOnEnterPlayMode]
Github 中 UnityDomainReloadHelper 扩展了 RuntimeInitializeOnLoadMethod,添加了更方便清理的特性:
https://github.com/joshcamas/unity-domain-reload-helper
4 相关的开源库
4.1 com.unity.editoriterationprofiler
https://github.com/Unity-Technologies/com.unity.editoriterationprofiler
官方库,用于测量域重载的耗时。
4.2 UnityManuallyReload
https://github.com/ZeroUltra/UnityManuallyReload
手动编译 Reload 的工具,以及作者在知乎上的文章:
4.3 UnityDomainReloadHelper
https://github.com/joshcamas/unity-domain-reload-helper
4.4 UnityFastPlay
单脚本,大概是单独添加一个“Play without domain reload”的按钮
https://github.com/JonathanTremblay/UnityFastPlay
5 个人实践
个人会尝试关闭域重载,保持场景重载。对静态变量进行手动重置,相关重置方法限制在编辑器宏之内。
或者参考使用 UnityFastPlay,加一个用于快速迭代的播放按钮。
目前的理解是,由于静态字段的状态保留,可能会导致额外的报错,但应该不会掩盖原本的问题。即不会导致问题在打包之后才暴露出来,所以整体上应该是相对“安全”的。
另外在代码修改编译时,仍然还是会进行重载的。所以整体运行状态应该是时旧时新的。
目前的疑惑是文档中提及:“当您禁用域重新加载时,非序列化字段在编辑模式下保持在播放模式期间分配给它们的值。”还需要观察下这里保持可能造成的影响。

浙公网安备 33010602011771号