空间Cell:降频更新必须用运动包络兜住漏同步
自动关联目录:空间Cell:降频更新必须用运动包络兜住漏同步
核心判断:二维网格减少的是每连接候选数;把动态 Actor 的 Cell 更新改成每隔若干帧执行,会引入一段“位置已变、成员关系未变”的时间。没有运动包络或越界事件,这不是降精度,而是可能漏相关性。
一、业务冲突:动态对象很多,但并非每个对象每帧都值得搬 Cell
开放场景中的移动单位、投射物和可移动机关若每帧全部重算网格,会让 DS 的复制准备阶段按动态 Actor 总量增长;完全不更新又会让新进入范围的连接拿不到对象。目标不是简单降频,而是在明确的最大陈旧时间内维持候选集保守正确。
二、实际实现:网格、Cull 半径和 Dormancy 已经形成分层
实际复制图按位置与 Cull Distance 计算 Actor 覆盖的多个 Cell。动态 Actor 加入时立即登记,之后按固定帧模数批量刷新;静态 Actor 在初始化完成后进入静态桶,休眠变化时在静态列表与 Dormancy 节点之间迁移。静态桶还能继续按频率分组。
这些设计抓住了 UE 的关键成本:连接只 Gather 邻近 Cell;大 Cull 半径 Actor 可以跨 Cell;休眠对象不必承担动态更新。初始化未完成的静态 Actor 单独等待,也避免把半初始化对象放入复制图。
三、结构性缺陷:固定 K 帧没有表达最大位移
动态 Actor 在两次网格刷新之间最多移动 Vmax * K / FPS。旧 Cell 会产生多余候选,而新 Cell 缺少 Actor 会产生漏同步;Cull 半径偶然覆盖相邻 Cell,不等于对高速、传送和低帧率有证明。
待初始化静态列表若每帧全扫,长时间不 Ready 的对象会形成另一个 O(Pending) 热点。为避免空间 Bias 重建而把所有类都加入重建黑名单,引擎会把越界对象钳制在边界 Cell;它消除了整图重建和强制 GC 尖峰,但前提必须是世界边界明确,不能把“不会重建”当成“无限世界仍正确”。
四、目标设计:时间降频与事件快路并存
void TrackDynamic(NetEntity& e, float dt) {
float staleWindow = Scheduler.NextDelay(e.tier);
float motionMargin = e.maxSpeed * staleWindow + e.teleportMargin;
CellRange conservative = Grid.Cover(e.bounds.Expand(motionMargin));
if (e.teleported || !conservative.Contains(e.lastPublishedCell))
Grid.PublishNow(e, conservative);
else
Scheduler.Schedule(e, staleWindow);
}普通移动使用扩大后的保守 Cell 范围;跨 Cell、传送、速度等级变化和 Cull Distance 变化走事件快路。超出固定世界边界的对象进入 Overflow Node 或被明确拒绝,而不是静默钳制。Pending Static 使用初始化事件或分片审计队列,不能永久每帧全扫。
五、预算与证据
必须同时观测 dynamic_tracked、每帧 Cell 迁移数、网格准备耗时、旧 Cell 假阳性、漏相关性检测、最大 Cell 陈旧时间、Overflow 数、Pending 年龄和重建次数。故障测试至少包括高速穿越多个 Cell、瞬移、服务器掉帧、运行时修改 Cull Distance、Dormancy 唤醒和边界外生成。网格优化成立的标准不是“Prepare 更快”,而是更快且零错误漏选。