← 筆記

《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幀

          • 幀同步保證的是,各個客戶端在執行到同一個「同步幀」時,表現效果完全一樣
            • 當移動計算公式一樣,只要執行相同的幀數,移動距離必然相同
    • 指令的執行
      • 為了讓所有客戶端有一樣的表現,有兩種妥協方案
        • 延遲執行
          • 讓快的客戶端等慢的客戶端
          • 對快的客戶端不利
        • 樂觀幀同步
          • 丟棄速度慢的客戶端所發送的、過時的指令
          • 對慢的客戶端不利
  • 網絡延遲問題基本無解
    • 盡量發更少的數據,降低數據丟失和重傳的概率
    • 在客戶端上做一些障眼法