位置: 编程技术 - 正文

【Unity3D基础教程】(五):详解Unity3D中的协程(Coroutine)(unity3d官方教程)

编辑:rootadmin
【狗刨学习网】为什么需要协程在游戏中有许多过程(Process)需要花费多个逻辑帧去计算。你会遇到“密集”的流程,比如说寻路,寻路计算量非常大,所以我们通常会把它分割到不同的逻辑帧去进行计算,以免影响游戏的帧率。你会遇到“稀疏”的流程,比如说游戏中的触发器,这种触发器大多数时候什么也不做,但是一旦被调用会做非常重要的事情(比图说游戏中自动开启的门就是在门前放了一个Empty Object作为trigger,人到门前就会触发事件)。不管什么时候,如果你想创建一个能够历经多个逻辑帧的流程,但是却不使用多线程,那你就需要把一个任务来分割成多个任务,然后在下一帧继续执行这个任务。比如,A*算法是一个拥有主循环的算法,它拥有一个open list来记录它没有处理到的节点,那么我们为了不影响帧率,可以让A*算法在每个逻辑帧中只处理open list中一部分节点,来保证帧率不被影响(这种做法叫做time slicing)。再比如,我们在处理网络传输问题时,经常需要处理异步传输,需要等文件下载完毕之后再执行其他任务,一般我们使用回调来解决这个问题,但是Unity使用协程可以更加自然的解决这个问题,如下边的程序:private IEnumerator Test() { WWW www = new WWW(ASSEST_URL); yield return www; AssetBundle bundle = www.assetBundle;}协程是什么从程序结构的角度来讲,协程是一个有限状态机,这样说可能并不是很明白,说到协程(Coroutine),我们还要提到另一样东西,那就是子例程(Subroutine),子例程一般可以指函数,函数是没有状态的,等到它return之后,它的所有局部变量就消失了,但是在协程中我们可以在一个函数里多次返回,局部变量被当作状态保存在协程函数中,知道最后一次return,协程的状态才别清除。简单来说,协程就是:你可以写一段顺序的代码,然后标明哪里需要暂停,然后在下一帧或者一段时间后,系统会继续执行这段代码。协程怎么用?一个简单的C#代码,如下:IEnumerator LongComputation(){ while(someCondition) { /* 做一系列的工作 */ // 在这里暂停然后在下一帧继续执行 yield return null; }}协程是怎么工作的注意上边的代码示例,你会发现一个协程函数的返回&#;是IEnumerator,它是一个迭代器,你可以把它当成指向一个序列的某个节点的指针,它提供了两个重要的接口,分别是Current(返回当前指向的元素)和MoveNext()(将指针向前移动一个单位,如果移动成功,则返回true)。IEnumerator是一个interface,所以你不用担心的具体实现。通常,如果你想实现一个接口,你可以写一个类,实现成员,等等。迭代器块(iterator block)是一个方便的方式实现IEnumerator没有任何麻烦-你只是遵循一些规则,并实现IEnumerator由编译器自动生成。一个迭代器块具备如下特征:返回IEnumerator使用yield关键字所以yield关键词是干啥的?它声明序列中的下一个&#;或者是一个无意义的&#;。如果使用yield x(x是指一个具体的对象或数&#;)的话,那么movenext返回为true并且current被赋&#;为x,如果使用yield break使得movenext()返回false。那么我举例如下,这是一个迭代器块:public void Consumer(){ foreach(int i in Integers()) { Console.WriteLine(i.ToString()); }}public IEnumerable<int> Integers(){ yield return 1; yield return 2; yield return 4; yield return 8; yield return ; yield return ;}注意上文在迭代的过程中,你会发现,在两个yield之间的代码只有执行完毕之后,才会执行下一个yield,在Unity中,我们正是利用了这一点,我们可以写出下面这样的代码作为一个迭代器块:IEnumerator TellMeASecret(){ PlayAnimation("LeanInConspiratorially"); while(playingAnimation) yield return null; Say("I stole the cookie from the cookie jar!"); while(speaking) yield return null; PlayAnimation("LeanOutRelieved"); while(playingAnimation) yield return null;}然后我们可以使用下文这样的客户代码,来调用上文的程序,就可以实现延时的效果。IEnumerator e = TellMeASecret();while(e.MoveNext()) { // do whatever you like}协程是如何实现延时的?如你所见,yield return返回的&#;并不一定是有意义的,如null,但是我们更感兴趣的是,如何使用这个yield return的返回&#;来实现一些有趣的效果。Unity声明了YieldInstruction来作为所有返回&#;的基类,并且提供了几种常用的继承类,如WaitForSeconds(暂停一段时间继续执行),WaitForEndOfFrame(暂停到下一帧继续执行)等等。更巧妙的是yield 也可以返回一个Coroutine真身,Coroutine A返回一个Coroutine B本身的时候,即等到B做完了再执行A。下面有详细说明:Normal coroutine updates are run after the Update function returns. A coroutine is a function that can suspend its execution (yield) until the given YieldInstruction finishes. Different uses of Coroutines:yield; The coroutine willcontinue after all Update functions have been called on the next frame.yield WaitForSeconds(2); Continue after a specified time delay, after all Update functions have been called for the frameyield WaitForFixedUpdate(); Continue after all FixedUpdate has been called on all scriptsyield WWW Continue after a WWW download has completed.yield StartCoroutine(MyFunc); Chains the coroutine, and will wait for the MyFunc coroutine to complete first.实现延时的关键代码是在StartCoroutine里面,以为笔者也没有见过Unity的源码,那么我只能猜想StartCoroutine这个函数的内部构造应该是这样的:List unblockedCoroutines;List shouldRunNextFrame;List shouldRunAtEndOfFrame;SortedList<float, IEnumerator> shouldRunAfterTimes; foreach(IEnumerator coroutine in unblockedCoroutines){ if(!coroutine.MoveNext()) // This coroutine has finished continue; if(!coroutine.Current is YieldInstruction) { // This coroutine yielded null, or some other value we don't understand; run it next frame. shouldRunNextFrame.Add(coroutine); continue; } if(coroutine.Current is WaitForSeconds) { WaitForSeconds wait = (WaitForSeconds)coroutine.Current; shouldRunAfterTimes.Add(Time.time &#; wait.duration, coroutine); } else if(coroutine.Current is WaitForEndOfFrame) { shouldRunAtEndOfFrame.Add(coroutine); } else /* similar stuff for other YieldInstruction subtypes */} unblockedCoroutines = shouldRunNextFrame;当然了,我们还可以为YieldInstruction添加各种的子类,比如一个很容易想到的就是yield return new WaitForNotification(“GameOver”)来等待某个消息的触发.还有些更好玩的?第一个有趣的地方是,yield return可以返回任意YieldInstruction,所以我们可以在这里加上一些条件判断:YieldInstruction y; if(something) y = null; {} else if(somethingElse) y = new WaitForEndOfFrame(); {} else y = new WaitForSeconds(1.0f); {yield return y;第二个,由于一个协程只是一个迭代器块而已,所以你也可以自己遍历它,这在一些场景下很有用,例如在对协程是否执行加上条件判断的时候:IEnumerator DoSomething() { /* ... */} IEnumerator DoSomethingUnlessInterrupted() { IEnumerator e = DoSomething(); bool interrupted = false; while(!interrupted) { e.MoveNext(); yield return e.Current; interrupted = HasBeenInterrupted(); }}第三个,由于协程可以yield协程,所以我们可以自己创建一个协程函数,如下:IEnumerator UntilTrueCoroutine(Func fn) { while(!fn()) yield return null;}Coroutine UntilTrue(Func fn) { return StartCoroutine(UntilTrueCoroutine(fn));} IEnumerator SomeTask(){ /* ... */ yield return UntilTrue(() => _lives < 3); /* ... */}声明:此篇文档时来自于【狗刨学习网】社区,是网友自行发布的Unity3D学习文章,如果有什么内容侵犯了你的相关权益,请与官方沟通,我们会即时处理。更多精彩内容:www.gopedu.com

