先來看看使用協程的作用一共有兩點:
1)延時(等待)一段時間執行代碼;
2)等某個操作完成之後再執行後面的代碼。總結起來就是一句話:控制代碼在特定的時機執行。
協程不是線程,也不是異步執行的。協程和 MonoBehaviour 的 Update函數一樣也是在MainThread中執行的。使用協程你不用考慮同步和鎖的問題。
對於使用協程帶來GC問題,不推薦使用了!。
使用我之前封裝的 游戲簡單控制邏輯Clock類 可以完美解決
IEnumerator myAwesomeCoroutine() { while (true) { doAwesomeStuff(); yield return new WaitForSeconds(waitTime); } }
我想要指出的是使用 yield return new WaitForSeconds() 將會每幀導致垃圾分配GC,21個字節,由於new 部分(相對於標准的協程 yield return null只產生 9 個字節)。
若要避免此問題,只是提前設置你的wait 等待的時間......
WaitForSeconds shortWait = new WaitForSeconds(0.1f); WaitForSeconds longWait = new WaitForSeconds(5.0f); IEnumerator myEvenAwesomerCoroutine() { while (true) { if (iNeedToDoStuffFast) { doAwesomeStuffReallyFast(); yield return shortWait; } else{ dontDoMuch(); yield return longWait; } } }
現在你coroutine 協程每次調用只會引起最低 的9 字節 GC 分配 (不包括其他分配allocations,當然你可能通過您其他的代碼會導致 !)。
防止GC而做的事情的列表可能比較長。
- 不要使用Invoke或 StartCoroutine 的字符串。
- 不要使用GUILayout 和標記您的 GUI MonoBehaviour來防止每幀 800bytes的GC發生。 http://docs.unity3d.com/ScriptReference/MonoBehaviour-useGUILayout.html
- 不要使用 GameObject.Tag 或 GameObject.Name
- 不要在Update中使用GetComponent ,如果可能的話將其緩存
- 不要使用 foreach
- 不要使用string + ----》 StringBuild 或 string.Format()