文章

Networking in unreal engine

在虚幻引擎中,在客户端与服务器间同步数据和调用程序的过程被称为 复制(Replication)

复制系统同时提供了较高层次的抽象物以及低层次的自定义,以便在创建针对多个并发用户的项目时更加方便地处理可能遇到的情况。

远程过程调用(RPC)

RPC类型说明
Server仅在主持游戏的服务器上调用。
Client仅在拥有该函数所属Actor的客户端上调用。若Actor无拥有连接,将不会执行此逻辑。
NetMulticast在与服务器连接的所有客户端及服务器本身上调用。

提供对应 UFUNCTION 宏中的 ServerClientNetMulticast 说明符,可在将C++函数指定为RPC。其代码将在代码实现中使用后缀 _Implementation

ExampleClass.h

1
2
3
//服务器RPC MyFunction的声明。
UFUNCTION(Server, Reliable, WithValidation)
void MyFunction(int myInt);

ExampleClass.cpp

1
2
3
4
5
//服务器RPC MyFunction的实现。
void AExampleClass::MyFunction_Implementation(int myInt)
{
    //游戏代码在此。
}

DS 服务器优化

  • 压测数据监控,及时发现(CI)
  • Property Replication 的效率比 RPC 慢的多, 100 ~ 1000 倍;但官方更推荐 RepNotify
  • 自定义 Animation 的采样频率
    • 业务向的LOD降低,eg. 在某些情况下的Idle等
  • 关注 Mem Missing - 非统一内存访问 NUMA
    • img
  • 关注程序调度系统

在 UObject 内调用 RPC 函数

当 RPC 被触发时,CallRemoteFunction 将被调用,需要通过一个 actor 来路由它,它希望有一个拥有的连接。

如果我们的外部是一个 Actor,那么我们可以从该 Actor 获取 NetDriver,如果发生这种情况,我们可以通过该 NetDriver 传递我们的远程函数。

GetFunctionCallspace 是我们要调用函数的调用空间,有3个可能的调用空间,但是我们不想在这里确定如果我们有一个外部actor,我们可以让它确定它,所以我们只是把它传递下去。如果我们没有外部 Actor,那么我们就知道它的本地 Actor,并且可以直接返回它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bool UMyObject::CallRemoteFunction(UFunction* Function, void* Parameters, struct FOutParmRec* OutParams, FFrame* Stack)
{
    if (AActor* OuterActor = Cast<AActor>(GetOuter()))
    {
        UNetDriver* NetDriver = OuterActor->GetNetDriver();
        if (NetDriver)
        {
            NetDriver->ProcessRemoteFunction(OuterActor, Function, Parameters, OutParams, Stack, this);
            return true;
        }
    }
    return false;
}
 
int32 UMyObject::GetFunctionCallspace(UFunction* Function, FFrame* Stack)
{
    if (AActor* OuterActor = Cast<AActor>(GetOuter()))
    {
        return OuterActor ->GetFunctionCallspace(Function, Stack);
    }
 
    return FunctionCallspace::Local;
}
本文由作者按照 CC BY 4.0 进行授权