3:虛幻引擎網絡架構:GameInfo,PlayerMove

  1.GameInfo和Network初始化算法

  在一個單獨類中是使用WorldInfo.Game來獲取當前的遊戲類型的,在客戶端是沒有GameInfo,即WorldInfo.Game=none。而只有服務器端纔會具備,由於只有服務器端規定了遊戲規則。服務器

  在遊戲啓動的時候,GameInfo會進行如下序列:網絡

  - event InitGame(string options,out string ErrorMessage),即服務器啓動遊戲時調用這個函數,解析URL選項,如 Unreal.exe MyLevel.rnr?Game=unreali.teamgame,其中Option字符串是?game=unreali.teamgame。錯誤將返回失敗函數

  - event PreLogin(string Options,string Address,out string ErrorMessage,out string FailCode), 當客戶端登陸時調用這個函數,使得服務器能夠拒絕玩家,這是服務器能夠驗證玩家的密碼,執行限制。性能

  - event Login(string Portal,string Options,out string ErrorMessage),當調用PreLogin正確後調用,負責使用Option中的參數來生成玩家,成功返回PlayerController,Login和PostLogin也負責在單機遊戲中建立PlayerController動畫

      - event PostLogin(PlayerController NewPlayer) 能夠爲函數賦值等操做。設計

  

  2.預測玩家移動遊戲

  Unreal不是使用了純粹的客戶端-服務器模式,不然玩家的運動是很是緩慢的,我估計大多數國產網絡遊戲使用的是這種方式(大牛勿噴哈:D)。ip

  如果傳統的網絡模式,會是這樣:若是網絡延遲是300ms,那麼遊戲延遲將會達到300ms。Unreal使用了QuakeWorld的預測方式,即在UnrealScript中進行實現。這是在PlayerController中實現的一個高級功能,而不是網絡代碼的功能。字符串

  

  Unreal客戶端的運動預測是基於網絡代碼中的複製功能設計的。在PlayerPawn中能夠查看其代碼,這種方法被描述爲鎖步,預測/校訂 算法。

  客戶端考慮了操做鍵盤,手柄,鼠標,物理力(重力,浮力,區域速度)並把它描述爲3D加速度矢量。在複製函數中調用ServerMove,客戶端把它的加速度及各類輸入相關的信息及它當前的時間戳(WorldInfo.TimeSeconds)發送給服務器端。因爲過程詳細且重要,我直接將流程表複製如下方便觀察:

服務器   客戶端
    ReplicateMove()
    調用這個函數替代 ProcessMove()。 根據玩家輸入進行 pawn 物理更新,保存(在 PlayerController SavedMoves 中)並複製結果。 SavedMove 能夠是子類,保存遊戲指定的運動輸入和結果。 ReplicateMove() 也會嘗試結合複製的運動來保存上游帶寬並改善服務器性能。
ServerMove() <- CallServerMove()
根據接收到的輸入進行 pawn 物理更新,而後將結果與客戶端發送的結果對比。 注意根據客戶端計時器進行運動更新。 若是客戶端已經積聚了一個嚴重的位置錯誤,那麼請求校訂。 不然,請求確認運動適宜。   發送一個或兩個當前運動(根據幀速率和可使用的帶寬),它們附帶客戶端時鐘時間戳記。 每次發送兩個運動能夠保存帶寬,可是會增長校訂的延遲時間。 在包丟失的狀況下也能夠調用 OldServerMove() 從新發送最近的「重要」運動。
SendClientAdjustment() -> ClientAckGoodMove()
推遲到 PlayerController 記號的末端的客戶端相應能夠在多個 ServerMoves() 接收到這個記號的狀況下避免發送多個響應。 若是沒有錯誤,那麼確認運動適宜。   根據時間戳記的環回時間更新 ping,經過之前的時間戳記清除保存的運動。
服務器   客戶端
SendClientAdjustment() -> ClientAdjustPosition()
推遲到 PlayerController 記號的末端的客戶端相應能夠在多個 ServerMoves() 接收到這個記號的狀況下避免發送多個響應。 若是有錯誤,請調用 ClientAdjustPosition() 確認運動適宜。   使用校訂時間戳記以前的時間戳記清除 SavedMoves。 將 Pawn 移動到服務器指定的位置,而後設置 bUpdatePosition。
    ClientUpdatePosition()
    在 bUpdatePosition 爲 true 的狀況下經過 PlayerTick() 調用這個函數。 從新播放全部未完成的 SavedMoves 使 Pawn 返回當前客戶端時間。

  在服務器端有一些非關聯性的動畫不須要執行,例如你在看CS中丟手雷,手雷出去但並無看到手丟的動做,咱們使用bUpdateSkelWhenNoRendered和IgnoreControllersWhenNotRendered爲false來讓其在服務器端不更新。

  對於屍體bTearOff=true將不會被複制到客戶端,而且在已經複製了這個Actor的客戶端上關閉變成一個Role_Authority。當接收到bTearOff,會調用TornOff()

 

  3.武器開火

  - 一旦玩家輸入開火,客戶端將會當即播放開火特效。並調用ServerStartFire()和ServerStopFire()函數來要求服務器開火。

  客戶端有足夠的信息來預測當前是否在開火,例如根據(子彈數量,武器時間狀態)來預測武器是否開火。

  - 服務器Spawn Projectile,這個Projectile將會被複制到Client。

 

  Projectile:

  Projectile也能夠很輕易的進行預測。

  bNetTemporary=true

  當被複制後,Actor Channel將會被關閉,Actor將永遠不會被更新,Actor將會被client,Destroy掉。

  涉及網絡部分的內容還很是的多,只有深刻操做才能更好的理解和記憶。下一章將會進行實例代碼。

相關文章
相關標籤/搜索