5.2 复制分层:属性、RPC 与相关性

核心结论

复制不是"把数据全部同步给所有人",而是分层选择性同步:属性复制(状态)、RPC(事件)、相关性(谁需要看见)。三者按需组合,才能把网络流量从"爆炸"压到"可玩"。官方的 Actor 休眠(https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/actor-network-dormancy-in-unre-559d)与带宽优化(https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/performance-and-bandwidth-tips-d100)是这一篇的依据。

三层工具的分工

工具 用途 例子 开销
属性复制 状态(持续存在的) 血量、位置、装备 Tag 按变化发送
RPC 事件(一次性的) 受击粒子、开火、开门 瞬时
相关性 谁需要收到 距离内/同房间的 Actor 连接级过滤

核心划分纪律: - 持续状态 -> 属性(如血量、State.Dead Tag)。 - 一次性事件 -> RPC 或 GameplayCue(如命中反馈)。 - 不是每个连接都需要 -> 相关性。

相关性配置(Roguelike 尤其重要)

设置 我的值 说明
NetUpdateFrequency 10~30(默认太高) 远处的怪降到 5
bOnlyRelevantToOwner UI/玩家专属 不给别人
相关距离 房间半径 门槛外不同步
Dormancy 远处的怪 完全暂停复制(https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/actor-network-dormancy-in-unre-559d)

Roguelike 的天然优势:房间是分隔的——只有同房间的玩家互相相关。把相关性按房间(Volume/区域)划分,流量直接降一个数量级。

复制分层(对齐各系统)

数据 复制方式 说明
玩家状态(血量等) 属性 + OnRep GAS 的属性集
GA 事件 GameplayCue 自动分发 不用自己写 RPC
怪物状态 属性(相关时) 休眠屏蔽
掉落物 属性 + 相关性 房间内
任务进度 GameState/PlayerState 属性 一致性
飘字/特效 本地或 GC 不走复制
输入 客户端->服务器(意图) Server RPC

一个观察:GAS 的事件做了几件 RPC 的工作——GC 的分发、属性的复制已经覆盖 80% 同步需求。先把 GAS 的网络功能用满,再补自定义 RPC。

常见坑与解法

坑 1:流量爆炸(50KB/s 起步)

原因:所有属性默认 NetUpdateFrequency=100,全部全量。

解法: - 按重要性分级(玩家 33、怪 10、掉落 5)。 - Replication Graph(https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/replication-graph-in-unreal-en-6d0e)对大世界项目是必须的(空间分区一次性解决相关性)。 - Dormancy:远处的怪直接休眠。

坑 2:属性同步"同值不同命"(被覆盖)

原因:多个属性 replicates 到同一目标但顺序不定。

解法:属性的复制顺序确定性:组(Group)与优先级(RepLayout 的排序),重要先发。中小项目不用管,GAS 已经排好。

坑 3:模拟代理出现"瞬移"

原因:休眠的 Actor 醒来时位置差大。

解法:醒来时先补发一次全量快照;客户端用平滑插值处理(bNetworkSmoothing)。

坑 4:RPC 的可靠性滥用

原因:所有 RPC 都设 Reliable。

解法: | RPC 类型 | Reliable | 用途 | |---|---|---| | Server 攻击意图 | Reliable | 丢了 = 攻击丢失 | | 开火特效 | Unreliable | 丢了 = 一次画面缺 | | 受击反馈 | Unreliable(或 GC) | 同上 | | 关键状态变更 | Reliable | 死亡/结算 |

Reliable 的代价:阻塞与顺序保证,全 Reliable 会拖慢整个网络。80% 应该是 Unreliable。

相关节点速查

  • 官方网络概览:https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/networking-and-multiplayer-in-e475
  • 带宽优化:https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/performance-and-bandwidth-tips-d100
  • 休眠:https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/actor-network-dormancy-in-unre-559d
  • 复制图:https://www.wanxiangyundang.top/read/unreal-engine-5-8-docs/replication-graph-in-unreal-en-6d0e

与 0403 对象池的联机版

池化怪物与复制的冲突:池里 Disable 的怪,联机时怎么处理?我的答案:池只在本地表现层,网络上的"生成/销毁"走标准复制(服务器 Spawn,客户端的池只是本地表演的包装)。联机时不要把"池"概念扩展到网络层——那是自找麻烦。

心得:我们项目第一次做联机测试时流量 40KB/s,按上面分层清完后 8KB/s——8 个人能跑在 1Mbps 的云服务器上。这就是分层与相关性的价值:省钱省到肉里。