Unity中的協(xié)程

協(xié)程
WunderMinibar — 讓玩變得奇妙吧!
這次要講的是一個非常有趣的玩意兒,那就是傳說中的【協(xié)程 Coroutine】。其實在現(xiàn)實生活中我們也有類似協(xié)程的概念
可能你會說,攜程誰不知道啊,不就是哪個用來訂機票訂酒店的軟件么,這有什么好學的!這樣的話你就錯了,此協(xié)程非彼攜程,可不要傻傻分不清楚嘍!
來吧,和我一起進入奇妙的世界。

生活中的協(xié)程
阿偉不會用協(xié)程打電動
今天,阿偉在家打電動玩游戲 "弱誒,拜托你很弱誒!" “現(xiàn)在知道誰才是老大喔” "......"
......
他的阿媽從房間出來看到你又在玩游戲于是說道:"阿偉你又在打電動喔~休息一下吧,看看書好不好"
這時阿偉也在聽阿媽的話,但還是玩游戲重要一些。
"煩捏" 阿偉心不在焉的說。
“我在跟你講話你有沒有聽到?” 阿媽說。
"你不要煩好不好~" 阿偉不耐煩的說道。
”我才講你兩句,你就說我煩“ 阿媽生氣道。
”我只希望你能夠好好用功讀書,整天就看到你在這打電動“ 阿媽繼續(xù)說。
”豁~ 死了啦,都你害的,拜托~“阿偉生氣的離開了家。
......
這時阿偉和阿媽就產(chǎn)生矛盾了,阿偉也有因此出門離家遇到了杰哥。那我們來幫助阿偉避免產(chǎn)生矛盾,避免遇上杰哥吧。
用協(xié)程幫助阿偉打電動
為了不產(chǎn)生矛盾,阿偉想在家里同時玩游戲和學習,但阿媽經(jīng)常會打擾他,并強烈要求他只專注于學習。為了避免與阿媽的爭吵,我們決定使用協(xié)程來管理他的學習和游戲時間。
他使用在每隔一段時間自動暫停游戲(阿媽進來查房了),并切換到學習模式,以滿足阿媽的期望(阿媽滿意離開),然后再返回游戲模式。
這樣阿偉既可以享受游戲,也能夠?qū)W⒂趯W習,同時避免與阿媽的矛盾,也不會出門遇上杰哥了。
這里就有了協(xié)程的概念了 ===>?"一心二用"。

