2017-01-18 289 views
2

我目前正在嘗試理解IEnumerator & Unity內部的協同程序,對「yield return null」執行的內容不太置信。目前我相信它基本上會暫停並等待下一幀,並在下一幀中再次執行while語句。Unity - IEnumerator的yield返回null

如果我省略「yield return null」,看起來對象會立即移動到其目的地或可能「跳過很多幀」。所以我想我的問題是這個「yield return null」函數在這個while循環中是如何的,爲什麼它有必要擁有它。

void Start() { 
    StartCoroutine(Move()); 
} 

IEnumerator Move(){ 

    while (a > 0.5f){ 

     ... (moves object up/down) 

     yield return null; // <--------- 
    } 

    yield return new WaitForSeconds(0.5f); 

    .... (moves object up/down) 

    StartCoroutine(Move()); 
} 
+1

我對Coroutines本人並不熟悉,但我的猜測是他們會每幀運行一次(或者什麼東西),'yield return'基本上是說「等到下一次更新繼續」的快捷方式。如果你沒有它,while循環將一直運行到完成一次更新,這就是爲什麼沒有它的對象立即移動。 – Abion47

回答

5

程序將開始循環,如果您沒有收益率,它會在同一個框架內運行所有迭代。 如果你有數百萬次的迭代,那麼它很可能會阻止你的程序,直到所有的迭代完成,然後繼續。

創建協程時,Unity將其附加到MonoBehaviour對象。它將在StartCoroutine調用之前運行,直到獲得收益。然後它將從協程返回並根據產量將其放到堆棧上。如果爲空,那麼它將再次運行下一幀。如果某些協程需要在特定時刻執行操作,則可能需要WaitForEndOfFrame。在某些情況下,您可能會像在第二種情況下那樣啓動計時器。

此時,協程關閉,程序可以運行剩餘的程序。在下一幀中,Unity會發現堆疊的協程,並會從他們離開的地方調用它們。 如果你的循環永遠不會達到真實的條件,那麼你基本上創建了一個更新方法。

協程的目的是執行跨越一段時間而不會阻塞程序的操作。

重要事實:這不是多線程。

3

你是對的。 yield return null將等到下一幀,然後繼續執行。在你的情況下,它會檢查你的while循環的下一幀的條件。

「爲什麼這是必要的」可能是因爲您希望對象每幀輸入一個輸入。沒有yield return null它只是在一幀內通過while循環執行。

更重要的是:它看起來像你想Update每幀和調整psoition。您可以輕鬆使用Update()。這個函數將在活動腳本的每一幀被Unity調用。