了解Actor复制中的,网络角色和授权、客户端拥有权、Actor 及其关联连接、Actor Role(Actor 角色)和RemoteRole。有助于深入的理解UE的网络框架。文档中讲述的都是一些理论,如果要真正的深入了解,还需要从具体的业务出发。
官方文档的解释:
An Actor’s network role
determines whose machine has control over the Actor during a network game. An authoritative Actor
is considered to have control over that Actor’s state, and will replicate information to other machines within the network multiplayer session. A remote proxy
is a copy of that Actor on a remote machin
e, and it receives replicated information from the authoritative Actor
. This is tracked by the Local Role
and Remote Role
variables, which can take the following values:
翻译:
Actor的 网络角色 将决定网络游戏期间控制 Actor 的机器。授权(Authority) Actor 被认为可控制Actor的状态,并可将信息复制到网络多人游戏会话中的其他机器上。远程代理(remote proxy) 是该Actor在远程机器上的副本,其将接收 授权(Authority)Actor 中的复制信息。其由 Local Role 和 Remote Role 变量进行追踪,可取以下值:
虚幻引擎使用的默认模型是 服务器授权,意味着服务器对游戏状态固定具有权限,而信息固定从服务器复制到客户端。服务器上的Actor应具有授权的本地角色,而其在远程客户端上的对应Actor应具有模拟或自主代理的本地角色。
Authority Actor,又叫做权威端。指的是服务器上的 Actor。服务器是游戏的权威,负责管理和验证所有的游戏状态和操作。
Simulated Proxy Actor通常用于客户端上的非自主 Actor 。这些 Actor 在客户端上进行模拟,但最终的状态由服务器决定。
Autonomous Proxy Actor 通常用于客户端拥有的 Actor ,例如玩家控制的角色(Player Character)。这种 Actor 在客户端上有更多的控制权,并且可以自主地进行一些操作。在UE4的网络架构中,主动端(Autonomous Proxy)主要用于玩家角色
,以便直接响应玩家输入并进行本地预测。
在一个多人塔防联机游戏中,两个客户端(A和B)以及服务器的NetRole是如何分配和工作的。假设我们有一个多人塔防游戏,玩家可以在地图上放置防御塔来抵御敌人的进攻。每个玩家控制一个角色,可以在地图上移动并放置防御塔。我们有两个客户端(A和B)和一个服务器。
一、角色和对象
二、不同对象的Network Role
下面来分析一下每个对象在不同机器上的NetRole。
玩家角色(Player Character):
防御塔(Tower):
敌人(Enemy):
三、数据流和同步的过程
四、总结
主动端(Autonomous Proxy)主要用于玩家角色
,以便直接响应玩家输入并进行本地预测。其他对象(如防御塔、敌人等)通常只需要在客户端进行模拟(Simulated Proxy),而服务器作为权威端(Authority)来管理和验证它们的状态。直接翻译的话是:Actor及其关联连接。但是通常叫做Actor 所有权或拥有权比较多。
Actor所有权决定了一个Actor的生命周期、网络复制行为以及权限管理。Owner是指向另一个Actor的指针,表示当前Actor的所有者。每个Actor都可以有一个Owner,可以是另一个Actor或者PlayerController。
所有权(Connection Ownership)在UE4中的作用非常重要,特别是在多人游戏的网络同步和权限管理方面。具体作用和机制如下:
RPC 执行的客户端确定:
Actor
上调用远程过程调用(RPC)函数时,UE4需要知道在哪个客户端上执行该RPC。除非RPC被标记为多播(Multicast),否则需要通过连接所有权来确定目标客户端。Actor 复制与连接相关性:
bOnlyRelevantToOwner
设置为 true
的Actor,只有拥有此Actor的连接才会接收该Actor的属性更新。PlayerController
都设置了 bOnlyRelevantToOwner
标志,因此客户端只会收到它们拥有的 PlayerController
的更新。这有助于防止玩家作弊并提高网络效率。Actor 属性复制条件:
详细机制
1. RPC 执行的客户端确定
当在服务器上调用一个RPC函数时,服务器需要知道将该RPC发送到哪个客户端。连接所有权通过以下方式实现这一点:
例如:
// 在服务器上调用一个RPC函数
void AMyActor::ServerFunction_Implementation()
{
// 服务器逻辑
// 查找所有者的连接并发送RPC
if (APlayerController* PC = Cast<APlayerController>(GetOwner()))
{
PC->ClientFunction();
}
}
2. Actor 复制与连接相关性
在Actor复制期间,连接所有权用于确定哪些连接应该接收特定Actor的更新:
bOnlyRelevantToOwner
标志设置为 true
,则只有拥有此Actor的连接才会接收该Actor的属性更新。PlayerController
都设置了 bOnlyRelevantToOwner
标志,因此客户端只会收到它们拥有的 PlayerController
的更新。例如:
// 设置Actor的bOnlyRelevantToOwner标志
AMyActor::AMyActor()
{
bOnlyRelevantToOwner = true;
}
3. Actor 属性复制条件
连接所有权还影响Actor属性的复制条件。某些属性可能只会复制给拥有该Actor的连接:
ReplicatedUsing
标记可以用于指定一个函数,当属性复制时调用该函数。例如:
// 属性复制函数
void AMyActor::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
// 只复制给所有者
DOREPLIFETIME_CONDITION(AMyActor, MyProperty, COND_OwnerOnly);
}
4. 总结
所有权在UE4中对于RPC执行、Actor复制和属性复制条件至关重要。它确保了RPC函数在正确的客户端上执行,控制了Actor的属性更新发送到哪些连接,并且在多人游戏中提供了有效的权限管理和防作弊机制。通过合理地使用连接所有权,可以实现高效的网络同步和安全的游戏状态管理。
在一个多人塔防游戏中,所有权(Ownership)和连接所有权(Connection Ownership)的设计和管理对于确保游戏的流畅运行、同步和安全性至关重要。以下是一些常见的所有权情况和设计原则,适用于不同类型的 Actor
和游戏元素。
1. 玩家控制的角色(Player Characters)
PlayerController
拥有。// 在玩家控制器中生成角色
void AMyPlayerController::BeginPlay()
{
Super::BeginPlay();
// 生成玩家角色
AMyPlayerCharacter* PlayerCharacter = GetWorld()->SpawnActor<AMyPlayerCharacter>(PlayerCharacterClass);
// 设置角色的所有者为玩家控制器
PlayerCharacter->SetOwner(this);
// 让玩家控制器控制角色
Possess(PlayerCharacter);
}
2. 防御塔(Towers)
// 在玩家控制器中放置防御塔
void AMyPlayerController::PlaceTower(FVector Location)
{
// 生成防御塔
AMyTower* Tower = GetWorld()->SpawnActor<AMyTower>(TowerClass, Location, FRotator::ZeroRotator);
// 设置防御塔的所有者为玩家控制器
Tower->SetOwner(this);
}
3. 敌人(Enemies)
// 在服务器上生成敌人
void AMyGameMode::SpawnEnemy()
{
// 生成敌人
AMyEnemy* Enemy = GetWorld()->SpawnActor<AMyEnemy>(EnemyClass);
// 设置敌人的所有者为服务器(通常不需要显式设置,因为默认就是服务器)
Enemy->SetOwner(nullptr);
}
4. 子弹和投射物(Bullets and Projectiles)
// 在防御塔中发射子弹
void AMyTower::Fire()
{
// 生成子弹
AMyBullet* Bullet = GetWorld()->SpawnActor<AMyBullet>(BulletClass, MuzzleLocation, MuzzleRotation);
// 设置子弹的所有者为防御塔
Bullet->SetOwner(this);
}
5. 游戏资源(Game Resources)
// 在服务器上管理资源
void AMyGameMode::AddResource(int32 Amount)
{
// 增加资源
Resources += Amount;
// 通知所有客户端资源更新
OnRep_Resources();
}
6. 总结
在一个多人塔防游戏中,合理地设置和管理所有权和连接所有权对于确保游戏的流畅运行、同步和安全性至关重要。玩家控制的角色和防御塔通常由对应的 PlayerController
拥有,敌人和游戏资源通常由服务器拥有。通过合理地分配所有权,可以确保游戏的各个元素能够正确地进行控制、更新和同步,从而提供良好的游戏体验。
在 Actor 的复制过程中,有两个属性扮演了重要角色,分别是 Role 和 RemoteRole。有了这两个属性,您可以知道:
首先一件要确定的事,就是谁拥有特定 actor 的主控权。要确定当前运行的引擎实例是否有主控者,需要查看 Role 属性是否为 ROLE_Authority。如果是,就表明这个运行中的 虚幻引擎 实例负责掌管此 actor(决定其是否被复制)。
Actor Role
Role
属性表示当前 Actor
在本地的角色。它可以有以下几种值:
ROLE_None
:该 Actor
不参与网络复制。ROLE_SimulatedProxy
:该 Actor
是一个模拟代理,通常在客户端上使用。它接收来自服务器的更新,但不能自主决定其状态。ROLE_AutonomousProxy
:该 Actor
是一个自主代理,通常用于客户端拥有的 Actor
。它可以自主决定其状态,并将这些状态发送到服务器。ROLE_Authority
:该 Actor
拥有主控权,通常在服务器上使用。它决定 Actor
的状态并将这些状态复制到客户端。RemoteRole
RemoteRole
属性表示该 Actor
在远程(通常是服务器或客户端)上的角色。它可以有以下几种值:
ROLE_None
:该 Actor
不参与网络复制。ROLE_SimulatedProxy
:该 Actor
在远程是一个模拟代理。ROLE_AutonomousProxy
:该 Actor
在远程是一个自主代理。ROLE_Authority
:该 Actor
在远程拥有主控权。要确定当前运行的引擎实例是否拥有某个 Actor
的主控权,可以检查 Role
属性是否为 ROLE_Authority
。如果是,则表明该引擎实例负责掌管此 Actor
。
if (Role == ROLE_Authority)
{
// 当前实例拥有主控权
}
通过 Role
和 RemoteRole
的组合,可以确定 Actor
的复制模式。例如:
服务器上的 Actor
:
Role
为 ROLE_Authority
RemoteRole
为 ROLE_SimulatedProxy
或 ROLE_AutonomousProxy
客户端上的 Actor
:
Role
为 ROLE_SimulatedProxy
或 ROLE_AutonomousProxy
RemoteRole
为 ROLE_Authority
以下是一个示例,展示如何使用 Role
和 RemoteRole
属性来确定 Actor
的主控权和复制模式。
MyActor.h
UCLASS()
class AMyActor : public AActor
{
GENERATED_BODY()
public:
virtual void Tick(float DeltaTime) override;
protected:
virtual void BeginPlay() override;
};
MyActor.cpp
#include "MyActor.h"
void AMyActor::BeginPlay()
{
Super::BeginPlay();
if (Role == ROLE_Authority)
{
UE_LOG(LogTemp, Log, TEXT("This instance has authority over this actor."));
}
else
{
UE_LOG(LogTemp, Log, TEXT("This instance does not have authority over this actor."));
}
}
void AMyActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (Role == ROLE_Authority)
{
// 服务器上的逻辑
}
else if (Role == ROLE_AutonomousProxy)
{
// 客户端自主代理的逻辑
}
else if (Role == ROLE_SimulatedProxy)
{
// 客户端模拟代理的逻辑
}
}
Role
和 RemoteRole
属性在 UE4 的网络复制系统中扮演了重要角色。通过检查这些属性,可以确定当前引擎实例是否拥有某个 Actor
的主控权,以及该 Actor
的复制模式。理解和正确使用这些属性对于开发多人游戏和实现网络同步至关重要。
在Unreal Engine 4(UE4)中,Network Role 和 Actor Role 是两个相关但不同的概念。
区别:
联系: