Unity中coroutine问题的示例分析

这篇文章主要介绍了Unity中coroutine问题的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

1、从表面看协程的执行顺序

一个最简单的协程函数:

IEnumerator Test()
{
    yield return new WaitForSeconds(1);
    Debug.Log("End");
}

// 在其它地方StartCoroutine(Test());

作用:当你在其它地方执行了StartCoroutine(Test());之后,1秒之后打印“End”。

在开启协程之后,Test何时被调用?答案其实是每帧都要调用一次。(对迭代器函数来说,意思是每帧继续执行一次)。

如果每帧都继续,那么Test为什么最终在一秒后继续执行呢?答案在WaitForSeconds里面。

流程是这样的:

1、在StartCoroutine(Test())里,Test第一次被执行,yield中止并返回一个“WaitForSeconds(1)”对象。

2、执行StartCoroutine时,Unity内部注册这个Test函数。因为之后每帧都要调用,Unity内部先记下来。

3、这里,返回的WaitForSeconds(1)其实是一个小花招,它的设计思路是:

如果(Time.time小于之前说好的时间)
{
    返回:没结束;
}
返回:结束了,继续。

// 这里用伪码表示,想知道原理可以看后面的Unity官方说明文档

4、记住:协程函数每帧都要调用一次。于是Unity引擎层在这一秒,每帧都调用Test函数,重复了几十次,每次都被WaitForSeconds挡住,无法往下执行。

5、直到某一次调用,时隔1秒后了,WaitForSeconds终于放行了,Test才有机会继续执行,打印“End”。

这就是以WaitForSeconds为例解释的,协程的执行流程,以及等待1秒的原理。

2、解释yield return www;

现在可以回到题主问题了,其实yield return www 和 yield return new WaitForSeconds(1)是完全一样的道理,WWW的设计是:

如果(网络请求还在进行中)
{
    返回:没结束;
}
返回:结束了

同样的方式,如果网络请求没完成,那么你的协程函数就会被www阻拦住。这样就巧妙实现了一种异步机制,整个游戏不会因为www而卡住。

3、Unity如何做到这一点的?

eldereal 的回答很详细,其实C#根本就不支持真正的协程,而只支持迭代器。

由于游戏引擎的特殊性(每帧更新),Unity很巧妙的把迭代器改装成了一个似乎能并行执行的东西,也确实很好用。

别忘了,WWW和WaitForSeconds都是Unity提供的类,并不是C#原本就支持的。如果你很好奇,想扩展出自己的类似WWW的类,参考官方文档自定义Yield对象:

CustomYieldInstruction

https://docs.unity3d.com/ScriptReference/CustomYieldInstruction.html

由于Unity的这种“伪”协程属于自己制定的方案,未来引擎更新时候甚至会修改设计,所以理解调用顺序和大致原理更重要,不要拘泥于代码本身。

4、其它说明

Unity的Coroutine机制设计的很好,就是这个名字起的太有问题了,无论英文的Coroutine和中文的协程,都很不合适。

有一定golang、python gevent、skynet开发经验的人(主要是服务器端的),都对协程有较好的理解,而Unity的协程与真正的协程差异太大了。起同样的名字带来很大的误导作用,交流也很困难。

一句话解释Unity协程:其实Unity的Coroutine在我看来,更像是“注册一个 每帧都调用的函数”,只不过这个函数支持yield中止,仅此而已。

感谢你能够认真阅读完这篇文章,希望小编分享的“Unity中coroutine问题的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持编程之家,关注编程之家行业资讯频道,更多相关知识等着你来学习!

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

相关推荐


这篇文章主要介绍了Unity游戏开发中外观模式是什么意思,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家...
这篇文章主要介绍Unity中地面检测方案的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1.普通射线在角色坐标(一般是脚底)...
这篇文章主要介绍了Unity游戏开发中如何消除不想要的黄色警告,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带...
这篇文章主要介绍了Unity中有多少种渲染队列,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解
这篇文章主要介绍Unity中如何实现Texture,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!了解Texture2D 如上图,Texture2D是一张
小编给大家分享一下Unity中DOTS要实现的特点有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让...
这篇文章给大家分享的是有关unity中如何实现UGUI遮罩流光特效的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。下面是核心shader:Sh...
这篇文章主要为大家展示了“Unity中如何实现3D坐标转换UGUI坐标”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下...
这篇文章主要介绍了Unity游戏开发中设计模式的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家...
这篇文章主要介绍了Unity中如何实现仿真丝袜渲染,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了...
这篇文章给大家分享的是有关Unity插件OVRLipSync有什么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。项目需要接入对话口型动...
这篇文章主要介绍了Unity性能优化之DrawCall的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家...
这篇文章给大家分享的是有关Unity给力插件之Final IK怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。这插件有什么用:一般游...
这篇文章给大家分享的是有关Unity中如何内嵌网页插件UniWebView的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、常见Unity中内...
小编给大家分享一下Unity如何做流体物理的几个轮子,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让...
小编给大家分享一下Unity中Lod和Occlusion Culling的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收...
这篇文章将为大家详细讲解有关Unity中LineRenderer与TrailRenderer有什么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获...
这篇文章主要介绍了Unity中coroutine问题的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起...
这篇文章将为大家详细讲解有关unity中spine怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。骨骼动画首先我们来看到...
这篇文章主要为大家展示了“Unity Shader后处理中如何实现简单均值模糊”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学...