YUAN
协程原理的简单认识.txt
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的方法

Published: 2023/7/23