《Unity3D網絡遊戲實踐》(第2版)要點摘錄 - 「同步理論」
書名:****《Unity3D網絡遊戲實踐》(第2版)
作者:羅培羽
所讀版本:機械工業出版社
同步理論
- 狀態同步
- 同步狀態信息
- 客戶端定時向服務端報告位置,其他玩家收到轉發的消息後,直接將對方移動到指定位置
- 這樣會導致看到對方瞬移,因此出現了「跟隨算法」和「預測算法」
- 跟隨算法
- 玩家1發送同步信息後,玩家2收到後,將對方以同樣速度移動至指定點
- 導致更大的誤差出現
- 如玩家1從A點 -> B點 -> C點,在經過B點時發送同步信息
- 玩家2還看到玩家1在A點,收到信息後,將玩家1的對象以同等速度移動至B點
- 當玩家2看到的玩家1到達B點時,真實的玩家1可能已經到達C點
- 預測算法
- 預測對方在接下來某個時間點的位置,讓對方提早走到預測的位置上
- 如玩家1從A點 -> B點 -> C點,在經過B點時發送同步信息
- 玩家2根據移動公式計算出下一次收到同步信息時,玩家1應到達的點,並直接讓其同步移動至該預測點
- 指令同步
- 幀同步是一種常見的指令同步
- 同步操作信息
- 只傳輸玩家的操作指令
- 玩家1按W時,發送前進的消息至服務端,服務端將其轉發至所有客戶端
- 缺點
- 誤差的累積
- 不同電腦的執行速度有異,導致有人看到玩家1走了很遠,有人看到玩家1只走了一點點
- 引入「同步幀」優化
- 只傳輸玩家的操作指令
- 同步幀
- 發送命令時附帶時間信息,客戶端根據指令的時間信息去修正移動的計算方式,讓不同電腦有盡可能一致的運行效果
- 增加一個函數FrameUpdate,程序固定每隔0.1秒調用一次,每一次調用稱為1幀
-
int frame = 0; //目前執行到第幾幀 float interval = 0.1f; //兩幀之間的理想時間 public void Update() { while(Time.deltaTime < frame * interval) { FrameUpdate(); frame++; } } -
如果某幾幀執行時間太長,程序就會直接調用下一幀,盡量保證在第N秒的時候,執行到第10*N幀
- 幀同步保證的是,各個客戶端在執行到同一個「同步幀」時,表現效果完全一樣
- 當移動計算公式一樣,只要執行相同的幀數,移動距離必然相同
- 幀同步保證的是,各個客戶端在執行到同一個「同步幀」時,表現效果完全一樣
-
- 指令的執行
- 為了讓所有客戶端有一樣的表現,有兩種妥協方案
- 延遲執行
- 讓快的客戶端等慢的客戶端
- 對快的客戶端不利
- 樂觀幀同步
- 丟棄速度慢的客戶端所發送的、過時的指令
- 對慢的客戶端不利
- 延遲執行
- 為了讓所有客戶端有一樣的表現,有兩種妥協方案
- 網絡延遲問題基本無解
- 盡量發更少的數據,降低數據丟失和重傳的概率
- 在客戶端上做一些障眼法