2021年9月29日 星期三

微头条丨Unity中的协程

时间:2023-05-16 21:06:47来源 : 哔哩哔哩

协程

WunderMinibar — 让玩变得奇妙吧!


(资料图)

这次要讲的是一个非常有趣的玩意儿,那就是传说中的【协程 Coroutine】。其实在现实生活中我们也有类似协程的概念

可能你会说,携程谁不知道啊,不就是哪个用来订机票订酒店的软件么,这有什么好学的!这样的话你就错了,此协程非彼携程,可不要傻傻分不清楚喽!

来吧,和我一起进入奇妙的世界。

生活中的协程

阿伟不会用协程打电动

今天,阿伟在家打电动玩游戏 "弱诶,拜托你很弱诶!" “现在知道谁才是老大喔” "......"

......

他的阿妈从房间出来看到你又在玩游戏于是说道:"阿伟你又在打电动喔~休息一下吧,看看书好不好"

这时阿伟也在听阿妈的话,但还是玩游戏重要一些。

"烦捏" 阿伟心不在焉的说。

“我在跟你讲话你有没有听到?” 阿妈说。

"你不要烦好不好~" 阿伟不耐烦的说道。

”我才讲你两句,你就说我烦“ 阿妈生气道。

”我只希望你能够好好用功读书,整天就看到你在这打电动“ 阿妈继续说。

”豁~ 死了啦,都你害的,拜托~“阿伟生气的离开了家。

......

这时阿伟和阿妈就产生矛盾了,阿伟也有因此出门离家遇到了杰哥。那我们来帮助阿伟避免产生矛盾,避免遇上杰哥吧。

用协程帮助阿伟打电动

为了不产生矛盾,阿伟想在家里同时玩游戏和学习,但阿妈经常会打扰他,并强烈要求他只专注于学习。为了避免与阿妈的争吵,我们决定使用协程来管理他的学习和游戏时间。

他使用在每隔一段时间自动暂停游戏(阿妈进来查房了),并切换到学习模式,以满足阿妈的期望(阿妈满意离开),然后再返回游戏模式。

这样阿伟既可以享受游戏,也能够专注于学习,同时避免与阿妈的矛盾,也不会出门遇上杰哥了。

这里就有了协程的概念了 ===> "一心二用"。

“一心二用”的协程

“ 阿伟玩游戏,停下一段时间,这段时间去写作业,随后又恢复玩游戏状态。” 这就是传说中的【协程】。

我们的阿伟可以在玩游戏和学习之间轻松切换,并且在各个任务之间没有任何明显的暂停或阻塞。

既然阿伟已经学会了现实生活怎么使用协程来享受游戏又能学习,那我们来用协程代码实现一下吧....

代码中的协程

在代码中:

协程是一种让程序在某个点暂停执行,然后在稍后的时间点继续执行的方法,这种方式可以避免在等待某些操作完成时浪费计算资源。

首先我们要理解做一件事,上面阿伟“即学习又玩游戏” 这个事的逻辑不是说只能用协程代码实现的。而我们用协程的原因是避免浪费计算资源。

虽然不是很严谨,但我们可以把Start函数类似看成一天的开始。程序开始执行了:

起床了开始一天的工作开始了

阿伟起床了,他要去刷牙了

刷完牙后阿伟去吃饭了

吃完饭了阿伟开始写作业了

我们的阿妈每10秒查一次房,查一次房10秒钟。阿伟捉到规律之后,利用发现只要查房的10秒学习,阿妈走后10秒钟空档期玩游戏就能 充分的管理时间,即能好好学习又能充分娱乐,简直时间管理大师。

阿伟是个人要呼吸的,我们给他加入点现实元素让阿伟生动一些吧。

这里的update函数我们可以看成每时每刻都在做的事情(其实是不严谨的,Unity的生命周期函数Start在Update前执行)

于是我们得出了完整的代码逻辑 起床-> 刷牙->吃饭->学习和玩游戏 呼吸穿插其中,总结得出整体代码:

来看看阿伟的学习情况吧,阿妈每10秒查一次房,我们看到阿伟在玩10秒游戏后又学习10秒,这样就完美避开了阿妈的逮捕。同时不影响阿伟呼吸,也有时间呼吸不至于被缺少氧气窒息了。

这里可以看到协程中有重要的东西就是 yield return XXX的。

“啊!看不懂这什么玩意儿啊?” “写的什么乱七八糟的?”

别急吖~ 让我给你细细道来。

yield return

这个yield return xxx 就是将协程暂时挂起,暂停运行。我们的阿妈查房10秒钟,这时候阿伟需要切换学习状态保持10秒钟,就可以躲避啦。这10秒钟阿伟也是可以呼吸的,不影响其他呼吸等主线程的运行。

所以看这个 yield return 就相当于这行下面的代码都不执行了,“什么时候执行呢?”得看return后面的内容咯

阿伟是yield return new WaitForSeconds(10f); 这个意思是10秒钟后再执行。那么阿伟这10秒内就在呼吸和玩游戏或者学习啦。

我们来看看Unity官方对协程的定义:

A coroutine is like a function that has the ability to pause execution and return control to Unity but then to continue where it left off on the following frame. In C#, a coroutine is declared like this:

It is essentially a function declared with a return type of IEnumerator and with the yield return statement included somewhere in the body. The yield return null line is the point at which execution will pause and be resumed the following frame. To set a coroutine running, you need to use the StartCoroutine function:

By default, a coroutine is resumed on the frame after it yields but it is also possible to introduce a time delay using WaitForSeconds:

简单的说,协程就是一种特殊的函数,用StartCoroutine()开启。它可以主动的请求暂停自身并提交一个唤醒条件,Unity会在唤醒条件满足的时候去重新唤醒协程。

用StartCoroutine()开启协程,用 yield return xxx 暂停协程运行(也叫挂起)。

通常用最多的就是 yield return null就是让协程暂停一帧,下帧继续执行后面代码。

既然我们已经明白协程了,那我们来做点奇妙的事吧。

淡入淡出动画

现在这个场景还没有淡入淡出效果很单调,用户不喜欢

我们来做一下场景切换有渐变的效果吧。

当我们不使用协程时会出现错误的

这段代码很简单:在函数内些一个循环体,让渲染对象的alpha值不断下降趋近目标值。但是函数被调用完成后才返回的,这个函数的一切逻辑都是在一瞬间完成。

也就是说,上述Fade函数的alpha值会在一瞬间变为目标值,如果调用这样的函数,那么我们将会看到场景切换是一瞬间切换,而不是淡入淡出。

要解决也很简单,我们只要使用协程即可

从而 达到 我们想要的 淡入淡出的效果啦!

结尾

非常感谢你能看到这里,我们尽量通过一个小故事简洁阐述了协程的应用场景和意义。

协程能运用的场景还有很多,比如打字机效果、异步加载、定时器等等。

要是你对这些都非常感兴趣赶紧动起来吧,拿起键盘,开始你的游戏开发之旅吧。

这里有一个哔哩哔哩up出的视频教程--->打字机效果<---赶紧动起来吧~

最后的最后

最后让我宣传一下我们的Wunderminibar微信公众号吧,我们会在公众号发表有趣的文章呢!

奇妙小作坊 —— 让玩变得更加奇妙!

关键词:

(责任编辑:黄俊飞)

推荐内容

Back to Top