unity提供了一种类似“多段代码并行执行”的功能,即协程。
我们在定义一个协程的时候,需要遵循类似这样的语法
IEnumerator(枚举器接口)
namespace System.Collections
{
public interface IEnumerator
{
object Current { get; }//获取当前元素
bool MoveNext();//移动至下一个元素
void Reset();//重置回第一个元素
}
}
枚举器接口提供了一种通用遍历集合的方法,如使用foreach就是使用了一个IEnumerator。
IEnumerable(可被枚举接口)
C#自带的数据结构大多数都是IEnumerable,我们可以用IEnumerable来获取一个它的枚举器。
public interface IEnumerable
{
IEnumerator GetIEnumerator();
}
使用枚举器遍历一个List:
Iterator(迭代器)
迭代器是一种设计模式,是自定义一个枚举器的行为。
一个简单的迭代器:
注意:当我们在一个返回类型为IEnumerable的函数中使用yield关键字时,系统会自动生成一个继承自IEnumerable的类,并在该类中实现我们所写的逻辑(如MoveNext()等)。
这个类会做以下事情:
1.记录当前的迭代状态,包括本地变量的值和迭代器在集合中的位置。
2.将yield return x翻译为“将Current设为x,记录当前状态,并暂停执行”
所以yield的功能就显而易见了:
1.提供枚举器的下一个值
2.“暂停函数执行”,并在下一次执行该函数时从yield return的位置开始。
协程的原理:利用迭代器的机制实现了“执行一系列操作”的功能。
当我们在调用StartCoroutine()来执行协程时,其实是:
1.每一帧调用MoveNext(),直到遇到yield return。
2.通过yield return来返回Current的值。
协程的使用
首先通过一个迭代器定义一个返回值为IEnumerator的方法,然后再程序中通过StartCoroutine来开启一个协程即可:
在正式开始代码之前,需要了解StartCoroutine的两种重载方式:
StartCoroutine(string methodName):这种是没有参数的情况,直接通过方法名(字符串形式)来开启协程
StartCoroutine(IEnumerator routine):通过方法形式调用
StartCoroutine(string methodName,object values):带参数的通过方法名进行调用
在一个协程开始后,同样会对应一个结束协程的方法StopCoroutine与StopAllCoroutines两种方式,但是需要注意的是,两者的使用需要遵循一定的规则,在介绍规则之前,同样介绍一下关于StopCoroutine重载:
StopCoroutine(string methodName):通过方法名(字符串)来进行
StopCoroutine(IEnumerator routine):通过方法形式来调用
StopCoroutine(Coroutine routine):通过指定的协程来关闭
刚刚我们说到他们的使用是有一定的规则的,那么规则是什么呢,答案是前两种结束协程方法的使用上,如果我们是使用StartCoroutine(string methodName)来开启一个协程的,那么结束协程就只能使用StopCoroutine(string methodName)和StopCoroutine(Coroutine routine)来结束协程。