Lag Compensation
簡介
延遲補償解決了快節奏網路遊戲中的一個基本問題:允許客戶端獲得所見即所得的體驗,但又不能相信客戶端。
問題是網路上沒有一台機器在遊戲中處於完全相同的時間。一個客戶所看到的並基於他們的行動,對他們來說只是100%正確的。典型的例子是檢測對一個遠處物體的精確射擊;盡管客戶直接在十字準線上看到了目標,但實際上它已經移動了。
- 如果授權的伺服器只根據自己對世界的感知來進行命中檢測,那麼就不會有人故意擊中任何東西。
- 如果客戶端被允許擁有授權,並且可以告訴伺服器他們擊中了什麼,那麼這個系統就會被簡單的破壞遊戲的行為所利用。
延遲補償允許伺服器暫時從每個客戶的角度看世界,並決定他們是否真的處於一個位置來進行那個不可能的射擊。反過來說,這意味著目標可能會被擊中,盡管他們自己認為他們被安全地拉到了牆後面;然而,這不太可能被注意到。
Fusion保留了過去HitBoxes
位置的歷史,並且知道每個客戶的視圖與當前伺服器狀態相比有多大的差距。利用這個歷史記錄,Fusion能夠通過在過去進行射線傳送來進行延遲補償。(Reminder: 客戶端只在它有輸入權限的對象上領先於伺服器)
對於超高精度,Fusion將延遲補償又向前推進了一步。AAA級遊戲的幀率通常高於網路的tick rate。玩家在螢幕上實際看到的通常不是離散的刻度,而是兩個刻度之間的插值。Fusion確切地知道延遲補償的光線傳輸是在兩個tick之間多遠的地方進行的,並可以利用這一點進行次tick精度的光線傳輸。
延遲補償的特點
對於使用Fusion的遊戲開發者來說,所有這些魔法幾乎都是透明的。所有需要的是預先建立的HitBox
組件,代替或補充常規的Unity Colliders。
HitBox
要在一個聯網的GameObject上設置一個延遲補償的hitbox,需要以下兩個步驟:
在GameObject的最上面的節點上需要一個
HitBoxRoot
組件。HitBoxRoot的作用是將其子節點上的所有HitBox
組件分組。HitBox
節點應該與所有動態對象的常規UnityCollider
組件保持在一個單獨的層中;這是在射線傳輸時將動態Colliders與Hitboxes分開的最快和唯一可靠的方法。這種分離允許延遲補償的光線投射擊中所有的靜態幾何體,同時避免了添加HitBox
組件的需要,這將是非常昂貴的。同時,所有的動態命中都應該完全依賴於HitBox
,但完全刪除動態碰撞器是行不通的,因為需要它們來讓物體與PhysX進行良好的互動。顧及兩者解決方法是將動態碰撞器放在一個可以被延遲補償的射線投射忽略的層上。
N.B.: 每個HitBoxRoot
有31個HitBox
節點的限制。如果在一個對象或預制件中需要更多的子節點,必須將層次結構分解並分布在幾個根上。
命中框層次的具體結構完全取決於具體遊戲的需要。
Raycasts
在伺服器上執行延遲補償的物理查詢與內置的PhysX射線傳送一樣簡單,甚至還支持重疊檢查。只需將Fusion預制的HitBox
組件添加到聯網的GameObject中。
對於查詢延遲補償數據和PhysX中保存的靜態水平數據,API是相同的。
C#
Runner.LagCompensation.Raycast(transform.position, transform.forward, 25, Object.InputAuthority, out var hit);
參數Object.InputAuthority
告訴Fusion是控制這個hitscan/Projectile。射線傳送將針對與控制它的特定玩家客戶端查看的時間框架相匹配的數據進行。所有這些都是自動發生,不需要添加任何復雜的數學運算!