unity 下一帧执行_理解Unity中的优化(三):协程(Coroutines)
Coroutines:
Coroutines與其他腳本代碼的執(zhí)行方式不同。在性能分析中,大多數的腳本代碼只會在Unity的生命周期方法下出現一次。但是協(xié)程總是會在兩個地方出現。
在性能分析中,Coroutines中所有從協(xié)程開始到第一個yield中的代碼,都會出現在協(xié)程出現的地方。通常,它會在StartCoroutine的方法中出現。由Unity回調產生的Coroutines(例如Start回調返回一個IEnumerator),首先會出現在各自的回調中。
協(xié)程中剩余的代碼(從第一次恢復到完成執(zhí)行),會出現在Unity的主循環(huán),DelayedCallManager方法中。
要理解為什么出現這種情況,就需要理解協(xié)程實際上是怎么執(zhí)行的:
協(xié)程運行時,C#編譯器會自動生成一個類。這個類會在多個調用中,追蹤Coroutine的狀態(tài)。對于局部變量,由于協(xié)程中的局部變量在yield后也必須存在,所以這些局部變量會被封裝到生成類里面。在協(xié)程執(zhí)行期間,這些變量就會在托管堆中持續(xù)存在。這個對象也會追蹤協(xié)程的內部狀態(tài):它會記錄在yield之后,協(xié)程會在什么時候繼續(xù)執(zhí)行。
正因為如此,啟動一個coroutine的內存開銷等于一個固定的開銷成本加上它的局部變量的開銷。
開始調用一個協(xié)程的代碼,在協(xié)程滿足yield條件時,Unity會通過DelayedCallManager再次調用它們。因為協(xié)程有時候是被另一個協(xié)程調用的,這時候它們的開銷就是上述兩個被拆分的開銷。
在上述的截圖中,我們可以看到,DelayedCallManager執(zhí)行執(zhí)行了幾個協(xié)程,PopulateCharacters, AsyncLoad 和LoadDatabase。
在可能的情況下,最好在單個協(xié)程中執(zhí)行一系列的操作,雖然在代碼的清晰度和可維護方面,嵌套調用的協(xié)程比較好,但由于需要追蹤對象,嵌套調用將會花費更高的內存。
如果,一個協(xié)程每幀都會被執(zhí)行, 并且在長時間的操作中沒有yield語句。那么最好把里面的代碼放到Update或者LateUpdate中。
當一個對象被設置成disable時,協(xié)程不會停止,只有當對象被destroy時,才會停止。就是說,disable一個對象時,協(xié)程仍然在運行,需要的話,可以在協(xié)程中enable這個對象。調用Destroy(this)會立即觸發(fā)OnDisable回調,同時,協(xié)程也會被停止。最后,在最后一幀會調用OnDestroy方法。
協(xié)程不是線程,記住這個很重要。協(xié)程中的操作依舊運行在主線程上。如果在優(yōu)化的目標是減少CPU在主線程上話費的時間,那么在協(xié)程中避免出現一些阻塞的操作跟在其他代碼中避免出現一樣重要。
當然,當我們需要執(zhí)行一些例如Http傳輸、Asset加載或者文件I/O操作這類長時間的異步操作時,最好使用協(xié)程。
本文內容來自Unity官方文檔:
Unity - Manual: Coroutines?docs.unity3d.com作者水平有限,如有錯誤請多加指正。
總結
以上是生活随笔為你收集整理的unity 下一帧执行_理解Unity中的优化(三):协程(Coroutines)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 枣树根的功效与作用、禁忌和食用方法
- 下一篇: sessionlistener方法中获取