UE4网络之基本概念

UE4网络之基本概念


1 几种类型的角色


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

2 几种RPC调用


  • 服务器上调用,客户端上执行的 RPC:
UFUNCTION( Client );
void ClientRPCFunction();

  • 客户端上调用,服务器上执行的 RPC:
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());
}

3 几种同步复制


3.1 Actor复制

通过Replicates属性标记Actor是否复制(C++中为bReplicates):

actorrep

NetLoadonClient属性标记地图加载时同步创建到网络客户端,Replicate Movement标记是否同步移动或位置相关属性(Actor的Replicates设置为true,该标记才能生效)。

3.2 组件复制

  • C++设置复制:SetReplicate()
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

    }
}
  • 蓝图中设置复制(静态与动态设置):

rep rep

组件复制开销大,不建议使用。

3.3 属性复制

蓝图中:

prorep

标记Replication属性,并给出复制条件:

proprep

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;
}

4 C/S模式

UE4中的网络模型采用的是C/S模型。有两种两种服务器:

  • Listen Server:方便进行局域网本地游戏,在本地机器上搭建服务器,此时本地机器既是服务器又是客户端。

  • Dedicated Server: 更为专业的是独立服务器,在独立服务器上则不执行渲染任务,只承担服务器的相关职责。

UE4编辑器提供的基本命令行:

CS

参考

[1] UE4网络连接与多人游戏

Tags: UE4 网络 Vistied:
Share: Twitter Facebook LinkedIn