Unity的协程是一个可以暂停协程执行的函数,暂停后立即返回到主函数,并执行主函数的剩余部分,直到中断指令执行完毕,然后继续执行协程的剩余函数从中断指令的下一行开始。
所有函数体执行完毕后,协程结束。 由于中断指令的出现,一个函数可以分成多个帧来执行。
协程不是进程或线程。 它是一个特殊的功能,可以在某处暂停,并可以在暂停点继续运行。
协程方法与普通方法的区别:
普通法
调用时,原来执行的部分保留在现场unity 协程3D素材,停止执行,然后执行要调用的方法。 而且,只有被调用的方法执行完毕后,才能返回到调用前的状态,继续执行。
协作方法
执行不需要等待协同方法执行完毕才执行原方法的代码再调用。 相反,两者异步执行。
协程不是多线程的。 它与主线程同时运行。 它在主线程运行时启动另一段逻辑处理。
类似于一个子线程,分开来处理一些问题,性能开销很小。
Unity的协程会在每一帧之后检查是否满足yield条件。 如果满足,就会执行yield return之后的代码。
MonoBehaviour 提供的主线程中只能有一个正在运行的协程,而其他协程则处于休眠状态。
协程实际上是在一个线程中,但是每个协程分时共享CUP。 协程可以访问和使用unity的所有方法和组件。
表现:
在性能方面与一般函数相比并没有更多的开销。
协程的好处:
这样原本使用异步+回调方法编写的非人类代码可以以看似同步的方式编写。
能够逐步完成耗时的任务。 如果需要大量计算,可以将计算放在一个随时间运行的协程中处理,这样可以分散计算压力。
协程的缺点:
协程本质上是迭代器,并且基于 Unity 生命周期。 启动大量协程会导致gc
如果同时激活的协程过多,多个高开销的协程可能会被挤到同一个帧中,导致帧卡住。
协程在哪里执行?
协程不是线程,也不是异步执行的; 协程和monobehaviour的update函数一样,也是在主线程中执行。
Unity将在每一帧中处理对象上的协程。 换句话说,协程和update一样,都是unity会处理每一帧的函数。 经测试,协程至少在每一帧的lateUpdate之后运行。
前驱知识:
2. 协程的实现
协程的实现需要继承Unity中的MonoBehaviour,并使用C#的迭代器IEnumrator。 格式如下:
IEnumrator 函数名(形参表) //最多只能有一个形参
{
yield return xxx; //恢复执行条件
//方法体
}
将需要执行的操作写入IEnumerator类型的方法中。 遇到yield后会暂时挂掉。 它不会继续执行yield语句后面的内容,直到满足yield返回后的条件。
3. 启动和停止协程
3.1 启动协程
要启动协程,您需要使用 StartCoroutine() 方法:
启动不带参数的协程:
StartCoroutine(协程名称()); 或 StartCoroutine("协程名称");
启动单参数协程:
StartCoroutine(协程名称(参数)); 或 StartCoroutine("协程名称",参数);
启动多参数协程:
StartCoroutine(协程名称(参数1,...));
或者
void StartCoroutine()//开启协程的函数
{
IEnumerator coroutine = Test(5, 6);
StartCoroutine(coroutine);
}
public IEnumerator Test(int a, int b)//协程
{
//等待帧画面渲染结束
yield return new WaitForEndOfFrame();
a=2;
b=3;
}
以“协程名称”开头的方法不允许传入多个参数。
3.2 协程结束
结束协程有两种情况:
协程终止的几种情况:
只有以协程名称字符串开头的协程才能使用此方法终止。
即:StartCoroutine("协程名称"); 或 StartCoroutine("协程名称", 参数);
允许使用 **StopCoroutine("coroutine name");** 终止协程
不允许通过直接调用协程方法来中止指定的协程。
两者: **StopCoroutine(协程名称([参数]));** 不允许
4.yield协程回复条件语句
快速查表:
收益声明
功能
产量返回空;
在下一帧中执行后续代码
收益率返回0;
在下一帧中执行后续代码
产量返回 6;(任意数字)
在下一帧中执行后续代码
产量突破;
直接结束协程后续操作
产量返回异步操作;
等待异步操作结束后再执行后续代码
yield return StartCoroution(其他协程);
在执行后续代码之前调用并执行其他协程
收益率返回WWW();
等待WWW操作完成后再执行后续代码
产量返回新的WaitForEndOfFrame();
等待该帧结束,等到所有相机和GUI都渲染完毕,在该帧显示在屏幕上之前执行
产量返回新的WaitForSeconds(0.3f);
等待0.3秒,在所有Update函数调用完成的帧后,指定的延迟时间后继续执行(这里的时间会受到Time.timeScale的影响);
产量返回新的WaitForSecondsRealtime(0.3f);
等待0.3秒,在所有Update函数调用完成的帧后unity 协程,指定的延迟时间后继续执行(这里的时间不受Time.timeScale的影响);
产量返回WaitForFixedUpdate();
等待下一个FixedUpdate开始后再执行后续代码
产量返回新的WaitUntil()
将协调执行程序开发,直到输入参数(或委托)为 true
产量返回新的WaitWhile()
将协调执行直到输入参数(或委托)为 false
生命周期图: