Player
概述
Player
(Player
指令碼,Player
預製件)代表遊戲中連線的同儕節點,沒有視覺效果。玩家提供對通用中繼資料的存取權限-使用者帳號、暱稱、所選角色和其他資料,這些資料應該在Agent
(遊戲世界中產生的視覺表示)重新生成後仍然存在。
Agent
(Agent
指令碼、AgentBase
預製件,及其變體)代表由玩家控制的遊戲中角色。它由GameplayMode
生成,具有Health
、Weapons
和其他元件。角色會根據需要被生成和取消生成。
下圖將元件層次結構顯示為執行瀑布圖:
輸入處理
下圖說明了動作的處理輸入和執行:
注意事項:
Frame
:Unity幀編號(UnityEngine.Time.frameCount
)。為了更好的可讀性,幀101和102是不完整的。- 在每幀開始時,來自裝置的輸入被收集在
ProcessFrameInput()
中,並寫入到Render Input
資料結構(僅限輸入授權) - 相同的輸入也被累積到
Accumulated Input
(例如,查看旋轉差量)中 - 如果累積的差量時間大到足以模擬下一個固定的刷新(幀103):
Accumulated Input
透過NetworkEvents.OnInput()
回調進行輪詢/消耗- 玩家輸入在
BeforeTick()
中從Fusion讀取,並存儲在Fixed Input
中(根據輸入和狀態授權執行) AgentInput.FixedUpdateNetwork()
調用被轉發到Agent.EarlyFixedUpdateNetwork()
,其使用Fixed Input
來處理移動。這確保了所有代理在任何人在當前模擬刷新中開始射擊之前移動Agent.FixedUpdateNetwork()
讀取Fixed Input
並處理射擊AgentInput.Render()
調用被轉發到Agent.EarlyRender()
,其使用Render Input
(也可以使用Accumulated Input
)來處理轉譯預測的移動和查看旋轉。Agent.Render()
不處理轉譯預測射擊的輸入,因為它不在此範例的範圍內。射擊只在固定模擬中進行。
- 如果累積的差量時間不足以模擬下一個固定刷新(幀101、102)
AgentInput.Render()
調用被轉發到Agent.EarlyRender()
(為了更好的可讀性,未在上圖中顯示),其使用Render Input
(也可以使用Accumulated Input
)來處理轉譯預測的移動和查看旋轉。
此圖是一個簡化版本,並沒有涵蓋所有邊緣情況。有關更多詳細資訊,請查看檔案程式碼。
查看旋轉平滑
BR200配備了一個自訂解決方案,可在任何條件下實現流暢的查看旋轉。
以下日誌說明了使用普通硬體(滑鼠以125Hz的速率輪詢)和高轉譯/輸出刷新率(200+ FPS)時原始輸入的混疊問題。無論CPU/GPU有多好,轉譯輸出總是會感到抖動。
為了解決這個問題,輸入值用時間戳記來記錄,然後將當前幀的值計算為定義的時間跨度的平均值(BR200預設使用25ms窗口)。這帶來奶油般絲滑的感知體驗(尤其是在高刷新率顯示器上),但引入了非常小的輸入延遲。使用取樣速率較高的硬體可以將平滑窗口減少到最小值。
下圖顯示了 原始 滑鼠差量(底限)和角色查看旋轉(上限)的時間:
下圖顯示了 平滑 滑鼠差量(底限)和角色查看旋轉(上限)的時間:
這也有助於減少取樣誤差(桌面表面)和由手/滑鼠不均勻運動(桌面摩擦、肌肉)引起的微抖動。
角色動畫
專案具有基於可遊玩API的自訂動畫控制器執行方式。它提供了對刷新準確動畫評估和動態效能縮放的支持。
下圖顯示了類似於Mecanim
的結構:
在代理的物件層次結構中設定動畫層和狀態:
動畫層:
Locomotion
:移動的基礎全身層FullBody
:覆蓋全身動作的層,與運動混合LowerBody
:覆蓋下半身角色翻轉的層UpperBody
:覆蓋上半身動作的層,通常與運動混合Shoot
:覆蓋手部動作(射擊)的層,通常與運動混合Look
:額外的上半身的層,用於看上看下
根據動畫控制器的複雜性,評估200名玩家很容易成為伺服器上的瓶頸。為了獲得更好的效能,伺服器允許基於連線的玩家數量,每隔n幀進行交錯的PlayableGraph
評估。所有重要屬性(如圖層或狀態權重)仍會在每幀中進行計算。下表顯示了交錯評估的規則。
已連線玩家 | 可遊玩圖表評估 |
---|---|
> 150 | 每隔6幀 |
> 100 | 每隔4幀 |
> 50 | 每隔2幀 |
其他 | 每幀 |
角色控制器
此範例使用Fusion KCC(一種高級運動學角色控制器附加元件)進行移動。它是一個通用的低級別角色控制器,主要關注效能、遊戲互動和客製化。
Fusion KCC特色:
- 控制位置和查看旋轉(俯仰+轉頭)
- 膠囊碰撞器定義的形狀
- 本機玩家的預測轉譯移動
- 基於速度的動態(類似物理學)和運動學(非現實的)組合移動
- 外力-來自爆炸、移動平台…
- 移動加速度和摩擦力
- 用於客製化的高級KCC處理器流程(速度和方向覆寫、阻擋)
- 預設屬性(半徑、高度、質量等)的開箱即用網路同步,其他屬性的可選同步
- 自訂碰撞器篩選和忽略清單
- CCD(連續碰撞檢測)
- 碰撞回調
- 支援地面貼齊和台階高度
- 支援本機模式(無網路流量)
- 網路與效能最佳化
- 獨立於平台,便於使用行動裝置
- 對逐幀偵錯編輯器繪圖和日誌記錄的基本支援
當玩家的生命值低於某個閾值,並且該玩家當前已退出戰鬥時,自動治療開始生效,並開始補充該玩家的生命。
噴射背包
噴射背包提供了在水平面上飛行和快速導航的能力,同時排出燃料。可以透過拾取物品箱中的燃料罐來補充燃料。
噴射背包的狀態由Jetpack
指令碼處理,該指令碼處理燃料消耗、螺旋槳、聲音和打開/關閉狀態。空氣中的實際移動由JetpackKCCProcessor
處理。此指令碼覆寫KCC速度並抑制預設行為。
觀眾模式
當玩家被淘汰或加入遊戲太遲時,他們將進入觀眾模式。在觀眾模式下,玩家可以從其他玩家的角度觀察比賽。在程式碼中,這實際上處理得很簡單。相機和UI基於SceneContext
中指派的ObservedAgent
進行操作。ObservedAgent
可以是本機玩家代理,也可以是觀戰玩家代理。