FishPlayer

一个喜欢摸鱼的废物

0%

Unity函数Awake和OnEnable执行顺序小坑

Awake: This function is always called before any Start functions and also just after a prefabis instantiated. (If a GameObject is inactive during start up Awake is not called until it is made active.)

OnEnable: (only called if the Object is active): This function is called just after the object is enabled. This happens when a MonoBehaviour instance is created, such as when a level is loaded or a GameObject with the script component is instantiated.

check the exec order here

今天做工时候遇到了一个问题,我在Mono A的 Awake 中把Mono A的实例绑定到了GameManager里,然后再Mono B的 OnEnable 中获取Mono A的实例,结果跳了个空引用异常。
把我惊了,原来这一年多来我一直在一个误区里。

我以前一直认为是当场景里所有的 Awake 跑完才开始跑 OnEnable()。但其实不是这样的。

当一个Mono的 Awake 跑完以后会接着跑他的 OnEnable , 接着才去跑其他物体的 Awake 和 OnEnable。

随便写两行测试一下就知道了。

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

public class TesterA1 : MonoBehaviour
{
private Type m_type = null;

private void Awake()
{
m_type = this.GetType();
Debug.Log($"{m_type.Name} awake");
}

private void OnEnable()
{
Debug.Log($"{m_type.Name} on enable");
}
}

public class TesterB1 : MonoBehaviour
{
// Start is called before the first frame update
private Type m_type = null;

private void Awake()
{
m_type = this.GetType();
Debug.Log($"{m_type.Name} awake");
}

private void OnEnable()
{
Debug.Log($"{m_type.Name} on enable");
}
}

public class TesterC1 : MonoBehaviour
{
private Type m_type = null;

private void Awake()
{
m_type = this.GetType();
Debug.Log($"{m_type.Name} awake");
}

private void OnEnable()
{
Debug.Log($"{m_type.Name} on enable");
}
}

都整上一样的内容,A和C绑在物体tester01上,B绑在物体tester02上。