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

          • 幀同步保證的是,各個客戶端在執行到同一個「同步幀」時,表現效果完全一樣

            • 當移動計算公式一樣,只要執行相同的幀數,移動距離必然相同

    • 指令的執行

      • 為了讓所有客戶端有一樣的表現,有兩種妥協方案

        • 延遲執行

          • 讓快的客戶端等慢的客戶端

          • 對快的客戶端不利

        • 樂觀幀同步

          • 丟棄速度慢的客戶端所發送的、過時的指令

          • 對慢的客戶端不利

  • 網絡延遲問題基本無解

    • 盡量發更少的數據,降低數據丟失和重傳的概率

    • 在客戶端上做一些障眼法