Unity--Monobehaviour生命周期 & 协程Coroutine

今天遇到一个问题,记录一下,顺便吧Monobehaviour生命周期 重新看了一遍。

Q:当在monobehaciour中调用了StartCoroutine后(此时yield return new WaitForSeconds(5f))monobehaciour脚本的enable置程false,那么协程后面的代码还会执行吗?

其实我的第一反应是不执行了,但是经过测试发现,我是错的。

先看一下正常情况下,协程的执行顺序

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
50
51
52
53
54
55
56
57
58
59
60
61
62
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class test1 : MonoBehaviour {

private bool startCall = true;
private bool updateCall = true;
private bool lateUpdateCall = true;

// Use this for initialization
void Start () {
if (startCall) {
Debug.LogError("Start Begin");
StartCoroutine(TestStart());
Debug.LogError("Start End");
startCall = false;
}
}

private void LateUpdate()
{
if (lateUpdateCall) {

Debug.LogError("TestLaterUpdate Begin");
StartCoroutine(TestLaterUpdate());
Debug.LogError("TestLaterUpdate End");
lateUpdateCall = false;
}
}

// Update is called once per frame
void Update () {
if (updateCall) {
Debug.LogError("Update Begin");
StartCoroutine(TestUpdate());
Debug.LogError("Update End");
updateCall = false;
}
}

IEnumerator TestStart()
{
Debug.LogError("TestStart Before");
yield return new WaitForSeconds(1);
Debug.LogError("TestStart After");
}

IEnumerator TestUpdate()
{
Debug.LogError("TestUpdate Before");
yield return new WaitForSeconds(1);
Debug.LogError("TestUpdate After");
}

IEnumerator TestLaterUpdate()
{
Debug.LogError("TestLaterUpdate Before");
yield return new WaitForSeconds(1);
Debug.LogError("TestLaterUpdate After");
}
}

输出:

那么现在改一下代码,在Start中调用完了协程后,将这个monobehaviour的enable置为false,看一下输出结果

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class test1 : MonoBehaviour {

private bool startCall = true;
private bool updateCall = true;
private bool lateUpdateCall = true;

// Use this for initialization
void Start () {
if (startCall) {
Debug.LogError("Start Begin");
StartCoroutine(TestStart());
Debug.LogError("Start End");
this.enabled = false;
startCall = false;
}
}

private void LateUpdate()
{
if (lateUpdateCall) {

Debug.LogError("TestLaterUpdate Begin");
StartCoroutine(TestLaterUpdate());
Debug.LogError("TestLaterUpdate End");
lateUpdateCall = false;
}
}

// Update is called once per frame
void Update () {
if (updateCall) {
Debug.LogError("Update Begin");
StartCoroutine(TestUpdate());
Debug.LogError("Update End");
updateCall = false;
}
}

IEnumerator TestStart()
{
Debug.LogError("TestStart Before");
yield return new WaitForSeconds(1);
Debug.LogError("TestStart After");
}

IEnumerator TestUpdate()
{
Debug.LogError("TestUpdate Before");
yield return new WaitForSeconds(1);
Debug.LogError("TestUpdate After");
}

IEnumerator TestLaterUpdate()
{
Debug.LogError("TestLaterUpdate Before");
yield return new WaitForSeconds(1);
Debug.LogError("TestLaterUpdate After");
}
}

结果:

也就是说我们在将monobehaviour的enable置程false后并没能终止协程,协程还是在运行,但是如果我们将GameObject的SetActive(false)后协程和monobehaviour和协程都会停止。

所以monobehaviour的enable是对协程没有影响的

最后 看一下Unity Monobehaviour的生命周期图

坚持原创技术分享,您的支持将鼓励我继续创作!