Prediction Culling
概述
預測揀選在遊戲中使用的時機是,當玩家在任何時刻時只有遊戲世界的一部分檢視的時候。它使用上很安全,並且很容易啟用。
預測揀選 允許在Quantum預測及復原階段時節省CPU時間。啟用它之後將允許預測工具來專門為本機玩家的重要及可見的實體來運行,而在伺服器確認輸入之後,檢視之外的任何內容在每次刷新時只模擬一次;因此盡可能地避免復原。
雖然性能效益隨著遊戲而異,它們可能相當大;您有越多的玩家,這對於您而言更為重要,因為預測程式最終將至少錯過他們其中之一。
以30赫茲模擬率運行的遊戲為例。如果遊戲要求每個已確認的輸入平均有十個刷新復原,這意味著遊戲模擬將必須要足夠輕量,才能以接近300赫茲來運行(包含復原)。使用 預測揀選,將始終以預期的30/60赫茲來模擬全幀,並且揀選將應用於預測緩衝區內的預測區域。
設定預測揀選
作為 預測揀選 的結果,這意味著已預測模擬永遠不會被接受為幀的最終結果,這是因為它的一部分被揀選,因此它永遠不會推進整個遊戲狀態的模擬。
為了設定預測揀選,有兩個步驟;一個在Quantum中以及一個在Unity中。
在Quantum中
在Quantum中啟用預測揀選非常簡單,只需在其他任何系統之前,將揀選系統新增到SystemSetup.cs
。
C#
namespace Quantum {
public static class SystemSetup {
public static SystemBase[] CreateSystems(RuntimeConfig gameConfig, SimulationConfig simulationConfig) {
return new SystemBase[] {
// pre-defined core systems
new Core.CullingSystem2D(),
new Core.CullingSystem3D(),
new Core.PhysicsSystem2D(),
new Core.PhysicsSystem3D(),
new Core.NavigationSystem(),
new Core.EntityPrototypeSystem(),
// user systems go here
};
}
}
}
預設下,Core.CullingSystem2D()
及Core.CullingSystem3D()
都被包含在SystemSetup
之中。
在Unity中
在Unity中,您需要設定預測區域。這將用於決定從預測來揀選的實體。
您可以透過在每個Unity更新上調用SetPredictionArea()
來更新預測區域:
C#
// center is either FPVector2 or FPVector3
// radius is an FP
QuantumRunner.Default.Game.SetPredictionArea(center, radius);
哪些值得期待
物理及導航網格代理
物理引擎及導航網格相關的系統將受到 預測揀選 的影響。
當啟用 預測揀選,它們將只考慮及更新未驗證(也就是已預測)幀上的可見區域內的實體。
由於物理及導航網格相關的代理跳過了附有相關元件(物理碰撞器、物理主體、導航網格路徑尋找器、導航網格轉向代理、導航網格迴避代理)的任何實體的更新,並且位於本機機器上的預測區域中心點和半徑所定義的感興趣的區域之外,因而節省了CPU週期。
迭代器
您自己的程式碼也將受益於 預測揀選。任何包含一個Transform2D
或Transform3D
的篩選器,將基於它們的位置而受到揀選。
基本上而言,不論一個預測幀在何時運行,調用以下任何方法將只會傳回在預測半徑的限制之內的實體,而在輸入確認到達之後模擬已驗證幀時,同樣的調用將傳回所有啟用中的執行個體)。
f.Filter()
f.Unsafe.FilterStruct()
請注意: 雖然 篩選器 受益於 預測揀選, 元件迭代器 並未受益。
f.GetComponentIterator()
f.Unsafe.GetComponentBlockIterator()
手動揀選控制旗標
也可能手動地 旗標標識 實體,來透過幀所提供的API,在已驗證幀上揀選。
方法 | 說明 |
---|---|
設定可揀選(EntityRef實體參照,布林值可揀選—) | 如果實體參照是無效的或實體不存在的話,則不做任何事情。 |
被揀選(EntityRef實體參照) | 傳回布林值
真 = 如果實體是可揀選,並且在揀選區域之內,無論幀狀態為何 偽 = 實體並未正在被揀選,實體不存在,或實體參照是無效的 |
已揀選(EntiyRef實體參照) | 傳回布林值
真 = 實體是可揀選,並且正在這個幀被揀選 False = 如果上述的兩個條件的其中之一沒有被滿足 |
揀選(EntiyRef實體參照) | 針對這個刷新來手動地揀選一個實體 |
清除已揀選狀態() | 在該幀上重新設定所有實體的揀選狀態 |
為了保持一個一致性的狀態,並且避免取消同步,在您最初以旗標標識的被揀選的實體的同樣系統中的已驗證幀上,取消旗標標識 被揀選的實體。來自同樣的系統,所以您保持一個一致性的狀態,並且不會取消同步。
避免RNG問題
使用 RNG工作階段 執行個體搭配 預測揀選 是完全安全的,並且確保了確定性。然而,當兩個實體共享一個 RNG工作階段 時,它們的結合使用可能會導致一些視覺上的抖動,比如儲存在Quantum的_globals_
中的預設情形。這是因為在模擬一個 已驗證 幀之後,針對一個 已預測 實體,生成新的一個RNG值,因此更改/修改了實體的最終位置。
解決方案是在各個需要進行揀選的實體中,儲存一個隔離式的RNG工作階段架構。這個隔離確保了揀選將不會影響已預測實體的最終位置,除非是復原實際上需要它。
chsarp
struct SomeStruct {
RNGSession MyRNG;
}
您可以以您需要的方法,將各個RNG工作階段的種子插入它們之中。
Back to top