推荐整理分享【Unity3D基础教程】(五):详解Unity3D中的协程(Coroutine)(unity3d官方教程),希望有所帮助,仅作参考,欢迎阅读内容。

【Unity3D基础教程】(五):详解Unity3D中的协程(Coroutine)(unity3d官方教程)

文章相关热门搜索词:unity3d官方教程,unity3d基础操作,unity3d入门视频教程,unity3d2019教程,unity3d入门视频教程,unity3d初学者教程视频,unity 3d教学,unity 3d教学,内容如对您有帮助,希望把文章链接给更多的朋友!

Unity Android中的游戏移植 本周在旧金山举办的游戏开发者大会上,Unity宣布他们的UnityAndroid软件可以有偿的为开发者提供将他们自己开发的iOS平台上的游戏移植到Android平台的服

unity3D游戏之三消手游[陌陌熊熊消]发布8小时免费榜第3 狗刨学习网报道/陌陌旗下三消游戏《陌陌熊熊消》已于昨日(2月5日)开启公测,安卓和iOS双版同步登陆陌陌游戏中心。据官方透露,游戏发布仅8小时

[Unity3D]使用碰撞体做触发器实现自动开门 在游戏制作中触发器的使用非常的方便也非常实用。这一张我们简单介绍一下如何使用一个简单的触发器来实现自动开门关门的效果。首先确保你已经

