StopAllCoroutines二三事

刚学习Unity的时候,总会不时看到文章说合理使用协程(Coroutine)能更好实现一些功能。今天不说怎么使用协程,相信网上已经有非常多的资料了,重点分析的目标是当初从未上心的一个函数StopAllCoroutines。

1.函数意义

第一眼看到函数名的时候,很有迷惑性。Stop All?!乖乖,这个函数有点霸道啊,直接就停掉所有的协程,这岂不是会停掉一些我不想停掉的协程呢?算了,这种接口还是少用为妙。不过后来仔细想想,Unity这么成熟一个商业引擎,做设计的工程师不至于这么无聊弄一些意义不大的接口吧。仔细看了看官方接口描述:

这些能够解释清楚了,只是停掉当前behaviour上的所有协程,不会影响到其他物体。做个测试,创建一个C#文件,名字叫Coroutine1,代码如下:

using UnityEngine;
using System.Collections;

public class Coroutine1 : MonoBehaviour {

	// Use this for initialization
	void Start () {
		StartCoroutine (Cor1 ());
		StartCoroutine (Cor2 ());
	}
	
	// Update is called once per frame
	void Update () {
		if(Input.GetKeyDown(KeyCode.Alpha1))
		   StopAllCoroutines();
	}

	IEnumerator Cor1(){
		Debug.LogError ("Start Cor1");
		int i = 0;
		while (true) {
			Debug.LogError ("Cor1 frame " + i);
			i++;
			yield return new WaitForSeconds(0.5f);
		}
		Debug.LogError ("end Cor1");
	}

	IEnumerator Cor2(){
		Debug.LogError ("Start Cor2");
			int i = 0;
			while (true) {
				Debug.LogError ("Cor2 frame " + i);
				i++;
				yield return new WaitForSeconds(0.5f);
			}
		Debug.LogError ("end Cor2");
	}
}

讲脚本随意挂到一个GameObject上,运行程序,可以看到Cor1和Cor2函数中while里面的日志交替输出。按下键盘上数字1后,停止输出日志,说明StopAllCoroutines确实停止了当前脚本上的所有协程。至于它真的会不会停掉所有物体上的所有协程,我不想贴代码,大家自己写个脚本去验证吧。

2.What is this behaviour?

搞清楚了函数的大致应用情况,但是仍有一丝疑惑。

回到接口本身,按照接口描述,是停止this behaviour上所有的协程,这个behaviour指的到底是挂载了我们所写脚本的GameObject上的这一个Coroutine1的实例,还是指场景里面所有的Coroutine1 实例呢?再做一个测试,新建一个脚本Coroutine2,代码如下:

using UnityEngine;
using System.Collections;

public class Coroutine2 : MonoBehaviour {

	// Use this for initialization
	void Start () {
		StartCoroutine (Cor ());
	}
	
	// Update is called once per frame
	void Update () {
		if (Input.GetKeyDown (KeyCode.Alpha1) && name == "Cube1") {
			StopAllCoroutines();
		}
	}

	IEnumerator Cor(){
		Debug.LogError ("Start Cor " + name);
		while (true) {
			Debug.LogError("Update Cor " + name);
			yield return new WaitForSeconds(0.5f);
		}
	}
}

在场景中创建2个GameObject “Cube1” 和 “Cube2”,再为两个物体分别挂载Coroutine2脚本。为了方便,代码中直接使用了物体名字,而没有通过其他方式来加以区分。

运行游戏可以看到仍然是两条日志交替输出。当按下数字键1后,日志不再输出“Start cor 1”,说明Cube1上脚本里面启动的协程已经被停止了,而Cube2上的协程还在继续运行。

很显然,输出结果已经告诉了我们答案。StopAllCoroutines只会停止调用这个接口的脚本实例对象上的所有协程,而非调用这个接口脚本的所有实例对象。

结语

可能有人会说,这个接口描述一看就知道结果是这样啊,还需要这样写脚本来验证?!请原谅一个强迫症患者偶尔咬文嚼字想要对于疑惑进行验证的心情。与其懵懵懂懂前进,不如怀着喜悦心情去寻究真相,这个过程本来就是满怀乐趣呢。

你可能感兴趣的:(unity3d)