前言

最近在学习 unity 的 dots,然后在配置环境的时候发现其修改设置有这么一句话 In the "Editor" section of the project settings, enable "Enter Play Mode Options" but leave "Reload Domain" and "Reload Scene" disabled.

Reload Scene 我们可以看为重新加载场景,那么 Reload Domain 是什么,因此就有了这篇文章。

Reload Domain

即重置脚本状态。因此我们可以知道按下 unity editor 的播放键之后,unity 会干两件事:

  • 重置所有脚本的状态
  • 重新加载场景

这两个操作是非常耗时的,且耗费时间会随着项目复杂度增大而增大。因此在 Unity 2019.3 beta 版本起,可以选择关掉这两个选项。

在禁用后正确修改自己的脚本

静态字段

以下代码在第二次运行时,counter 字段在第二次运行时并不会重置为 0 ,而是保持前一次运行时最后的数字。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ReloadDomainTest : MonoBehaviour
{
private static int counter = 0;

private void Update()
{
if (Input.GetKeyDown(KeyCode.K))
{
counter++;
Debug.Log($"counter: {counter}");
}
}
}

此时需要 [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] 来显示初始化此字段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ReloadDomainTest : MonoBehaviour
{
private static int counter = 0;

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void InitFiled()
{
counter = 0;
Debug.Log("Reset static field");
}

private void Update()
{
if (Input.GetKeyDown(KeyCode.K))
{
counter++;
Debug.Log($"counter: {counter}");
}
}
}

静态事件

同理,禁用之后 unity 也不会从静态事件中注销方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ReloadDomainTest : MonoBehaviour
{
private static event EventHandler staticEvent;

private void Start()
{
Debug.Log("Register static function");
staticEvent += OnstaticEvent;
}

private void OnstaticEvent(object sender, EventArgs e)
{
Debug.Log("static function call");
}

private void Update()
{
staticEvent?.Invoke(this, EventArgs.Empty);
}
}

此处就需要使用 [RuntimeInitializeOnLoadMethod] 属性显示注销方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class ReloadDomainTest : MonoBehaviour
{
private static event EventHandler staticEvent;

[RuntimeInitializeOnLoadMethod]
private static void RunOnStart()
{
Debug.Log("Unregister static function");
staticEvent -= OnstaticEvent;
}

private void Start()
{
Debug.Log("Register static function");
staticEvent += OnstaticEvent;
}

private static void OnstaticEvent(object sender, EventArgs e)
{
Debug.Log("static function call");
}

private void Update()
{
staticEvent?.Invoke(this, EventArgs.Empty);
}
}