该技能面向虚幻引擎 C++ 多人游戏开发,讲解如何实现服务器权威(server-authoritative)的网络复制。核心原则是:服务器持有权威状态并复制给客户端,客户端通过 RPC 向服务器发送意图;多数多人 bug 源于权威或复制配置错误,因此应先在 gameplay-framework 中确定状态所有权,再正确复制。
适用时机:将 Actor 状态(生命值、弹药、门、分数)复制给所有客户端;让客户端通过 RPC 请求服务器执行动作(开火、交互、技能);在 Replicated 与 ReplicatedUsing 之间选择,或选择 COND_* 条件;为大规模性能配置休眠、网络更新频率与相关性;诊断“PIE 单人正常、多人失效”问题;采用 Push Model 或 FFastArraySerializer 提升高负载复制效率。
权威与角色:每个 Actor 副本在各机器上有角色。ROLE_Authority 出现在服务器或独立模式,是权威副本,应在此做决策;ROLE_AutonomousProxy 出现在客户端自己的 Pawn 上,本地控制且可预测;ROLE_SimulatedProxy 出现在客户端其他 Actor 上,依据收到的复制模拟。HasAuthority() 内联为 GetLocalRole() == ROLE_Authority。Server RPC 在服务器执行,状态变更应在服务器发生并向下复制,客户端只发送意图。
Actor 复制设置:构造函数中设置 bReplicates = true 启用复制;SetReplicateMovement(true) 复制非 Character Actor 的变换;NetUpdateFrequency 控制每秒更新次数(5.5+ 用 SetNetUpdateFrequency);NetDormancy 设为 DORM_DormantAll 可初始休眠,修改属性前需调用 FlushNetDormancy。GameMode 为服务器独有;GameState 与 PlayerState 按设计可复制。运行时调用 SetReplicates(true) 会触发复制启动回调,Iris 项目(5.7+)应重写 OnReplicationStartedForIris 而非已弃用的 OnReplicationStarted。
属性复制:用 UPROPERTY(Replicated) 或 UPROPERTY(ReplicatedUsing=OnRep_X) 标记属性,并在 GetLifetimeReplicatedProps 中用 DOREPLIFETIME 或 DOREPLIFETIME_CONDITION 注册;复制仅从服务器流向客户端。OnRep 函数必须是 UFUNCTION,可带旧值参数,在客户端收到值时触发,用于更新 UI、播放受击特效等。只能在服务器设置复制属性,客户端修改仅本地有效并被丢弃。DOREPLIFETIME_CONDITION 可节省带宽。
RPC:Server RPC 由客户端调用、在服务器执行,目标 Actor 必须被该客户端拥有(其 Pawn、PlayerController 或 Owner 链可达),否则静默丢弃;Client RPC 由服务器调用、在拥有该 Actor 的客户端执行;NetMulticast 由服务器调用,在服务器及所有当前相关客户端执行,不会为后加入者重放,持久状态应改用复制属性加 OnRep。Reliable 保证送达与顺序,用于关键玩法调用;Unreliable 用于频繁的外观调用,可靠 RPC 泛滥会堵塞通道。所有接收不可信客户端参数的 Server RPC 按 Epic 规范应使用 WithValidation,_Validate 返回 false 会断开调用者。
所有权与相关性:Owner 决定哪个客户端可调用该 Actor 的 Server RPC,以及谁接收 COND_OwnerOnly 数据,可用 SetOwner 或生成参数 Owner 设置。相关性决定 Actor 只复制给相关连接,bAlwaysRelevant 可绕过,也可重写 IsNetRelevantFor。网络休眠中 DORM_DormantAll 的 Actor 在复制考察中被完全跳过,是最有效的服务器端优化之一。NetUpdateFrequency 与 NetCullDistanceSquared 应按类调整以平衡精度与带宽。
移动复制:ACharacter 与 UCharacterMovementComponent 自动处理移动与客户端预测,不要每帧手动 SetActorLocation,应通过 CMC 驱动输入。
多人测试:PIE 中设置 Number of Players > 1,Net Mode 选 Play As Listen Server 或 Play As Client,务必在多人 PIE 而非独立模式测试权威路径。控制台可用 net.DormancyEnable 0 调试时禁用休眠,NetEmulation.PktLag 100 模拟 100ms 延迟。
常见问题:在客户端修改复制状态不会传播;忘记 GetLifetimeReplicatedProps 或 DOREPLIFETIME 会导致属性静默不复制;对非所属 Actor 调用 Server RPC 会静默丢弃;用 Multicast 传后加入者状态会丢失;可靠 RPC 泛滥会阻塞复制;休眠中修改复制属性会被跳过,须先 FlushNetDormancy;GameMode 仅服务器可见,客户端可见状态应放 GameState;OnRep 只在客户端自动触发,服务器需同样副作用时应显式调用。
版本说明:5.5+ 直接写 NetUpdateFrequency 已弃用,改用 SetNetUpdateFrequency 与 GetNetUpdateFrequency。5.8 中 Iris 复制系统仍为 beta 且需显式开启(net.Iris.UseIrisReplication,默认关闭),与现有属性/RPC 模型共存;Iris 下 Push Model 使用 DOREPLIFETIME_WITH_PARAMS_FAST 加 bIsPushBased = true。资料还列有属性复制、RPC、复制条件与 Push Model、Fast Array 等深入参考,以及引擎源码与官方文档链接,并关联 gameplay-framework、actors-and-components、character-and-movement、gameplay-ability-system 等技能。