标签: unity3d官方教程

本文链接地址:https://www.jiuchutong.com/biancheng/372877.html 转载请保留说明!

上一篇:Unity游戏开发之动画播放与动画控制器 Animator Controller(unity游戏开发入门经典)

下一篇:Unity Android中的游戏移植(unity做安卓app)

  • 平价转让股权如何做
  • 支付税金怎么算
  • 税务硕士是什么学位类别
  • 个人所得税中社保填写在哪昆山
  • 建筑业挂靠企业所得税如何收取
  • 小规模差额征税全额开票和差额开票
  • 总账和成本哪个工资高
  • 经营罚没物品增值税计算
  • 所得税二季度可以先少缴吗
  • 企业的定期存款
  • 不征收耕地占用税的情形
  • 无票收入申报时要填税率吗
  • 采购商品未收到分录
  • 拿租金抵押金如何做账?
  • 收到的软件退税怎么处理
  • 股权转让时其他股东不配合怎么转让
  • 哪些发票可以报销抵税
  • 发票抵税是指哪些内容
  • 本期有进项没有销项需要转出增值税吗?
  • 购买国债逆回购有股东限制
  • 如何确定增值税
  • 会员的消费频次怎么计算
  • 分公司发生修理费能否在总公司列支?
  • 企业所得税是当期收入吗
  • 收到汇算清缴退税的现金流量
  • 工程部物品领用表格模板
  • 认缴资本 实收资本
  • 设备安装服务费税收分类编码
  • 华为鸿蒙一键抠图
  • 收到培训内容的英文
  • 存贷款利率计算器
  • 苹果电脑进入安全模式按什么键
  • 汽车报废残值收入怎么做账
  • 土地增值税的具体规定
  • 股权转让有溢价分录怎么写
  • 收到固定资产的记账凭证
  • 关税组成计税价格公式推导
  • pytorch如何学
  • 装修费摊销3年会计分录
  • 商贸企业出口退税吗
  • 出口未申报如何处理
  • 小企业的准备阶段是创办企业吗
  • 餐饮行业经营模式有哪些
  • 所得税申报表是什么
  • 个税专项附加扣除标准调整
  • 短期借款预提利息通过短期借款科目核算
  • 实行自行申报的项目有哪些
  • 出口退税会计处理流程
  • 有限责任公司减资的条件
  • 财产租赁合同印花税申报期限
  • 以旧换新价格怎么确认
  • 转让证券需要交增值税吗
  • 一年内到期的非流动负债是经营性负债吗
  • 余利宝收益如何算
  • 借调人员费用列支
  • 企业中征码怎么生成
  • 毛利润利润总额净利润的关系图
  • 税控盘的会计分录怎么做
  • 微信怎么帮别人代缴社保
  • 销售退货怎么开票
  • cmos是一种什么芯片
  • mac安装字体方法
  • win10阻止可能不需要的应用吗
  • ubuntu 18.04怎么用
  • linux远程登录命令ssh
  • win10浏览器下载不了软件怎么回事
  • win8.1拨号上网
  • linux中keepalive
  • 安卓微信5.0版本下载
  • 精仿和媲美专柜有什么区别
  • 查找第一个字符
  • python中字典怎么用
  • jQuery简单实现title提示效果示例
  • js实现物体移动
  • 普通话的对话
  • javascript操作网页
  • 江苏省国家税务局总局官网
  • 期初未缴税额是什么意思
  • 可以抵扣的消费税有哪些
  • 工商变更与税务变更为什么不能同步
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设