协程的基本原理

协程本质就是一个状态机,内部通过MoveNext()方法进行执行,并通过一个state状态标识来区分当前应该执行哪个部分,同时Current代表当前执行的部分的返回值。

Ienumerator PrintTime()
{
	int time = 10;
	yield return null;
	
	for(int i = 0;i < time;i++)
	{
		print(i);
		yield return null;
	}
	
	int totalTime = 0;
	for(j = 1;j < = time;j++)
	{
		totalTime += j;
	}
	yield return new WaitForSeconds(0.5f);
}

要点

public class 
{
	private int state;
	private object current;
	public object Current => current;
	public bool MoveNext()
	{
		switch(state)
		{
			case 0:
			int time = 10;
			current = null;
			state = 1;
			return true;

			case 1:
			int i = 0;
			print(i);
			current = null;
			state = 2;
			return true;

			//循环内部yield return ,则就是将循环拆成了多个小的部分
			//这里拆成了十个小的部分,state = 12
			case 12:
			int totalTime = 0;
			for(j = 1;j < = time;j++)
			{
				totalTime += j;
			}
			state = -1;  //最后一个部分,-1为结束标志
			current = new WaitForSeconds(0.5f);
			return false;  //由于这是最后一部分,返回false
		}
	}
}

进阶使用

//使用:
//在类中创建对象,并将对应的协程传入,在Update或Lateupdate等帧更新方法中进行调用自定义类的Update,通过类的标识位对协程进行控制
public class ManualCoroutineRunner
{
    private IEnumerator coroutine;
    private bool isPaused = false;
    
    public void Start(IEnumerator routine)
    {
        coroutine = routine;
    }
    
    public void Update()
    {
        if (!isPaused && coroutine != null)
        {
            if (!coroutine.MoveNext())
            {
                coroutine = null; // 协程结束
            }
        }
    }
    
    public void Pause() => isPaused = true;
    public void Resume() => isPaused = false;
}