每个Actor都存在两个属性来判断当前的Actor在 服务器 / 客户端上的身份类型:
Role: 判断当前角色在本地端的身份类型。
RemoteRole:判断当前角色在远端身份类型(当是客户端时,远端为服务端,当是服务端时,远端是客户端)。
网络角色类型:
Simulated : 由服务器进行数据发送,当前终端进行操控模拟。操控来源于服务器。
Autonomous: 由当前终端实例进行操控。操控来源于真人。
Authority:服务器端存在标记,表明当前Actor存在于服务器。
Simulate | Autonomous | Authority | |
---|---|---|---|
服务器 | 不存在 | 不存在 | 服务器拥有复制权限的权威性 |
客户端 | 服务器在当前引擎实例中模拟的玩家角色 | 当前引擎实例中由真人操控的角色 | 不存在 |
Role 可以用来清晰的裁定当前角色是否在服务器,一般HasAuthority就是检查此变量。
我们也可以用来裁定当前对象是否有权发动RPC。Simulate对象无法执行RPC函数。
Simulate | Autonomous | Authority | |
---|---|---|---|
服务器 | 当前Actor在远端是模拟的身份 | 当前Actor自主权操控权在远端 | 不存在 |
客户端 | 不存在 | 不存在 | 拥有当前Actor复制权限的权威性 |
RemoteRole可以用来裁定当前Actor另一端的身份类别。如果由服务器构建的对象,则远端均是Simulate。
RPC,远程调用,指在本机上调用函数,但在其他机器上远程执行函数。RPC函数可以允许客户端或服务器通过网络连接相互发送消息。
RPC执行分三种形式:
C++ 实现:
函数说明符 | 效果 |
---|---|
Server | 此函数仅在服务器上执行。用于声明名称与主函数相同的附加函数,但是末尾添加了_Implementation ,是写入代码的位置。必要时,此自动生成的代码将调用 _Implementation 方法。 |
Client | 此函数仅在拥有在其上调用此函数的对象的客户端上执行。用于声明名称与主函数相同的附加函数,但是末尾添加了Implementation 。必要时,此自动生成的代码将调用Implementation 方法。 |
NetMulticast | 此函数将在服务器上本地执行,也将复制到所有客户端上,无论该Actor的 NetOwner 为何。 |
Reliable | 此函数将通过网络复制,并且一定会到达,即使出现带宽或网络错误。仅在与Client 或Server 配合使用时才有效。 |
Unreliable | 此函数将通过网络复制,但是可能会因带宽限制或网络错误而失败。仅在与Client 或Server 配合使用时才有效。 |
WithValidation | 用于声明名称与主函数相同的附加函数,但是末尾需要添加_Validate 。此函数使用相同的参数,但是会返回bool ,以指示是否应继续调用主函数。 |
服务端执行:
UFUNCTION(BlueprintCallable, Server, Reliable, WithValidation, Category = "ALS|Character States")
void Server_SetDesiredGait(EALSGait NewGait);
bool AALSBaseCharacter::Server_SetDesiredGait_Validate(EALSGait NewGait)
{
// 这里写服务器进行检测的逻辑
return true;
}
void AALSBaseCharacter::Server_SetDesiredGait_Implementation(EALSGait NewGait)
{
// 这里写你的逻辑
SetDesiredGait(NewGait);
}
客户端执行:
UFUNCTION(BlueprintCallable, Client, Reliable, Category = "ALS|Character States")
void Client_SetDesiredGait(EALSGait NewGait);
oid AALSBaseCharacter::Client_SetDesiredGait_Implementation(EALSGait NewGait)
{
// 这里写你的逻辑
}
所有终端执行 :
UFUNCTION(BlueprintCallable, NetMulticast, Reliable, Category = "ALS|Character States")
void NetMulticast_SetDesiredGait(EALSGait NewGait);
void AALSBaseCharacter::NetMulticast_SetDesiredGait_Implementation(EALSGait NewGait)
{
// 这里写你的逻辑
}
RPC 调用注意事项 :
RPC调用情况分析
Actor 所有权 | 未复制 | NetMulticast | Server | Client |
---|---|---|---|---|
Client-owned actor | 在服务器上运行 | 在服务器和所有客户端上运行 | 在服务器上运行 | 在 actor 的所属客户端上运行 |
Server-owned actor | 在服务器上运行 | 在服务器和所有客户端上运行 | 在服务器上运行 | 在服务器上运行 |
Unowned actor | 在服务器上运行 | 在服务器和所有客户端上运行 | 在服务器上运行 | 在服务器上运行 |
Actor 所有权 | 未复制 | NetMulticast | Server | Client |
---|---|---|---|---|
Owned by invoking client | 在执行调用的客户端上运行 | 在执行调用的客户端上运行 | 在服务器上运行 | 在执行调用的客户端上运行 |
Owned by a different client | 在执行调用的客户端上运行 | 在执行调用的客户端上运行 | 丢弃 | 在执行调用的客户端上运行 |
Server-owned actor | 在执行调用的客户端上运行 | 在执行调用的客户端上运行 | 丢弃 | 在执行调用的客户端上运行 |
Unowned actor | 在执行调用的客户端上运行 | 在执行调用的客户端上运行 | 丢弃 | 在执行调用的客户端上运行 |
Actor必须满足在网络上被复制,设置的参数需要开启复制,参数的修正必须在服务器端被修改,才可以在网络上进行同步。
蓝图参数同步有两种方式 : Replicated, RepNotify
属性标签 | 效果 |
---|---|
Replicated | 属性应随网络进行复制。 |
ReplicatedUsing=FunctionName | ReplicatedUsing 说明符指定一个回调函数,其在属性通过网络更新时执行。(向除去服务器外的所有终端进行通知。) |
属性复制条件
属性复制被注册后, 无法进行取消。所有属性默认的复制条件是:不发生变化不进行复制。我们可以使用UE提供的条件进行修正,通过条件的约束设定可以有效的节约网络带宽。
条件 | 说明 | 事例 |
---|---|---|
COND_InitialOnly | 该属性仅在初始数据组尝试发送 | 玩家的名字等 |
COND_OwnerOnly | 该属性仅发送至 actor 的所有者 | 手持武器子弹剩余数量等 |
COND_SkipOwner | 该属性将发送至除所有者之外的每个连接 | |
COND_SimulatedOnly | 该属性仅发送至模拟 actor | FPS自己只需要看到手臂,但其他玩家需要看到自己的整个身体等 |
COND_AutonomousOnly | 该属性仅发送给自主 actor | |
COND_SimulatedOrPhysics | 该属性将发送至模拟或 bRepPhysics actor | |
COND_InitialOrOwner | 该属性将发送初始数据包,或者发送至 actor 所有者 | |
COND_Custom | 该属性没有特定条件,但需要通过 SetCustomIsActiveOverride 得到开启/关闭能力 |
C++ :
UPROPERTY(BlueprintReadOnly, Replicated, Category = "ALS|Ragdoll System")
FVector TargetRagdollLocation = FVector::ZeroVector;
UPROPERTY(BlueprintReadOnly, Category = "ALS|State Values", ReplicatedUsing = OnRep_RotationMode)
EALSRotationMode RotationMode = EALSRotationMode::LookingDirection;
绑定参数到复制参数列表:
virtual void GetLifetimeReplicatedProps(TArray
void AALSBaseCharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AALSBaseCharacter, TargetRagdollLocation);
DOREPLIFETIME_CONDITION(AALSBaseCharacter, RotationMode, COND_SkipOwner);
}
需要使用属性复制条件进行优化就使用:DOREPLIFETIME_CONDITION
,不需要就使用:DOREPLIFETIME
。
UE网络模块考虑到通信带宽问题,针对场景中的所有Actor数据更新制定了高效的同步方案,根据Actor的网络关联性,进行数据更新,这样可以有效的规避无用数据更新造成的通信带宽压力。
网络关联性约束了Replicated是否进行广播,约束关系受限于关联性规则。
关联性用途:用来解决同步过程中,无关数据的传递带宽压力,用来筛选有意义内容进行同步,表现同步信息是否同步给目标。
关联性规则: