Unity StartCoroutine 和 yield return 深入研究


StartCoroutine和yield return表面意思很好理解,StartCoroutine就是開啟一個協程,yield return 是迭代器塊返回調用迭代的地方。

是吧?不知道你什么感覺,反正我覺得,還是需要深入研究一下的。OK,here we go!

 

首先,先看一下StartCoroutine在Unity官方的解釋。

意思是:一個協程的執行可以在任何地方用yield語句來暫停,yield return的值決定了什么時候協程恢復執行。協程在協調在幾幀中執行的操作時有極大的用處.協程幾乎沒有任何性能開銷。

StartCoroutine一般都會立即返回,然而你也可以獲得返回結果的值。但是這一步會等到協程結束執行才能生效。

 

OK,意思應該不難理解,根據他的意思我們來分析一段程序。

運行結果是:

start1

test1

start2

test2

 

這下就一目了然了,當StartCoroutine剛調用的時候,可以理解為正常的函數調用,然后接着看調用的函數里面。

當被調用函數執行到yield return null;(暫停協程,等待下一幀繼續執行)時,根據Unity解釋協同程序就會被暫停,其實我個人認為他這個解釋不夠精確,先返回開始協程的地方,然后再暫停協程。也就是先通知調用處,“你先走吧,不用管我”,然后再暫停協程。。怎么?不信?那我們再寫個demo驗證一下。

執行結果:

start1

test1

start2

test2  (這個test2是等待三秒后才打印出來的)

 

正好順便驗證了“yield return的值決定了什么時候協程恢復執行”這句,其實yield return后面的值可以后很多用法,可以看這個帖子:http://blog.sina.com.cn/s/blog_aaa4ce8d010131kr.html

其實再回過頭來想想,協程->協同程序->其實就是協同兩個任務,表面看起來很簡單,但是在一些稍微大點的項目中用起來,對於新手來說還是會有些晦澀。。。

比如說

    IEnumerator Init()
    {
        yield return StartCoroutine(init1());
        Debug.Log("init1 finish");
        yield return StartCoroutine(init2());
        Debug.Log("init2 finish");
        yield return StartCoroutine(init3());
        Debug.Log("init3 finish");
    }

    IEnumerator init1()
    {
        // 模擬初始化
        yield return new WaitForSeconds(2);//
    }
    IEnumerator init2()
    {
        // do somthing..
        yield return new WaitForSeconds(2);//
    }
    IEnumerator init2()
    {
        // do somthing..
        yield return new WaitForSeconds(2);//
    }

其實就是一個執行順序的問題,這樣調用能保證,init1,init2,init3一個一個的執行,不至於出現后面執行的代碼引用一個前面未初始化的變量。。。

那么,接着這個執行順序的話題,我們在來研究一個話題,看下面代碼

    void Start () {
        Debug.Log("start1");
        StartCoroutine(Test());
        Debug.Log("start2");
    }

    IEnumerator Test()
    {
        Debug.Log("test1");
        yield return StartCoroutine(DoSomething());
        Debug.Log("test2");
    }

    IEnumerator DoSomething()
    {
        Debug.Log("load 1");
        yield return null;
        Debug.Log("load 2");
    }

執行結果:

start1

test1

load1

start2

load2

test2

這種StartCoroutine中嵌套一個yield return StartCoroutine,第一個StartCoroutine會等到第二個StartCoroutine中所有代碼結束后再繼續執行,而第二個StartCoroutine中的yield語句會先返回第一個,然后立即返回他的調用處,也就是調用處會繼續執行,而第一個StartCoroutine會等待第二個執行完再繼續執行。

如果還想繼續深入,可以看一下C#中的迭代器,那里面說明了yield和IEnumerator根本到底是什么。

OK,今天就說到這。Good Luck!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM