当前位置:   article > 正文

Unity协程那些事(二)_unity 协程执行速度

unity 协程执行速度

版权申明:

  • 本文为“优梦创客”原创文章,您可以自由转载,但必须加入完整的版权声明
  • 更多学习资源请加QQ:1517069595获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)

本系列索引:

协程执行原理

在这里插入图片描述

  • 上图是Unity官方帮助文档的一张图。我们知道游戏是一帧一帧执行的,那么在我们游戏启动的时候,Unity会做一些初始化的工作,然后在程序退出的时候,会做一些退出工作。

  • 这些初始化和退出的工作,只会执行一次,而黑色箭头所指的部分,是Unity每一帧都会执行的。

  • Unity默认一秒钟运行60帧,也就是一秒钟做60次循环。在每一次循环的过程中,我们重点关注 game logic部分。

  • 我们的程序会去执行四种协程。

    • 一种是yield return null的协程,返回一个空的协程,在Unity中表示等待一帧画面。
    • 第二种是yield WaitForSeconds,这种协程表示等待指定的秒数。
    • 第三种是yield WWW 表示等待一个下载完毕。第四种yield StartCoroutine表示等待用StartCoroutine启动的任何的协程。
  • 因此我们可以知道,StartCoroutine表示启动一个协程,StopCoroutine表示停止一个协程,而yield表示暂停协程执行。

  • 具体到上图的CountCoroutine例子中,我们来看下yield发挥了什么作用。

  • 前面我们可以得知当执行CountCoroutine这个函数时。实际上就是创建了一个协程对象。

  • 这个协程对象会往下执行,首先执行for循环,i=0的初始化,打印i的值,再往下走到yield,我们知道yield后面是一个整体,这个整体的功能是创建一个新的协程,这个协程具有等待一秒钟的功能。

  • 当程序执行到这的时候,Unity的引擎,或者说C#的运行时,就不再往下执行了。yield相当于暂停协程执行,或者说是转移控制权给Unity。

  • 然后Unity继续往下走,执行其他的操作,比如动画、移动和一些更新等。

  • 到下一帧时,又执行Update后,Unity引擎会检查有没有已经注册的WaitForSeconds这样等待一定秒数的协程,如果有的的话,WaitForSeconds会继续被执行。

  • 需要注意的是,由于我们的WaitForSeconds需要等待一秒钟,而Unity默认的一秒钟有60FPS也就是60帧,所以说它执行到下一次的WaitForSeconds时,我们的协程仍然是处于等待状态,因为我们的WaitForSeconds并没有准备完毕。在这个等待的过程中,控制权继续交给Unity,直到等待到1秒钟完毕后,yield就不再暂停了,而是接着执行下一个循环,也就是i++打印1。

  • 以此类推,打印2,3,4…由此我们可以看出,yield的功能是不停的等待,直到等待的协程执行完成。这就是协程的原理。

    后面我们还会再详细地讲yield可以等待什么样的协程,为什么它可以等返回null的,为什么可以等WWW以及StartCoroutine创建的协程,这些都是有它的原因的,并不是说随便new一个对象就可以等的。

协程停止的坑点

在这里插入图片描述

  • 协程的停止和创建必须用相同的形式。

  • 有的同学希望禁用脚本来停止协程的执行,这样的努力是无效的:

在这里插入图片描述

  1. 将脚本的√取消后,协程仍然没有停止运行。

在这里插入图片描述

  1. 也有的同学尝试通过控制脚本来实现指定按键控制脚本禁用掉,以此来停掉协程,这种努力也是无效的。

在这里插入图片描述

  • 以上述代码为例,按下F2后,脚本停掉了,但是协程并没有停止运行。

  • 虽然禁用脚本不灵,但是我们还是有其它办法解决停止协程的办法的。可以把整个脚本挂在主摄像机的给移除掉:

在这里插入图片描述

  • 当然,想要在程序里控制脚本通过移除来禁用协程也是可以的:

在这里插入图片描述

那么还有没有其他的方式来实现呢?虽然禁用脚本不能实现,但是禁用游戏对象是不是可以把协程停掉呢?我们可以来试一下。

在这里插入图片描述

  • 当禁用游戏对象后,协程也停掉了。其实除了禁用游戏对象,销毁或移除游戏对象也可以实现这样的效果,那么编程时又该如何实现呢?

在这里插入图片描述

  • 那么我们就把所以的禁用协程的方法都试过了,只有禁用脚本组件这一种方式是无效的,这也是新手同学最常见的误区。

  • 总结一下,协程的停止有以下四种做法:

    • 通过StopCoroutine来停止
    • 删除脚本
    • 禁用脚本
    • 删除整个GameObject

系列配套视频戳这里

更多学习资源请加QQ:1517069595获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/95647
推荐阅读
相关标签
  

闽ICP备14008679号