This document is about: QUANTUM 2
SWITCH TO

EntityRef Hijacking

概述

實體參照 劫持 是一個術語,是在檢視中的預測——復原模型可能有的已知副作用的術語。

說明

有幾個移動部件在這之中發揮作用:

  • 預測——復原;
  • 實體建立;及,
  • 實體檢視。

模擬不斷地預測接下來的幾幀。已預測幀 使用未經驗證的玩家輸入;當收到針對所有玩家的伺服器驗證輸入,Quantum就會模擬一個已驗證幀。 如果一個已預測幀需要 實體A 的建立,它會處理它並且接著指派一個「實體參照X」給它。如果與它關聯的EntityViewAsset有它自己的Bind Behaviour設定到 未驗證,在Unity中將在下一個OnUpdateView回調建立檢視元素。

當從伺服器接收到已確認輸入,Quantum使用伺服器端已驗證資訊來重新模擬幀——這些是 已驗證 幀。這是有趣的地方。

如果在一個已預測幀還沒有的重新模擬幀中,在 實體A 之前已經建立另一個 實體B,則將重新指派「實體參照X」,因為實體參照是確定性的,並且按照順序給出。在這個情況下,實體A 被指派一個新的「實體參照Y」。

現在下列兩者之一將發生:

  1. 實體A實體B 各自使用一個 不同的 EntityViewAsset。針對 實體A 及其關聯的檢視,EntityViewUpdater指令碼將偵測錯誤配對,銷毀它有的鏈結。當完成清除後,它接著將針對 實體A實體B 建立一個新的檢視。

  2. 實體A實體B 使用 相同的 EntityViewAsset。在下一個更新中EntityViewUpdater指令碼將偵測錯誤對戰,破壞 實體A 及其檢視之間的鏈結,鏈接 實體B 到現有的檢視,並且針對 實體A 來具現化一個新的檢視。

    • 實體A 有一個新的檢視。該檢視使用正確的資料。
    • 實體B 有一個先前與 實體A 關聯的檢視。該檢視以錯誤的資料被具現化,因此需要被更新。

實體檢視更新器注意事項: EntityViewUpdater指令碼透過快取一個實體參照及實體檢視資產鍵值對,來儲存在模擬及其檢視中的實體之間的鏈結。請參見EntityViewUpdater.cs以取得更多資訊。

繫結行為注意事項: 如果一個實體檢視使用 已驗證 繫結行為,它只將在一個已驗證幀上被具現化,因此上述情形將永遠不會發生在其上。它是一個取捨,實體的「類型」決定了哪種行為更合適(請參見下述的 一般建議 章節)。

如何處理它

這種情況可以透過調整模擬或檢視來輕鬆解決。

在程式碼中

為了確保只在已驗證幀上建立實體,您可以包裝以下的條件敘述:

C#

if(f.IsVerified) {
    // Do stuff
}

或是在未驗證(也就是已預測)幀上提前退出,方法是使用:

C#

if (f.IsPredicted == false)
    return;

如果需要,也可以在OnPlayerDataSet中使用API。

在Unity中

在檢視中,您可以選擇處理問題的方式有,修改初始化行為,或在檢視在它持有的資料中偵測到一個錯誤對戰時,讓檢視更新它自己。解決方案將取決於您是否設定了繫結行為已驗證未驗證。 為了在Unity中更改 繫結行為,簡單地導航到位於與EntityViewAsset關聯的預製件上的Entity View指令碼,並且將其從 未驗證 切換到 已驗證

editing the bind behaviour on the entity view
在Unity中的實體檢視上編輯繫結行為。

繫結行為——已驗證

在這個情況下,從一開始就保證您有正確的資訊,並且您可以信任在Unity的Start()方法時可用的資訊。也可以使用OnEntityInstantiated實體檢視事件(請參見附加在預製件的實體檢視指令碼)。

繫結行為——未驗證

在這個情況下,在具現化時您可用的資訊可能是錯誤的。

為了保證檢視能夠反映這個更改,請確保檢視可以透過輪詢從Unity Update()中設定自己。這樣的話,如果資料發生錯誤,它將能夠切換其資料。如果檢視完全獨立於模擬,並且已經持有了它需要的資訊,那麼就不需要採取這種預防措施,因為EntityViewUpdater將已經透過銷毀及重新建立遊戲物件來糾正問題。

關於繫結行為的一般建議

兩個行為,已驗證未驗證,有它們自己的優缺點。

  • Verified:對於毫秒級準確具現化不是極端敏感的事情,比如玩家角色。
  • Non Verified:快速且玩家需要時間來做出反應的事情,比如拋射物。
Back to top