2017/07/04修改 - 對WaitForEndOfFrame的LateUpdate時序進行說明。
測試結論:
1.如果只是等待下一幀執行,用yield return null即可。調用順序在Update后,LateUpdate前
2.如果有截屏需要,用WaitForEndOfFrame。具體參考官方例子。否則直接用Texture2D.ReadPixel抓取屏幕信息則會報錯。
3.此外,用WaitForEndOfFrame還可以讓代碼在LateUpdate的時序后調用。
測試1:
using UnityEngine; using System.Collections; using System.IO; public class Test1 : MonoBehaviour { void OnEnable() { StartCoroutine(ReturnNullTest()); StartCoroutine(ReturnWaitForEndOfFrame()); } IEnumerator ReturnNullTest() { Debug.Log("[1] ReturnNull Frame Count: " + Time.frameCount + "Render Frame Count: " + Time.renderedFrameCount); yield return null; Debug.Log("[2] ReturnNull Frame Count: " + Time.frameCount + "Render Frame Count: " + Time.renderedFrameCount); } IEnumerator ReturnWaitForEndOfFrame() { Debug.Log("[1] WaitForEndOfFrame Frame Count: " + Time.frameCount + "Render Frame Count: " + Time.renderedFrameCount); yield return new WaitForEndOfFrame(); Debug.Log("[2] WaitForEndOfFrame Frame Count: " + Time.frameCount + "Render Frame Count: " + Time.renderedFrameCount); } }
從測試順序來看,兩者都可以達到下一幀執行的目的
但WaitForEndOfFrame的渲染幀會多跳一幀
測試2:
先看一下官方的執行順序表
WaitForEndOfFrame會在一幀結束后調用,且在LateUpdate之后調用。
而正常yield return null的調用是在update之后,也就是說可以分別做到不同時序的調用。
測試腳本如下:
public class Test : MonoBehaviour { void Awake() { Debug.Log("0"); StartCoroutine(TestCoroutine()); Debug.Log("2"); } void Update() { Debug.Log("3 - Update"); } void LateUpdate() { Debug.Log("4 - LateUpdate"); } IEnumerator TestCoroutine() { Debug.Log("1"); yield return new WaitForEndOfFrame(); Debug.Log("5"); } }
結果:
不過對於靜態置於場景中調用時,會多經過一次Update和LateUpdate
起初以為是第0幀問題,但后來放在Start中執行依舊會多經過一次。
但動態加載的prefab則沒有該問題。