UE5.8 Mass Framework 专题系列

UE5.8 Mass 专题(十):Replication、Client Bubble 与联网应用

拆解 FMassNetworkIDFragment、FMassReplicatedAgentFragment、FMassReplicationParameters、FMassReplicationSharedFragment、TClientBubbleHandlerBase、LOD 复制和客户端泡泡。

总览

Mass 联网的核心思路是:服务器维护权威实体,但客户端只需要知道与自己相关的一小部分实体。MassReplication 用 Client Bubble 组织每个客户端的相关实体集合,再用 FastArray 风格的数据同步必要状态。它不是把每个 Mass 实体都变成 replicated Actor,而是把 Mass 数据压缩成面向客户端的复制项。

这对于城市人群、交通、战场单位都很重要。玩家附近的路人需要比较准确的位置和表现;远处只需要低频或根本不需要;不可见实体仍可在服务器模拟。

UE5.8 Mass 专题(十):Replication、Client Bubble 与联网应用 配图
Mass 联网不等于把每个实体变成 Actor 复制;Client Bubble 只给每个客户端同步相关实体和必要数据。

源码依据

MassReplicationFragments.h 定义 FMassNetworkIDFragmentFMassReplicatedAgentFragmentFMassReplicationViewerInfoFragmentFMassReplicationLODFragmentFMassReplicationParametersFMassReplicationSharedFragmentFMassReplicationGridCellLocationFragmentFMassInReplicationGridTagFMassReplicationParameters 包含 LODDistance、LODMaxCount、LODMaxCountPerViewer、UpdateInterval、BubbleInfoClass 和 ReplicatorClass。MassClientBubbleHandler.hTClientBubbleHandlerBase 负责添加、移除、标脏、客户端 PostReplicatedAdd/Change/Remove 等流程。

架构分析

Client Bubble 是“每个客户端看到的 Mass 世界切片”。服务器按 viewer 距离、LOD、数量上限和网格查找,把实体加入某客户端的 Bubble。Bubble Handler 管理网络 ID、Agent Handle、FastArray Item 和实体映射。客户端收到新增项后,可以创建对应 Mass Entity 或更新已有实体的数据。

联网设计要先回答三个问题:哪些数据需要服务器权威,哪些数据客户端可插值,哪些实体不需要同步。比如路人的精确心情、内部 StateTree 状态不一定要同步;位置、朝向、表现类型、动作状态可能需要。能不同步的不要同步,能低频的不要高频。

使用案例

一个路人复制数据可以这样拆:

USTRUCT()
struct FReplicatedCrowdAgent
{
    GENERATED_BODY()

    UPROPERTY()
    FMassNetworkID NetID;

    UPROPERTY()
    FVector_NetQuantize10 Location;

    UPROPERTY()
    FRotator Rotation;

    UPROPERTY()
    uint8 VisualState = 0;
};

服务器 Replicator 从 Mass Fragment 采样数据,写入 FastArray Item;客户端 Bubble Handler 在新增实体时用 Config Template 生成本地 Mass Entity,再把复制数据写入 Transform、Representation 或自定义 Fragment。远处实体可以只同步 Location 和 VisualState,近处才同步更细的动画状态。

项目落地

先只同步 Transform 和一个 VisualState,验证客户端出现、移动、离开 Bubble、重进 Bubble 都正确。第二步加入 LOD 更新间隔和数量上限。第三步才同步行为表现,例如挥手、排队、使用设施。最后再考虑客户端预测或插值。Mass 复制问题通常不是单个包错,而是 Bubble 进出、NetID 复用、实体销毁和表示切换的边界条件。

常见坑

不要把每个实体都转换成 replicated Actor。不要同步大型 Fragment 或内部状态机全部数据。不要忽略 LODMaxCountPerViewer,多人同屏时每个客户端的预算不同。不要忘记处理删除乱序,源码里有 AgentRemoveInterval 相关逻辑就是为了解决 add/remove 时序。不要让客户端本地生成的表现和服务器同步数据互相覆盖。

源码路径索引

  • MassReplication/Public/MassReplicationFragments.h
  • MassReplication/Public/MassClientBubbleHandler.h
  • MassReplication/Public/MassReplicationProcessor.h
  • MassReplication/Public/MassReplicationTrait.h