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

Posted Tanzq*

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UE4 C++网络编程基础知识总结相关的知识,希望对你有一定的参考价值。

角色类型

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

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

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

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

  • RemoteRole类型分布
SimulateAutonomousAuthority
服务器当前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 所有权未复制NetMulticastServerClient
Client-owned actor在服务器上运行在服务器和所有客户端上运行在服务器上运行在 actor 的所属客户端上运行
Server-owned actor在服务器上运行在服务器和所有客户端上运行在服务器上运行在服务器上运行
Unowned actor在服务器上运行在服务器和所有客户端上运行在服务器上运行在服务器上运行
  • 从客户端调用的 RPC
Actor 所有权未复制NetMulticastServerClient
Owned by invoking client在执行调用的客户端上运行在执行调用的客户端上运行在服务器上运行在执行调用的客户端上运行
Owned by a different client在执行调用的客户端上运行在执行调用的客户端上运行丢弃在执行调用的客户端上运行
Server-owned actor在执行调用的客户端上运行在执行调用的客户端上运行丢弃在执行调用的客户端上运行
Unowned actor在执行调用的客户端上运行在执行调用的客户端上运行丢弃在执行调用的客户端上运行

数据同步

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

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

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

属性复制条件

属性复制被注册后, 无法进行取消。所有属性默认的复制条件是:不发生变化不进行复制。我们可以使用UE提供的条件进行修正,通过条件的约束设定可以有效的节约网络带宽

条件说明事例
COND_InitialOnly该属性仅在初始数据组尝试发送玩家的名字等
COND_OwnerOnly该属性仅发送至 actor 的所有者手持武器子弹剩余数量等
COND_SkipOwner该属性将发送至除所有者之外的每个连接
COND_SimulatedOnly该属性仅发送至模拟 actorFPS自己只需要看到手臂,但其他玩家需要看到自己的整个身体等
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<FLifetimeProperty>& 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是否进行广播,约束关系受限于关联性规则。

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

关联性规则:

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

以上是关于UE4 C++网络编程基础知识总结的主要内容,如果未能解决你的问题,请参考以下文章

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

UE4基础知识总结(四)

虚幻4 C++编程经验总结

UE4项目界面基础知识总结(三)

UE4基础知识总结

UE4基础知识总结(五)