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 的云服务器上。这就是分层与相关性的价值:省钱省到肉里。
