Unity StartCoroutine 和 yield return 深刻研究

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

是吧?不知道你什麼感受,反正我以爲,仍是須要深刻研究一下的。OK,here we go!函數

 

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

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

StartCoroutine通常都會當即返回,然而你也能夠得到返回結果的值。可是這一步會等到協程結束執行才能生效。3d

 

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

運行結果是:協程

start1htm

test1blog

start2get

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!

相關文章
相關標籤/搜索