代码主要基于“多人游戏编程快速入门指南”里面的例程。
多人游戏编程快速入门指南
:https://docs.unrealengine.com/4.26/zh-CN/InteractiveExperiences/Networking/QuickStart/
变量赋值
:https://docs.unrealengine.com/5.1/zh-CN/property-replication-in-unreal-engine/
Role 和 RemoteRole
:https://docs.unrealengine.com/4.27/zh-CN/InteractiveExperiences/Networking/Actors/Roles/
RPC
:https://docs.unrealengine.com/4.27/zh-CN/InteractiveExperiences/Networking/Actors/RPCs/
主要有两种复制机制属性复制和rpc,分别用于不同的场景。
一、属性复制(变量赋值)
属性复制,当服务器中的特定属性变化时,服务器会与客户端通信,使客户端上的对应属性改变。属性复制只能在服务端复制数值到客户端。这里在服务器判断属性仍然要花费资源,所以适合那些经常变化的值,比如角色的血量。
实现步骤:
(1)角色类中声明复制变量
UPROPERTY( replicated )
AActor * Owner;
(2)注册变量复制
void AActor::GetLifetimeReplicatedProps( TArray< FLifetimeProperty > & OutLifetimeProps ) const
{
DOREPLIFETIME( AActor, Owner );
}
(3)构造函数中启动复制
bReplicates = true;
二、RPC(函数复制)
RPC,全称远程过程调用(Remote Procedure Call),是让一些函数在服务器调用的同时会让客户端也调用,或者在客户端调用的同时服务端也会调用。通常用于一些不经常发生的函数,比如发射子弹。
1、Role 和 RemoteRole
- 在 Actor 的复制过程中,有两个属性扮演了重要角色,分别是 Role 和 RemoteRole。同样的设置在服务端和客户端的变量是不一样的。
对于服务器:
Role == ROLE_Authority
RemoteRole == ROLE_SimulatedProxy 或 ROLE_AutonomousProxy
对于客户端:
Role == ROLE_SimulatedProxy 或 ROLE_AutonomousProxy
RemoteRole == ROLE_Authority
- ROLE_SimulatedProxy 和 ROLE_AutonomousProxy是客户端的两种处理方式。ROLE_SimulatedProxy会在服务端返回数值的间隔计算actor的属性,比如会按照之前服务器给的速度计算当前的位置。ROLE_AutonomousProxy会在服务端返回数值的间隔使用用户的控制值,比如玩家对角色运动的控制。
- 对于Role 和 RemoteRole两个值,可以通过GetLocalRole()和GetRemoteRole()两个函数获得。
2、RPC
ue4的actor在客户端和服务端公用同一份代码,这是函数有四种情况,对应的调用方式如下,注意这里的未复制就是没有做任何处理的函数。
3、实现步骤
(1)声明函数
UFUNCTION(Server, Reliable)
void HandleFire();
(2)定义函数
注意这里的函数名,要增加后缀_Implementation。如果要有验证环节,还要定义有后缀_Validate的函数。
void Amore_peopleCharacter::HandleFire_Implementation() //必须这么搞
{
FVector spawnLocation = GetActorLocation() + (GetControlRotation().Vector() * 100.0f) + (GetActorUpVector() * 50.0f);
FRotator spawnRotation = GetControlRotation();
FActorSpawnParameters spawnParameters;
spawnParameters.Instigator = GetInstigator();
spawnParameters.Owner = this;
AThirdPersonMPProjectile* spawnedProjectile = GetWorld()->SpawnActor<AThirdPersonMPProjectile>(spawnLocation, spawnRotation, spawnParameters);
}