unity協(xié)程(corounines)學(xué)習(xí)理解兼迭代器學(xué)習(xí),異步多任務(wù)處理
*本文原創(chuàng),表明來源可隨意轉(zhuǎn)載,主要是記錄自己在學(xué)習(xí)過程中遇到的問題,故不作為教程。如果有大佬愿意指導(dǎo)糾正,區(qū)區(qū)拜謝。
原文鏈接:https://blog.csdn.net/jubunihuan/article/details/129652810
一.協(xié)程學(xué)習(xí)的前置知識(shí)
迭代器
迭代器是一種用于簡化循環(huán)結(jié)構(gòu)的語法糖,它可以讓我們通過一種更加簡潔、優(yōu)雅的方式來遍歷一個(gè)集合或者執(zhí)行一些需要多次迭代的操作。
在Unity中,迭代器的基本語法是使用yield return語句。yield return語句用于暫停迭代器的執(zhí)行,并返回一個(gè)值或?qū)ο蟆?/p>
下面是一個(gè)使用迭代器的例子:
IEnumerator MyIterator() {
? ? Debug.Log("Start");
? ? yield return new WaitForSeconds(1.0f);
? ? Debug.Log("1 second later");
? ? yield return new WaitForSeconds(2.0f);
? ? Debug.Log("2 seconds later");
}
二.協(xié)程的入口
協(xié)程必須以IEnumerator開始,并且方法中必須包含關(guān)鍵字yield return,下面我們給出一個(gè)協(xié)程和普通程序的對(duì)比:
IEnumerator PrintDebug()
{
? ? Debug.Log(1);
? ? yield return 0;//暫時(shí)掛起程序
}
void PrintDebug()
{
? ? Debug.Log(1);
}
這時(shí)我們想要調(diào)用我們的協(xié)程就需要用到以下的代碼
StartCoroutine(PrintNum());
關(guān)鍵字yield return
yield return的作用是將我們的程序暫時(shí)掛起,滿足部分條件之后再執(zhí)行
下面是一些例子:
yield return null;//下一幀以后執(zhí)行后續(xù)代碼
yield return 0;//這里可以不是零,甚至可以是任意數(shù)字,效果同上
yield return StartCoroutine(MyCoroutine(1));//等待協(xié)程MyCoroutine(1)完成
yield return new WaitForSeconds(1); // 暫停協(xié)程1秒鐘,受到DeletaTime影響
yield return new WaitForSecondsRealtime(1);//不受到DeletaTime影響
yield return new WaitForFixedUpdate(); // 等待下一個(gè)FixedUpdate消息
yield return new WaitForEndOfFrame(); // 等待下一個(gè)渲染幀的結(jié)束
yield return new WaitUntil(() => oneSecond>1);//等到某判斷條件為真時(shí)
yield return new WaitWhile(() => oneSecond>1);//等到某判斷條件為假時(shí)
?
AsyncOperation async = SceneManager.LoadSceneAsync("SceneName");//暫停協(xié)程,異步場景加載
yield return async; // 等待場景加載完成
?
yield break;//直接終止,類似于return操作
不僅如此,你甚至能使用自定義的yield return,請(qǐng)看代碼
public class MyYieldInstruction : CustomYieldInstruction {
? ? private bool isFinished = false; // 是否完成的標(biāo)志位
?
? ? public override bool keepWaiting {
? ? ? ? get {
? ? ? ? ? ? return !isFinished; // 當(dāng)未完成時(shí),協(xié)程繼續(xù)等待
? ? ? ? }
? ? }
?
? ? public void Finish() {
? ? ? ? isFinished = true; // 設(shè)置完成標(biāo)志位
? ? }
}
眾所周知,自定義yield return類型需要滿足以下兩個(gè)條件:
1.繼承自Unity的CustomYieldInstruction類。
2.實(shí)現(xiàn)keepWaiting屬性,該屬性的返回值控制協(xié)程是否繼續(xù)等待。
在上面的示例中,MyYieldInstruction類繼承自CustomYieldInstruction類,并實(shí)現(xiàn)了keepWaiting屬性和Finish方法。在MyYieldInstruction類中,我們使用isFinished變量表示自定義的操作是否完成。在keepWaiting屬性中,當(dāng)isFinished為false時(shí),協(xié)程將繼續(xù)等待;當(dāng)isFinished為true時(shí),協(xié)程將不再等待,繼續(xù)執(zhí)行后面的代碼。
以下的代碼會(huì)告訴你該如何使用前面我們自定義的yield return
IEnumerator MyCoroutine() {
? ? Debug.Log("Start");
? ? MyYieldInstruction myYield = new MyYieldInstruction();
? ? yield return myYield;
? ? Debug.Log("Finish");
}
?
...
?
MyCoroutine coroutine = StartCoroutine(MyCoroutine());
coroutine.Stop(); // 可以通過Stop方法提前終止協(xié)程
值得注意的是,在使用自定義yield return類型時(shí),需要特別注意協(xié)程的終止條件,以避免出現(xiàn)不可預(yù)期的結(jié)果。
StartCoroutine語句
StartCoroutine(方法);
StartCoroutine(方法名);
StartCoroutine的返回值類型是IEnumerator
注意:StartCoroutine語句只能在MonoBehaviour派生類的方法中使用,因?yàn)閰f(xié)程依賴于Unity的消息循環(huán)機(jī)制。
三.協(xié)程的結(jié)束
StopCoroutine(方法);
StopAllCoroutine();
四.迭代器與協(xié)程的區(qū)別
迭代器(Iterator)和協(xié)程(Coroutine)在Unity中都用于異步操作,但它們?cè)趯?shí)現(xiàn)和使用上有一些區(qū)別。
1.實(shí)現(xiàn)方式不同
迭代器是一種基于枚舉器(Enumerator)實(shí)現(xiàn)的語法,通過yield return語句實(shí)現(xiàn)協(xié)程的暫停和恢復(fù)。在編寫迭代器時(shí),需要實(shí)現(xiàn)IEnumerator和IEnumerable接口,并實(shí)現(xiàn)MoveNext、Reset和Current等方法。
協(xié)程是一種基于IEnumerator實(shí)現(xiàn)的語法,通過StartCoroutine和yield return語句實(shí)現(xiàn)協(xié)程的啟動(dòng)和暫停。在編寫協(xié)程時(shí),需要定義一個(gè)返回值為IEnumerator類型的方法,并使用yield return語句來暫停協(xié)程的執(zhí)行。
2.使用方式不同
迭代器通常用于實(shí)現(xiàn)可枚舉類型的遍歷,可以通過foreach語句進(jìn)行遍歷操作。在協(xié)程中,迭代器通常用于實(shí)現(xiàn)異步操作,例如延遲執(zhí)行、動(dòng)畫效果等。
協(xié)程通常用于實(shí)現(xiàn)異步操作,可以通過StartCoroutine語句啟動(dòng)協(xié)程,并使用yield return語句實(shí)現(xiàn)協(xié)程的暫停和恢復(fù)。協(xié)程可以通過yield return語句實(shí)現(xiàn)延遲執(zhí)行、分步執(zhí)行、等待操作完成等功能。
3.執(zhí)行順序不同
迭代器的執(zhí)行順序是在同一線程中順序執(zhí)行,即在迭代器中的每個(gè)yield return語句執(zhí)行完畢后,才會(huì)執(zhí)行下一個(gè)yield return語句或方法的其他部分。
協(xié)程的執(zhí)行順序是異步的,即在協(xié)程執(zhí)行過程中可以執(zhí)行其他代碼。協(xié)程的執(zhí)行可以被暫停和恢復(fù),可以實(shí)現(xiàn)延遲執(zhí)行、動(dòng)畫效果、等待操作完成等功能。