【学习笔记】Unity StartCoroutine 中 yield return 总结

来源:互联网 发布:四川广电网络上网慢 编辑:程序博客网 时间:2024/06/02 14:09

          Unity 中协程是个非常强大的功能,其作用主要是用于游戏中的延时调用或者执行一连串的有时间间隔的事件流程,例如剧情对话等。

          看过几篇大佬的文章后,我简单总结了几点协程相关的知识点,旨在加深记忆,同时为初学者解惑。

          本篇总结没有截取测试代码,不过总结的内容并不深入,建议读者亲自调试一下,印象会更加深刻。

           1.协程与线程

            这是个面试中经常会问到的问题:协程与线程的区别在哪?

             其实就根本来说,协程除了名字之外,和线程是没有太大联系的。Unity中的特殊在于所有的脚本和代码都是在一个主线程里运行的,协程也不例外。协程与线程的相似点只在于,协程看起来也可以与其他函数并行执行。 但本质上来说,线程是通过可以开启多个子线程同时执行程序,而达到并行。而协程则是通过每帧检测的方式,在自己与其他函数之间切换。这种“来回跑”的方式,与Unity中一惯有明确执行顺序的风格(脚本生命周期)看起来不太统一。但这正是它的强大之处,使得我们在使用协程的时候不必考虑lock等诸多线程中的问题。

    

           2.协程的实现方式

            网上有大佬对协程本质的深入分析,简单理解就是,协程通过yield return  讲这个时间节点要执行的函数返回,然后在下一帧的时候再来继续yield return后面的调用。实质就是一个迭代器,执行到一定的节点位置进行记录。


           3.yield return 的不同返回类型(一)。

              使用yield return的时候你会发现它可以返回的类型一长串,对于初学者我觉得就分为带 new和不带new的就行了。

              先说不带new的。通常可以yield return的有 null,数字 ,字符串,布尔值甚至表达式,函数,嵌套协程等。

              以在Start()中开启当前协程为例,如果是不带new的返回类型,执行时间都是一样的。即在第一时间执行协程中的代码 到第一个yield return当行为止,然后在下一帧的Update之后,LateUpdate之前执行yield return后面的代码。(注:本人测试用的Unity版本是5.4.1,看过网上有些总结说是在LateUpdate之后执行,与我测试的结果不太一样,如果有疑问你们可以自己测试一下,因为Unity中某些版本可能会做微小改动)

             另外需要注意的是,yield return后面可以是一个函数调用,赋值表达式,嵌套的其它协程等。以赋值的表达式num=10为例;它会在当行yield return执行的时候就执行,函数调用和其它协程也是一样。也就是说,此时yield return的函数调用就相当于直接调用了这个函数,并且是当时就执行的。 而其它return 类型 如null,字符串,数字等一般只用作延迟一帧来用,其它作用,待我后期再研究下。

            4.yield return 的不同返回类型(二)。

             下面说带new的,也是通常我们重点使用的协程功能。

              这里列举几个:

                  (1).new  WaitUntil(Func<bool>)  参数是一个布尔返回类型的委托,作用是,知道这个返回的布尔值为true时,协程才会继续执行当行yield return 后面的代码。       

                  (2) new WaitForSeconds(ffloat)参数是float类型的数字,表示秒,也是协程最常用的功能之一。 作用是,在N秒后才会继续执行当行yield return 后面的代码。 

由于yield return可以在一个协程中任意位置写多个,配合这个可以实现很多时间细化可视化的功能。

                  (3)new WaitForEndOfFrame()作用是,在结束当前帧 摄像机和GUI被渲染以及其它函数完成后才会继续执行当行yield return 后面的代码。 这个我只验证了在LateUpdate执行完之后执行,具体在整个脚本周期中哪个函数执行完之后开始执行还未详细验证。

                  (4)new  WaitForFixedUpdate()  作用是,直到当行代码之后第一个FixedUpdate执行之后才会继续执行当行yield return 后面的代码。也就是说,如果是在start里面开启协程的话,第一次执行FixedUpdate之后就会继续执行return后面的代码。

                     后面还有许多类型的 返回,没有一一验证,不过作用应该大同小异,即在执行第一个该类型动作之后才会继续执行当行yield return 后面的代码。

                      值得一提的是,协程的延迟调用和非阻塞式挂起是用于网络请求等高级结构很好的工具,非常值得花一些时间去仔细研究。

             5.停止协程

                  协程内停止 可以用yield return break;

                  协程外停止 使用 StopCoroutine(string  methodname);

                  另外需要注意的是,设置当前协程所在脚本enable为false并不能停止当前协程的执行,只有设置当前脚本挂载gameobject.SetActive(false) 才可以。


协程使用得好坏,能够体现一个Unity工程师的功力如何,这是非常值得我们去深入研究的一块内容,这里只是简单进行一些总结学习。

  

传送门:http://www.manew.com/thread-102065-1-1.html            

0 0
原创粉丝点击