UE4網絡模塊解析(一)
一、 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。