UE4战斗服与客户端是共享一份代码,通过以下三个类型来区分:
ROLE_SimulatedProxy:其他客户端在本机客户端的一个模拟代理
ROLE_AutonomousProxy:客户端的自己控制的角色
ROLE_Authority:服务器上的角色
可以通过Actor的Role 和 RemoteRole 属性来区分服务器与客户端:
服务器: Role为ROLE_Authority,RemoteRole为ROLE_SimulatedProxy 或者 ROLE_AutonomousProxy
客户端:Role为ROLE_SimulatedProxy 或者 ROLE_AutonomousProxy, RemoteRole为ROLE_Authority
UFUNCTION( Client );
void ClientRPCFunction();
UFUNCTION( Server );
void ServerRPCFunction();
UFUNCTION( NetMulticast );
void MulticastRPCFunction();
多播 RPC 也可以从客户端调用,但这时就只能在本地执行。
RPC的可靠性与校验 指定Reliable关键字保证可靠性,通过 WithValidation 关键字指定校验(校验失败会断开RPC调用者的连接),需要实现_Validate与_Implementation函数:
UFUNCTION( Server, Reliable, WithValidation );
void SomeRPCFunction( int32 AddHealth );
bool SomeRPCFunction _Validate( int32 AddHealth )
{
If ( AddHealth > MAX_ADD_HEALTH )
{
return false; // This will disconnect the caller
}
return true; // This will allow the RPC to be called
}
void SomeRPCFunction _Implementation( int32 AddHealth )
{
Health += AddHealth;
}
针对在客户端Actor中需要向服务器发送RPC,只有out-most owner为PlayerContrller的Actor调用才会生效,否则调用无效,只有被玩家直接操控的对象及子对象才有资格调用RPC,详见AActor::SetOwner()与AActor::GetNetConnection()。同理,服务器调用的客户端RPC,只会在out-most owner的PlayerContrller所对应的Connection的客户端执行。
// Send function data to remote.
Connection = Actor->GetNetConnection();
if (Connection)
{
InternalProcessRemoteFunction( Actor, SubObject, Connection, Function, Parameters, OutParms, Stack, bIsServer );
}
else
{
UE_LOG(LogNet, Warning, TEXT("UIpNetDriver::ProcessRemoteFunction: No owning connection for actor %s. Function %s will not be processed."), *Actor->GetName(), *Function->GetName());
}
通过Replicates属性标记Actor是否复制(C++中为bReplicates):
NetLoadonClient属性标记地图加载时同步创建到网络客户端,Replicate Movement标记是否同步移动或位置相关属性(Actor的Replicates设置为true,该标记才能生效)。
ACharacter::ACharacter()
{
// Etc...
CharacterMovement = CreateDefaultSubobject<UMovementComp_Character>(TEXT("CharMoveComp"));
if (CharacterMovement)
{
CharacterMovement->UpdatedComponent = CapsuleComponent;
CharacterMovement->GetNavAgentProperties()->bCanJump = true;
CharacterMovement->GetNavAgentProperties()->bCanWalk = true;
CharacterMovement->SetJumpAllowed(true);
CharacterMovement->SetNetAddressable(); // Make DSO components net addressable
CharacterMovement->SetIsReplicated(true); // Enable replication by default
}
}
组件复制开销大,不建议使用。
蓝图中:
标记Replication属性,并给出复制条件:
C++中通过代码实现一样的机制:
将 replicated 关键字作为 UPROPERTY 声明的一个参数:
class ENGINE_API AActor : public UObject
{
UPROPERTY( replicated )
AActor * Owner;
};
实现 GetLifetimeReplicatedProps 函数:
void AActor::GetLifetimeReplicatedProps( TArray< FLifetimeProperty > & OutLifetimeProps ) const
{
DOREPLIFETIME( AActor, Owner );
}
actor 的构造函数中将 bReplicates 标志设置为 true:
AActor::AActor( const class FPostConstructInitializeProperties & PCIP ) :Super( PCIP )
{
bReplicates = true;
}
UE4中的网络模型采用的是C/S模型。有两种两种服务器:
Listen Server:方便进行局域网本地游戏,在本地机器上搭建服务器,此时本地机器既是服务器又是客户端。
Dedicated Server: 更为专业的是独立服务器,在独立服务器上则不执行渲染任务,只承担服务器的相关职责。
UE4编辑器提供的基本命令行:
[1] UE4网络连接与多人游戏