Unreal NetMode&NetRole 解析

Version: Unreal 4.26

問題

  • 為啥UE編輯器會有EPlayNetMode有三種讓你選擇。
  • 為啥描述World 的ENetMode 會有4種,而不只是(Client/Server 2種)。
  • 為何Actor 會有Role的概念。

EPlayNetMode

UENUM()
enum EPlayNetMode
{
	/** A non-networked game will be started. This can be used in combination with bLaunchSeparateServer to test menu -> server flow in your game. */
	PIE_Standalone UMETA(DisplayName="Play Offline"),
	/** The editor will act as both a Server and a Client. Additional instances may be opened beyond that depending on the number of clients. */
	PIE_ListenServer UMETA(DisplayName="Play As Listen Server"),
	/** The editor will act as a Client. A server will be started for you behind the scenes to connect to. */
	PIE_Client UMETA(DisplayName="Play As Client"),
};
  • PIE_Standalone

    單機玩法,本地直接有一個所謂的伺服器和一個或多個玩家。因此尤其注意相關網路請求rpc,值複製等都是同步執行的

    應用:一般遊戲的訓練場啊,遊戲大廳,新手引導關卡。不需要跟其他玩家交互的場景。

  • PIE_Client

    一般用於多人在線聯網戰鬥局內,比如吃雞遊戲那種開房間成功後進入局內戰鬥,就是所謂的戰鬥局內,用這個比較多。

    應用:比如吃雞遊戲的戰鬥場景(與其他聯網玩家戰鬥交互)。

  • PIE_ListenServer

    一般用於開發區域網遊戲。

    應用:無(我沒用過,現在好像沒有開發區域網遊戲的了吧)。


綜上:就是方便為了給UE 編輯器用戶開發測試使用。

ENetMode


 //* The network mode the game is currently running.*/
enum ENetMode
{
	/** Standalone: a game without networking, with one or more local players. Still considered a server because it has all server functionality. */
	NM_Standalone,

	/** Dedicated server: server with no local players. */
	NM_DedicatedServer,

	/** Listen server: a server that also has a local player who is hosting the game, available to other players on the network. */
	NM_ListenServer,

	/**
	 * Network client: client connected to a remote server.
	 * Note that every mode less than this value is a kind of server, so checking NetMode < NM_Client is always some variety of server.
	 */
	NM_Client,
};
  • NM_Standalone

    如果你開啟的是PIE_Standalone,所謂的客戶端和伺服器的World()->GetNetMode()都會只是NM_Standalone.

  • NM_DedicatedServer

    如果你開啟的是PIE_Client,伺服器上的World()->GetNetMode()才會是NM_DedicatedServer.

  • NM_Client

    如果你開啟的是PIE_Client,客戶端上的World()->GetNetMode()才會是NM_Client.

  • NM_ListenServer

    如果你開啟的是PIE_Standalone,所謂的客戶端和伺服器的World()->NetMode 都會只是PIE_Standalone.

ENetRole

class ENGINE_API AActor : public UObject
{
	/** Describes how much control the local machine has over the actor. */
	UPROPERTY(Replicated)
	TEnumAsByte<enum ENetRole> Role;

	/** Returns how much control the remote machine has over this actor. */
	UPROPERTY(Replicated, Transient)
	TEnumAsByte<enum ENetRole> RemoteRole;	
}

/** The network role of an actor on a local/remote network context */
enum ENetRole
{
	/** No role at all. */
	ROLE_None,
	/** Locally simulated proxy of this actor. */
	ROLE_SimulatedProxy,
	/** Locally autonomous proxy of this actor. */
	ROLE_AutonomousProxy,
	/** Authoritative control over the actor. */
	ROLE_Authority,
};

前面的ENetMode針對的是世界才能調用的,這個ENetRole是Actor才能調用的。你需要了解Actor是作為UE 可以同步的最小單元。
主要是Actor的Role和RemoteRole,大概描述的是這個Actor本地的控制性和遠端的控制性。還有一點需要申明,只能是伺服器複製Actor到客戶端,客戶端不會複製Actor到伺服器。

伺服器創建Actor

  • 不複製到客戶端
  • Role:ROLE_Authority
  • RemoteRole:ROLE_None
  • 複製到客戶端
  • Role:ROLE_Authority
  • RemoteRole:ROLE_SimulatedProxy 或 ROLE_AutonomousProxy

客戶端創建Actor

  • Role:ROLE_Authority
  • RemoteRole:ROLE_None

應用:
從伺服器複製一個Actor到ABCD四個客戶端,那麼我可以在這個Actor 的BeginPlay里判斷列印log。

this->GetLocalRole() == ROLE_AutonomousProxy 就是A客戶端,只列印一次。
this->GetLocalRole() == ROLE_Authority 就是伺服器,只列印一次。
this->GetLocalRole() == ROLE_SimulatedProxy 就是BCD客戶端,列印三次。

通俗的說:目的是為了描述這個Actor是伺服器生成的;還是客戶端生成的;還是伺服器生成複製到客戶端的;還是伺服器複製到客戶端,這個客戶端是本地玩家還是非本地玩家。
本地玩家的,還是非本地玩家的,這是個相對的概念,客戶端是我,就是本地玩家,專業術語是主控端(是我),還是模擬端。

參考