Date: 2023/7/23Tags: Unity协程CSharp
首先需要明确的一点是,协程不是线程,协程依旧在主线程中进行
Unity中的协程通过迭代器实现,通过一个IEnumerator关键字实现一个迭代器方法,所以实际上协程的原理并不难
使用Update模拟协程
我们声明一个Enumerable类
public class CoroutineExample : IEnumerable
{
public IEnumerator GetEnumerator()
{
yield return 1;
yield return 2;
yield return 3;
}
}
首先尝试在Start函数中用while和foreach来进行迭代
void Start()
{
CoroutineExample cor = new CoroutineExample();
IEnumerator enumerator = cor.GetEnumerator();
while (enumerator.MoveNext())
{
Debug.Log(enumerator.Current.ToString());
}
//////////或者/////////
foreach (var i in cor)
{
Debug.Log(i);
}
}
两者的运行结果一致
1
2
3
1
2
3
接下来,我们不使用while或者foreach枚举元素,我们使用Update函数,每一帧执行MoveNext来进行枚举
private CoroutineExample cor;
private IEnumerator enumerator;
void Start()
{
cor = new CoroutineExample();
enumerator = cor.GetEnumerator();
}
void Update()
{
if (enumerator.MoveNext())
{
Debug.Log(enumerator.Current);
}
}
运行效果一致
1
2
3
使用Unity的协程
接下来我们使用StartCoroutine方法启动协程(为了方便查看,修改了GetEnumerator的代码)
public IEnumerator GetEnumerator()
{
Debug.Log("1");
yield return 1;
Debug.Log("2");
yield return 2;
Debug.Log("3");
yield return 3;
}
在Start函数中启动协程
void Start()
{
cor = new CoroutineExample();
enumerator = cor.GetEnumerator();
StartCoroutine(enumerator);
}
运行结果为
1
2
3
原理
由此可见,通过Update模拟协程和使用StartCoroutine方法启动协程的效果似乎是差不多的,Unity内部的执行逻辑也是一步一步的执行程序块,StartCoroutine会不停调用MoveNext方法,直到迭代结束,Coroutine的原理大致是每一帧调用IEnumerator的MoveNext方法,这也就是为什么我们需要定义一个返回值为IEnumerator的方法