UE4網路模組解析(一)

achevery發表於2021-12-14

一、 UE4網路架構

Server-Client構架

1.一個伺服器,一個或多個客戶端。

客戶端所有的操作如擊殺等都需要傳到中央伺服器來運算,得到的運算結果下發到各個客戶端。伺服器是UE4多人遊戲的重要組成部分。它做出所有重要決策,包含所有權威狀態,處理客戶端連線,前往新地圖,處理開始比賽、結束比賽等整個遊戲流程。

2.不能信任客戶端,所有重要資訊都需要通過伺服器驗證。

在該種模式,一個重要的特徵就是對各個客戶端不信任,需要中央伺服器進行各方面驗證。

3.Listen Server & Dedicated Server。

Listen Server中Listen其實表示等待的意思,如早期CS遊戲在該種伺服器模式下,一個玩家先加入一個主伺服器,然後等待其他玩家的加入。Dedicated Server中沒有玩家的入駐,所有玩家都是以客戶端的方式加入進來的。Listen Server和Dedicated Server在開發流程上沒有什麼區別,在打包方式上有所區別。其中Dedicated Server在打包中需要原始碼編譯,會去掉圖形介面等冗餘部分,提高效率。關於Dedicated Server的打包詳情可以看第5期(2):UE4專案中使用“專用伺服器(Dedicated Server)”(1) - 知乎 (zhihu.com)

4.我們是客戶端時,是在操作本地角色還是遠端角色?(replicate movement)。

比如說,在射擊遊戲中,客戶端遊戲玩家開火射擊時,該操作被傳到服務端進行處理如驗證是否還有子彈等,由於網路有延時,為確保玩家遊戲體驗的流暢性,會在本地直接進行虛擬的開火動畫,這就是操作本地玩家;相應地,在服務端處理完成後,遠端角色才實現開火。UE4中有replicate movement選項,勾上這個就會實現本地角色和遠端角色的構架。

5.網路傳輸的主要方式:

Replication(Rep_Notify)、RPC

6.在C++中區分服務端和客戶端

If (HasAuthority){} //如果在服務端

else {} //在客戶端

二、 Replication網路複製

它是網路同步的核心概念之一,籠統來說,表示資訊從服務端同步到客戶端(單向)。Actor及其派生類才有Replication的能力。Replication的型別有Actor Replication、Property Replication、Component Replication。

Actor Replication開啟:

1.服務端生成,客戶端也跟著生成(在服務端生成一個replicate物件)。

2.他是當前Actor的所有屬性複製、元件複製、RPC的總開關。如果他沒有開啟,剩下的都預設關閉。

在藍圖中:勾選“Replicates”,在C++中輸入如下程式碼“bReplicates = true;”來開啟Actor Replication。具體的,在一藍圖中,點選“Class defaults”,然後在右邊細節皮膚中Replication中勾上Replicates。

Property Replication開啟:

在藍圖中,選中相關屬性,在細節皮膚中Replication設定為Replicated。在C++中,1.屬性前增加UPROPERTY(Replicated),2..cpp檔案中,在GetLifetimeReplicatedProps函式中新增:DOREPLIFETIME(類名稱,變數名)。不需要宣告該函式。

其中,程式碼頭部需要新增include “Net/UnrealNetwork.h”

RepNOTIFY:

複製通知:如果一個變數設定為Rep_Notify,當該變數發生複製時,服務端和收到該值的客戶端都可以呼叫一個自定義的函式。注意C++的版本略有區別,僅在客戶端呼叫函式。他的設定方法在藍圖中:設定為RepNotify即自動生成。在C++:UPROPERTY(ReplicatedUsing=xxX)

三、 Ownership所有權

Ownership指的是Connection、PlayerController、Pawn之間的連線所屬關係。像諸如建築、NPC是沒有所有權的。為什麼OWNERSHIP很重要:1、RPC需要確定哪個客戶端將執行執行於客戶端的 RPC。2、Actor複製與連線相關性。3、在涉及所有者時的Actor屬性複製條件。

連線所有權會在actor複製期間使用。對於那些將 bOnlyRelevantToOwner設定為true的actor,只有擁有此actor的連線才會接收這個actor的屬性更新。預設情況下,所有PlayerController都設定了此標誌,正因如此,客戶端才只會收到它們擁有的PlayerControler的更新。這樣做是出於多種原因,其中最主要的是防止玩家作弊和提高效率。

如何設定/改變/獲取OWNERSHIP呢,C+=變成中一是SpawnActor函式中SpawnParameters中有Owner,其實它就對應著藍圖在生成物件時的Owner引腳,二是在藍圖和C+=中有SetOwner函式呼叫,三是Possess函式 (QnPossess >PossessedBy>SetOwner), UnPossess函式。

四、Actor Role

有三種Role,分別是Authority、Simulated Proxy、Autonomous Proxy。Authority存在於伺服器,顧名思義,是一種權威的Role。Simulated Proxy、Autonomous Proxy存在於客戶端,其中Autonomous Proxy表示自己客戶端控制的角色,可以獲得玩家的輸入,而其他的角色在該客戶端都是模擬的,所以是Simulated Proxy。

在Actor的複製中,如果Role是ROLE_Authority, RemoteRole是ROLE_SimulatedProxy 或ROLE_AutonomousProxy,就說明這個引擎例項負責將此actor複製到遠端連線。就目前而言,只有伺服器能夠向已連線的客戶端同步Actor(客戶端永遠都不能向伺服器同步)。始終記住這一點,只有伺服器才能看到RoleROLE_Authority和RemoteRole == ROLE_SimulatedProxy或者ROLE_AutonomousProxy。

相關文章