“一心二用”的協(xié)程
“ 阿偉玩游戲,停下一段時間,這段時間去寫作業(yè),隨后又恢復(fù)玩游戲狀態(tài)?!?這就是傳說中的【協(xié)程】。
我們的阿偉可以在玩游戲和學習之間輕松切換,并且在各個任務(wù)之間沒有任何明顯的暫停或阻塞。
既然阿偉已經(jīng)學會了現(xiàn)實生活怎么使用協(xié)程來享受游戲又能學習,那我們來用協(xié)程代碼實現(xiàn)一下吧....
代碼中的協(xié)程
在代碼中:
協(xié)程是一種讓程序在某個點暫停執(zhí)行,然后在稍后的時間點繼續(xù)執(zhí)行的方法,這種方式可以避免在等待某些操作完成時浪費計算資源。
首先我們要理解做一件事,上面阿偉“即學習又玩游戲” 這個事的邏輯不是說只能用協(xié)程代碼實現(xiàn)的。而我們用協(xié)程的原因是避免浪費計算資源。
雖然不是很嚴謹,但我們可以把Start函數(shù)類似看成一天的開始。程序開始執(zhí)行了:
起床了開始一天的工作開始了
阿偉起床了,他要去刷牙了
刷完牙后阿偉去吃飯了
吃完飯了阿偉開始寫作業(yè)了
我們的阿媽每10秒查一次房,查一次房10秒鐘。阿偉捉到規(guī)律之后,利用發(fā)現(xiàn)只要查房的10秒學習,阿媽走后10秒鐘空檔期玩游戲就能 充分的管理時間,即能好好學習又能充分娛樂,簡直時間管理大師。
阿偉是個人要呼吸的,我們給他加入點現(xiàn)實元素讓阿偉生動一些吧。
這里的update函數(shù)我們可以看成每時每刻都在做的事情(其實是不嚴謹?shù)?,Unity的生命周期函數(shù)Start在Update前執(zhí)行)
于是我們得出了完整的代碼邏輯 起床-> 刷牙->吃飯->學習和玩游戲 呼吸穿插其中,總結(jié)得出整體代碼:
來看看阿偉的學習情況吧,阿媽每10秒查一次房,我們看到阿偉在玩10秒游戲后又學習10秒,這樣就完美避開了阿媽的逮捕。同時不影響阿偉呼吸,也有時間呼吸不至于被缺少氧氣窒息了。
這里可以看到協(xié)程中有重要的東西就是 yield return XXX的。
“??!看不懂這什么玩意兒???” “寫的什么亂七八糟的?”
別急吖~ 讓我給你細細道來。
yield return
這個yield return xxx 就是將協(xié)程暫時掛起,暫停運行。我們的阿媽查房10秒鐘,這時候阿偉需要切換學習狀態(tài)保持10秒鐘,就可以躲避啦。這10秒鐘阿偉也是可以呼吸的,不影響其他呼吸等主線程的運行。
所以看這個 yield return 就相當于這行下面的代碼都不執(zhí)行了,“什么時候執(zhí)行呢?”得看return后面的內(nèi)容咯
阿偉是yield return new WaitForSeconds(10f); 這個意思是10秒鐘后再執(zhí)行。那么阿偉這10秒內(nèi)就在呼吸和玩游戲或者學習啦。
我們來看看Unity官方對協(xié)程的定義:
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:
簡單的說,協(xié)程就是一種特殊的函數(shù),用StartCoroutine()開啟。它可以主動的請求暫停自身并提交一個喚醒條件,Unity會在喚醒條件滿足的時候去重新喚醒協(xié)程。
用StartCoroutine()開啟協(xié)程,用?yield return xxx?
暫停協(xié)程運行(也叫掛起)。
通常用最多的就是?yield return null
?就是讓協(xié)程暫停一幀,下幀繼續(xù)執(zhí)行后面代碼。
既然我們已經(jīng)明白協(xié)程了,那我們來做點奇妙的事吧。
淡入淡出動畫

現(xiàn)在這個場景還沒有淡入淡出效果很單調(diào),用戶不喜歡
我們來做一下場景切換有漸變的效果吧。
當我們不使用協(xié)程時會出現(xiàn)錯誤的
這段代碼很簡單:在函數(shù)內(nèi)些一個循環(huán)體,讓渲染對象的alpha值不斷下降趨近目標值。但是函數(shù)被調(diào)用完成后才返回的,這個函數(shù)的一切邏輯都是在一瞬間完成。
也就是說,上述Fade函數(shù)的alpha值會在一瞬間變?yōu)槟繕酥?,如果調(diào)用這樣的函數(shù),那么我們將會看到場景切換是一瞬間切換,而不是淡入淡出。
要解決也很簡單,我們只要使用協(xié)程即可

從而 達到 我們想要的 淡入淡出的效果啦!

結(jié)尾
非常感謝你能看到這里,我們盡量通過一個小故事簡潔闡述了協(xié)程的應(yīng)用場景和意義。
協(xié)程能運用的場景還有很多,比如打字機效果、異步加載、定時器等等。
要是你對這些都非常感興趣趕緊動起來吧,拿起鍵盤,開始你的游戲開發(fā)之旅吧。
這里有一個嗶哩嗶哩up出的視頻教程--->打字機效果<---趕緊動起來吧~
最后的最后
最后讓我宣傳一下我們的Wunderminibar微信公眾號吧,我們會在公眾號發(fā)表有趣的文章呢!
奇妙小作坊 —— 讓玩變得更加奇妙!
