【UE4 C++】网络编程基础知识总结

角色类型

每个Actor都存在两个属性来判断当前的Actor在 服务器 / 客户端上的身份类型:
Role: 判断当前角色在本地端的身份类型。
RemoteRole:判断当前角色在远端身份类型(当是客户端时,远端为服务端,当是服务端时,远端是客户端)。

网络角色类型:
Simulated : 由服务器进行数据发送,当前终端进行操控模拟。操控来源于服务器。
Autonomous: 由当前终端实例进行操控。操控来源于真人。
Authority:服务器端存在标记,表明当前Actor存在于服务器。

  • Role 类型分布
Simulate Autonomous Authority
服务器 不存在 不存在 服务器拥有复制权限的权威性
客户端 服务器在当前引擎实例中模拟的玩家角色 当前引擎实例中由真人操控的角色 不存在

Role 可以用来清晰的裁定当前角色是否在服务器,一般HasAuthority就是检查此变量。
我们也可以用来裁定当前对象是否有权发动RPC。Simulate对象无法执行RPC函数。

  • RemoteRole类型分布
Simulate Autonomous Authority
服务器 当前Actor在远端是模拟的身份 当前Actor自主权操控权在远端 不存在
客户端 不存在 不存在 拥有当前Actor复制权限的权威性

RemoteRole可以用来裁定当前Actor另一端的身份类别。如果由服务器构建的对象,则远端均是Simulate。

Remote Procedure Call (RPC)

RPC,远程调用,指在本机上调用函数,但在其他机器上远程执行函数。RPC函数可以允许客户端或服务器通过网络连接相互发送消息。

RPC执行分三种形式:

  • 服务端执行(Server) : 在客户端上调用,在服务器端执行
  • 客户端执行(Client): 在服务器端调用,在客户端执行
  • 所有终端执行(Multicast):在服务器端调用,在所有终端执行

C++ 实现:

函数说明符 效果
Server 此函数仅在服务器上执行。用于声明名称与主函数相同的附加函数,但是末尾添加了_Implementation,是写入代码的位置。必要时,此自动生成的代码将调用 _Implementation方法。
Client 此函数仅在拥有在其上调用此函数的对象的客户端上执行。用于声明名称与主函数相同的附加函数,但是末尾添加了Implementation。必要时,此自动生成的代码将调用Implementation 方法。
NetMulticast 此函数将在服务器上本地执行,也将复制到所有客户端上,无论该Actor的 NetOwner 为何。
Reliable 此函数将通过网络复制,并且一定会到达,即使出现带宽或网络错误。仅在与ClientServer配合使用时才有效。
Unreliable 此函数将通过网络复制,但是可能会因带宽限制或网络错误而失败。仅在与ClientServer配合使用时才有效。
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 调用注意事项 :

  1. 它们必须从Actor上调用
  2. Actor必须被复制。
  3. 如果RPC是从服务器调用并在客户端上执行,则只有实际拥有这个Actor的客户端才会执行函数。
  4. 如果RPC是从客户端调用并在服务器上执行,客户端就必须拥有调用RPC的Actor。
  5. 多播RPC则是个例外: ① 如果他们是从服务器调用,服务器将在本地和所有已连接的客户端上执行它们。 ②如果它们是从客户端调用,则只在本地而非服务器上执行。③ 多播事件限制机制:在特定的Actor的网络更新期内,多播函数将不会复制两次以上。

RPC调用情况分析

  • 从服务器调用的 RPC
Actor 所有权 未复制 NetMulticast Server Client
Client-owned actor 在服务器上运行 在服务器和所有客户端上运行 在服务器上运行 在 actor 的所属客户端上运行
Server-owned actor 在服务器上运行 在服务器和所有客户端上运行 在服务器上运行 在服务器上运行
Unowned actor 在服务器上运行 在服务器和所有客户端上运行 在服务器上运行 在服务器上运行
  • 从客户端调用的 RPC
Actor 所有权 未复制 NetMulticast Server Client
Owned by invoking client 在执行调用的客户端上运行 在执行调用的客户端上运行 在服务器上运行 在执行调用的客户端上运行
Owned by a different client 在执行调用的客户端上运行 在执行调用的客户端上运行 丢弃 在执行调用的客户端上运行
Server-owned actor 在执行调用的客户端上运行 在执行调用的客户端上运行 丢弃 在执行调用的客户端上运行
Unowned actor 在执行调用的客户端上运行 在执行调用的客户端上运行 丢弃 在执行调用的客户端上运行

数据同步

Actor必须满足在网络上被复制,设置的参数需要开启复制,参数的修正必须在服务器端被修改,才可以在网络上进行同步。

蓝图参数同步有两种方式 : Replicated, RepNotify

  • Replicated, 同步数据,但没有通知, 无法直接通过参数修改驱动逻辑
  • RepNotify, 同步数据,并生成通知,进行更新通知(向所有终端通知,满足相关性)
属性标签 效果
Replicated 属性应随网络进行复制。
ReplicatedUsing=FunctionName ReplicatedUsing 说明符指定一个回调函数,其在属性通过网络更新时执行。(向除去服务器外的所有终端进行通知。

属性复制条件

属性复制被注册后, 无法进行取消。所有属性默认的复制条件是:不发生变化不进行复制。我们可以使用UE提供的条件进行修正,通过条件的约束设定可以有效的节约网络带宽
【UE4 C++】网络编程基础知识总结_第1张图片

条件 说明 事例
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& OutLifetimeProps) const override;

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是否进行广播,约束关系受限于关联性规则。

关联性用途:用来解决同步过程中,无关数据的传递带宽压力,用来筛选有意义内容进行同步,表现同步信息是否同步给目标。

【UE4 C++】网络编程基础知识总结_第2张图片

关联性规则:

  • AlwaysRelevant, 相关性最大,勾选之后,所有终端永远会收到此Actor同步信息,例如烟雾弹。
  • NetUseOwnerRelevancy, 如果有拥有者Owner,则使用所有者的相关性(包括剔除距离约定)。此检查在第一项之后完成。例如角色拾取枪支。
  • OnlyRelevantToOwner, 只与当前所有者相关,同步数据只发给所有者,不发送任何人,没有所有者不同步。
  • Actor 出现依 附关系,则关联性取决于基础的Actor相关性。
  • 如果Actor不可见(bHidden = true )并且 Root Component 没有碰撞,则不具备相关性。
  • 采集距离(Net Cull Distance Squared)在采集范围内具备关联性。
  • 约束层级关系(如果RPC勾选了Reliable则关联性设置失效)

你可能感兴趣的:(#,虚幻C++总结,c++,开发语言,UE4)