Unity3D 协程
简介
什么是协程?
unity协程是一个能够暂停协程执行,暂停后立即返回主函数,执行主函数剩余的部分,直到中断指令完成后,从中断指令的下一行继续执行协程剩余的函数。函数体全部执行完成,协程结束。由于中断指令的出现,使得可以将一个函数分割到多个帧里去执行。
协程和线程的区别?
线程是利用多核达到真正的并行计算,缺点是会有大量的锁、切换、等待的问题,而协程是非抢占式,需要用户自己释放使用权来切换到其他协程, 因此同一时间其实只有一个协程拥有运行权, 相当于单线程的能力。
- 协程是 C# 线程的替代品, 是 Unity 不使用线程的解决方案。
- 使用协程不用考虑同步和锁的问题。
- 多个协程可以同时运行,它们会根据各自的启动顺序来更新。
性能:
在性能上相比于一般函数没有更多的开销。
协程的好处:
让原来要使用异步 + 回调方式写的非人类代码, 可以用看似同步的方式写出来。能够分步做一个比较耗时的事情,如果需要大量的计算,将计算放到一个随时间进行的协程来处理,能分散计算压力
协程的坏处:
协程本质是迭代器,且是基于unity生命周期的,大量开启协程会引起gc。如果同时激活的协程较多,就可能会出现多个高开销的协程挤在同一帧执行导致的卡帧。
使用
开启协程
// 形式一
StartCoroutine(CustomCorutine());
StartCoroutine(CustomCorutine("haha"));//向方法中传递参数 // 形式二
StartCoroutine(“CustomCorutine”);
StartCoroutine(“CustomCorutine”, "haha");//向方法中传递参数
void Awake()
{StartCoroutine(Corutine_WaitForFixedUpdate());
}void FixedUpdate()
{Debug.Log("FixedUpdate" );
}IEnumerator Corutine_WaitForFixedUpdate()
{yield return new WaitForFixedUpdate();Debug.Log(string .Format("====>{0} time:{1}", 1, Time .time));yield return new WaitForFixedUpdate();Debug.Log(string .Format("====>{0} time:{1}", 2, Time .time));
}
协程中的等待函数
yield null:协程将在下一帧所有脚本的Update执行之后,再继续执行.
yield WaitForSeconds:协程在延迟指定时间,且当前帧所有脚本的 Update全都执行结束后才继续执行.
yield WaitForFixedUpdate:协程在所有脚本的FixedUpdate执行之后,再继续执行.
yield WWW:协程在WWW下载资源完成后,再继续执行.
yield StartCoroutine:协程在指定协程执行结束后,再继续执行.
WaitForSecondsRealtime:与WaitForSeconds类似,但不受时间缩放影响.
WaitWhile:当返回条件为假时才执行后续步骤.
停止协程
在开发中可能会开启多个协程,如果你想停止其中某个协程,你可使用StopCoroutine,但在使用时,停止协程的方式要与开启协程的方法一致。.StopCoroutine(“CustomCorutine”)必须与StartCoroutine(“CustomCorutine”)成对使用,与StartCoroutine(CustomCorutine())一起使用则完全无效。
IEnumerator cor;
void Awake()
{// 注意保存IEnumerator变量.cor = Corutine_WaitForFixedUpdate();StartCoroutine(cor);StartCoroutine(Corutine_Stop());
}
IEnumerator Corutine_WaitForFixedUpdate()
{Debug.Log(string .Format("A : {0}", 0));yield return new WaitForEndOfFrame();Debug.Log(string .Format("A : {0}", 1));
}
IEnumerator Corutine_Stop()
{yield return new WaitForFixedUpdate();// 通过cor停止协程// 而不是this.StopCoroutine(Corutine_WaitForFixedUpdate());this.StopCoroutine(cor);
}
如果想停止多个协程,可使用StopAllCoroutines方法,但这种方法只能停止当前MonoBehaviour类实例中所有协程,其他不受影响。如果想停止gameObject上所有脚本组件中的协程,禁用脚本组件是无法停止协程的,只需要禁用gameObject即可。
其他问题
协程书写时的性能优化:
常见的问题是直接new 一个中断指令,带来不必要的 GC 负担,可以复用一个全局的中断指令对象,优化掉开销;在 Yielders.cs 这个文件里,已经集中地创建了上面这些类型的静态对象
这个链接分析了一下https://blog.csdn.net/liujunjie612/article/details/70623943
协程是在什么地方执行?
协程不是线程,不是异步执行;协程和monobehaviour的update函数一样也是在主线程中执行。unity在每一帧都会处理对象上的协程,也就是说,协程跟update一样都是unity每帧会去处理的函数。经过测试,协程至少是每帧的lateUpdate后运行的。
详细信息请看官方文档:Unity - Manual: Order of execution for event functions
同一时刻同一脚本实例中能有多少个运行的协程?
在一个MonoBehaviour提供的主线程里只能有一个处于运行状态的协程。因为协程不是线程,不是并行的。同一时刻、一个脚本实例中可以有多个暂停的协程,但只有一个运行着的协程。
协程的注意点:
- IEnumerator 类型的方法不能带 ref 或者 out 型的参数,但可以带被传递的引用。
- 在函数 Update 和 FixedUpdate 中不能使用 yield 语句,否则会报错, 但是可以启动协程。
- 在一个协程中,StartCoroutine()和 yield return StartCoroutine()是不一样的。
前者仅仅是开始一个新的Coroutine,这个新的Coroutine和现有Coroutine并行执行。
后者是返回一个新的Coroutine,是一个中断指令,当这个新的Coroutine执行完毕后,才继承执行现有Coroutine。
参考博客:https://zhuanlan.zhihu.com/p/59619632
https://www.cnblogs.com/crazytomato/p/8178382.html
Unity3D 协程相关推荐
- [Unity3D]-协程的介绍和使用
本文是个人对Unity协程的一些理解和总结.Unity协程长的有点像线程,但却不是线程.因为协程仍然是在主线程中执行,且在使用时不用考虑同步与锁的问题.协程只是控制代码等到特定的时机后再执行后续步骤. ...
- Unity3D协程(转)
这篇文章转自:http://blog.csdn.net/huang9012/article/details/38492937 协程介绍 在Unity中,协程(Coroutines)的形式是我最喜欢的功 ...
- Unity3d 协程、调用函数、委托
为什么80%的码农都做不了架构师?>>> (一)协程 开启方法:StartCoroutine("函数名"): 结束方法StopCoroutine(" ...
- unity3D协程(Coroutine)原理深入剖析
原文:http://www.tuicool.com/articles/3IV32m Unity协程(Coroutine)原理深入剖析 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:h ...
- Unity3D 协程 浅谈
理解:协程不是线程,也不是异步执行(知道就行). 1.协程和MonoBehaviour的Update函数一样,也是在MainThread中执行的(一定得明白这句话意思). 1 2 3 4 5 6 7 ...
- Unity3D协程介绍 以及 使用
作者ChevyRay ,2013年9月28日,snaker7译 原文地址:http://unitypatterns.com/introduction-to-coroutines/ 在Unity中,协 ...
- 6.Unity2D 横版 受击反馈+跟随血条+延时/延迟扣血+协程的应用
总目录https://blog.csdn.net/qq_54263076/category_11900070.html?spm=1001.2014.3001.5482 1. 受击反馈 用 Unity ...
- 学习|Unity3D使用协程实现减速停车效果
学更好的别人, 做更好的自己. --<微卡智享> 本文长度为4303字,预计阅读11分钟 前言 上一篇<学习|Unity3d的导航实现循环线路移动>讲了一下定制循环行驶路线的方 ...
- yield学习续:yield return迭代块在Unity3D中的应用——协程
必读好文推荐: Unity协程(Coroutine)原理深入剖析 Unity协程(Coroutine)原理深入剖析再续 上面的文章说得太透彻,所以这里就记一下自己的学习笔记了. 首先要说明的是,协程并 ...
最新文章
- 浅谈无人机的应用场景
- python的lambda函数_Python-Lambda函数的范围及其参数?
- VTK:相互作用之MoveAVertexUnstructuredGrid
- CentOS修改主机名(hostname)
- codeforces Balanced Substring
- Python 列表(List)
- mongodb排序_MongoDB排序
- 【Window】使用技巧
- 前端开发面试题-JavaScript(一)
- git小乌龟不显示图标状态解决方案
- 给SLAM小车添加 手柄遥控 功能 罗技F710和PS4 手柄
- 全网首篇用人话讲清楚:光纤中的色散
- python requests模块(爬虫)
- 整理--linux设备驱动模型
- 【科创人独家】EasyStack王瑞琳:All In超级领先,知易行难
- 美国参议员建议立法“黑掉国土安全部”
- 数学对计算机的重要性
- Pr 编译影片时出错。软件渲染错误
- 第39次全国计算机二级vb全真模拟考试系统,计算机等级考试二级VB全真模拟试题...
- WIZnet W5500系列培训活动之“MQTT协议讲解和实践(接入OneNET)”
热门文章
- CAD三维图形转化成二维图形的过程具体的步骤
- 经常听到卡农吧,可是你知道卡农背后的含义么?
- 第十三天-Http-GET、POST
- 级联引用完整性约束ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }
- DataGrip 连接MySQL 找不到需要的schemas
- 旅行青蛙服务器维护时间,旅行青蛙怎么调节时间 旅行青蛙修改时间攻略
- Mac下使用Eclipse读java源码
- [ZT]金融衍生品的重大危害性——兼谈3.27国债风暴
- Verilog语言- 和c语言的区别
- STM32 Cubemax(十一) ——JY901陀螺仪数据的读取与简单数据处理