微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

unity协程理解

什么是协程?

unity协程是一个能够暂停协程执行,暂停后立即返回主函数,执行主函数剩余的部分,直到中断指令完成后,从中断指令的下一行继续执行协程剩余的函数函数体全部执行完成,协程结束。

由于中断指令的出现,使得可以将一个函数分割到多个帧里去执行。

协程的好处:

让原来要使用异步 + 回调方式写的非人类代码, 可以用看似同步的方式写出来。

能够分步做一个比较耗时的事情,如果需要大量的计算,将计算放到一个随时间进行的协程来处理,能分散计算压力

协程的坏处:

协程本质是迭代器,且是基于unity生命周期的,大量开启协程会引起gc

如果同时激活的协程较多,就可能会出现多个高开销的协程挤在同一帧执行导致的卡帧

协程书写时的性能优化:

常见的问题是直接new 一个中断指令,带来不必要的 GC 负担,可以复用一个全局的中断指令对象,优化掉开销。

协程是在什么地方执行?

协程是通过迭代器来实现功能的,在迭代器中,最关键的是yield 的使用,这是实现协程功能的主要途径,通过该关键方法,可以使得协程的运行暂停、记录下一次启动的时间与位置。

yield 也是脚本生命周期的一些执行方法,不同的yield 的方法处于生命周期的不同位置:

yield return null; 暂停协程等待下一帧继续执行

yield return 0或其他数字; 暂停协程等待下一帧继续执行

yield return new WairForSeconds(时间); 等待规定时间后继续执行

yield return StartCoroutine("协程方法名");开启一个协程(嵌套协程)

yield return GameObject; 当游戏对象被获取到之后执行

yield return new WaitForFixedUpdate():等到下一个固定帧数更新

yield return new WaitForEndOfFrame():等到所有相机画面被渲染完毕后更新

yield break; 跳出协程对应方法,其后面的代码不会被执行

yield return new WaitUntil(...)根据定义挂起语句, 直到指定的条件返回 true

yield return new WaitWhile(...)根据定义挂起语句, 直到指定的条件返回 false

协程怎么开始?

首先通过一个迭代器定义一个返回值为IEnumerator的方法,然后再程序中通过StartCoroutine来开启一个协程即可:

在正式开始代码之前,需要了解StartCoroutine的两种重载方式:

StartCoroutine(string methodName):这种是没有参数的情况,直接通过方法名(字符串形式)来开启协程

StartCoroutine(IEnumerator routine):通过方法形式调用方法可以带参数

StartCoroutine(string methodName,object values):带参数的通过方法名(字符串形式)+参数(参数类型而不是字符串)进行调用

协程怎么结束?

StopCoroutine(string methodName):通过方法名(字符串)来进行

注意事项:如果使用StartCoroutine(string methodName)来开启一个协程的,那么结束协程就只能使用StopCoroutine(string methodName)和StopCoroutine(Coroutine routine)来结束协程

StopCoroutine(IEnumerator routine):通过方法形式来调用

StopCoroutine(Coroutine routine):通过指定的协程来关闭

StopAllCoroutines暂停的是当前脚本下的所有协程

gameObject.active = false 可以停止该对象上全部协程的执行,即使再次激活,也不能继续执行。但注意MonoBehavIoUr enabled = false 不能停止协程;对比 update却是可以在MonoBehavIoUr enabled = false 就中止

原因:由于协程在StartCoroutine时被注册到的GameObject上,他的生命期受限于GameObject的生命期,因此受GameObject是否active的影响。

结论:协程虽然是在MonoBehvavIoUr启动的(StartCoroutine)但是协程函数的地位完全是跟MonoBehavIoUr是一个层次的,不受MonoBehavIoUr的状态影响。

协程结束的标志是什么?

如果最后一个 yield return 的 IEnumerator 已经迭代到最后一个是,MoveNext 就会 返回 false 。这时,Unity就会将这个 IEnumerator 从 cortoutines list 中移除。

只有当这个对象的 MoveNext() 返回 false 时,即该 IEnumertator 的 Current 已经迭代到最后一个元素了,才会执行 yield return 后面的语句。

协程的使用场景例子:

一个复杂程序分帧执行;

制作计时器;

异步加载等功能,比如:

AB包资源的异步加载

Reaources资源的异步加载

场景的异步加载

WWW模块的异步请求

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