Unity 的游戲循環機制
在 Unity 中,游戲的運行是基于幀的。每一幀都遵循固定的執行順序:
處理輸入
執行游戲邏輯?(包括 Update、FixedUpdate 和協程)
渲染場景
顯示幀
為什么?GameTime.time
?在同一幀內不變
GameTime.time
?是只讀屬性:
它返回的是當前幀開始時刻的時間戳
在同一幀的所有代碼執行過程中,這個值保持不變
只有在下一幀開始時,Unity 引擎才會更新這個值
代碼執行與時間推進的關系:
您的代碼是在一幀內的「執行游戲邏輯」階段運行的
在這一階段,時間還沒有「推進」,
GameTime.time
?保持固定只有當這一幀完全結束,進入下一幀時,時間才會更新
舉例說明Bug
while (GameTime.time - begin <= 0.03f) // 條件永遠為 true
{var lerp = (GameTime.time - begin) / 0.03f; // 永遠是 0/0.03 = 0yMouse = Mathf.Lerp(_y_mouse, cameraConfig.y_mouse, lerp); // 永遠是起始值distanceFromTarget = Mathf.Lerp(...); // 同上// 沒有 yield return,循環繼續立即執行下一輪// GameTime.time 仍然是 10.0,因為還在同一幀
}
在第一輪計算:
GameTime.time - begin = 0
?≤ 0.03 → 繼續在第二輪計算:
GameTime.time - begin = 0
?≤ 0.03 → 繼續在第三輪計算:
GameTime.time - begin = 0
?≤ 0.03 → 繼續...無限循環,因為?
GameTime.time
?不會改變
? ? ? ? 為什么這一幀始終無法進入下一幀?
? ? ? ? 1、首先我們要知道——Unity是幀更新機制,包括GameTime.time
? ? ? ? 2、又因為GameTime.Time需要下一幀進行更新,但GameTime.Time又作為循環條件,這一幀的內容始終在While循環中
使用協程方法yield return new WaitForEndOfFrame
的原因
為什么?
yield return
?能解決這個問題
yield return new WaitForEndOfFrame()
?的作用是:
暫停當前協程的執行
允許當前幀完成(完成渲染等所有操作)
在下一幀繼續執行協程
此時?
GameTime.time
?已經更新為下一幀開始的時間所以,有了?
yield return
:
第1幀:執行一次循環,然后暫停
第2幀:
GameTime.time
?已更新,再次執行循環第3幀:
GameTime.time
?再次更新,可能已經超過 0.03 秒,循環結束
之后的話題:如何理解一幀的內容
這一幀的內容為什么是while循環,還有其他代碼屬于這一幀的內容嗎,如何判斷哪些代碼屬于一個幀內的?
如何判斷哪些代碼屬于同一個幀?
有一個非常簡單的判斷原則:所有在同一個“游戲邏輯處理階段”被連續調用的代碼,都屬于同一幀。
更具體地說,在Unity的主循環中,一幀內按順序會發生很多事,下圖清晰地展示了這一流程以及您的代碼是如何被嵌入執行的: