WalkingSurface 优化实现逻辑

图示 / 动图版完整文档

在线版(网页知识库):打开完整文档(12 图 + 7 动图)
本地版:同目录 WalkingSurface 优化实现逻辑.html(单文件,12 张图示与 7 张 GIF 已内嵌,可离线打开)。原始图片在 WalkingSurface_assets/。
3D 版:WalkingSurface 3D 几何图示(Three.js,可旋转/切图层/播放动画)。本文件是 Obsidian 检索用索引与速查。代码基准:F:\PX_Trunk\PX\Plugins\WalkingSurface + GPCharacterMovementComponent.cpp(UE 5.8.2)。

一句话

用 Editor 离线烘焙的紧凑只读结构替代 3P 包间外推帧里的 ComponentSweepMulti 物理扫掠:Clear 直接无 sweep 落位、Hit 截断落位、Fallback 回退 UE。收益来自「预计算 + 缓存局部性 + 早退剪枝」,安全边界靠「不可信就回退」。

三接口已退役

专题文档里的 FindFloor / ProbeForward / MoveAlongFloor「三接口」是 v5–v7 旧设计。当前代码(kBuildVersion = 13)中 ProbeForward、MoveAlongFloor 运行接口与 FEdgePrim / EdgeBVH / FWS*Result 全库 0 命中;生产实现 = FindFloor + SweepHorizontal。旧 BlockEdges(净空轮廓派生)v13 已删除,当前 G1 几何驱动重设计 = FBlockEdge(真实碰撞面 Z)+ FGroundClue / FGroundClueNode BVH。

核心优化点

层做法位置
内存FWSHotArena 一次连续分配 + 大页 + 64B 对齐;FWSTileHot 恰好一条缓存行Runtime.h:303-335
索引4-ary BVH:16B 量化 3D AABB 节点,4 子节点 = 64B 对齐;树深 log4 减半,Z 同量化可枝级剪枝Runtime.h:66-89
访存FConvexRecHeader 24B + 顶点连续 blob → 叶子到顶点一跳访存;FWSInlinePoly int32 cm / int64 包围圆 / 边斜率 <<20 定点,热路径零浮点Runtime.h:91-141
查询FindFloor 两种模型(LineTrace 最快 / Capsule 对齐 UE 胶囊 sweep,`Zsweep = Zplane + R(N
精度B5 槽位预展开 O(1) 取值,判定与 Reference 逐位一致Runtime.h:381-393
剪枝SweepHorizontal:先 patch 扫掠得首命中,再只在 [0, 首命中+容差] 邻域查烘焙线索Runtime.h:526-534
缓存稠密 tile 网格直接寻址替代 TMap;per-agent lastPatch 短路 + Generation 代际失效;WarmupQueryData 预取(但消不掉 I-cache 冷启动税)Runtime.h:504-515, QueryTypes.h:52-63

常量(易错)

kGridCellSize = 20 cm;  kTileWorldSizeX/Y = 3200 cm (32m, 160×160 格)   ← v6 起由 16m 改 32m
kBuildVersion = 13;  kPrecisionLayoutVersion = 18
StepLength = 100 cm;  MinProgressEps = 1 cm(配置残留,已无 MoveAlongFloor 实现)
kCollectSlopeCos = 0.015;  kStandableSlopeCos = 0.71
kFloorTrustMinDist = 1.8;  kFloorTrustMaxDist = 2.5;  法线余量 0.02

采信与回退

  • IsAuthoritativeFloor:法线 N.z ≥ WalkableFloorZ + 0.02 且 FloorDist ∈ [1.8, 2.5](UE AdjustFloorHeight 稳态 [1.9, 2.4] 两端放宽 0.1)。区间外回退 UE 物理 FindFloor。
  • EWalkingSurfaceSweepFallback:MissingData / InvalidInput / OutsideCoverage / VerticalSurface / UncollectedSurface / NoGroundSupport / InitialOverlap / OuterBoundaryContact / PrecisionBudget / RoundShape / BudgetExceeded … 全部指向「改走 UE」。
  • 只覆盖静态几何、水平位移、胶囊碰撞契约一致;动态阻挡、竖直分量、元数据需求一律回退。

生产接入(GP CMC 已落地,CVar 默认关)

CVar默认模式
gp.Movement.WalkingSurfaceHorizontalSweep00 关 / 1 Clear+Hit / 2 仅测量 / 3 仅 Clear
gp.Movement.WalkingSurfaceFindFloor00 关 / 1 完全替换 / 2 仅高度图回退
gp.Movement.SimProxySweepSingle1SweepSingle 找首阻挡后 bSweep=false 落位
...HoverTolCm25悬空放宽,只加速 Clear
px.SimProxy.MovementEnginePure0整链路回退 UE 原生

接入点:SimProxyMoveSmoothSweep_WalkingSurface(GPMC.cpp:11348)、FindFloor_WalkingSurface(:11825)、统计 FWalkingSurfaceSweepRuntimeStats(:11254)。

实测结论(口径很重要)

  • 70K 语料:假 Clear 0 / 多报 0;停位误差 max 0.0075 cm;地面短步采信 78.1% → 83.6% → 83.7%(迭代 12→13→b10)。
  • 净开销迭代 12:0.75× UE(地面)/ 0.94×(全部);迭代 13:采信 845 ns vs UE 4630 ns(0.18×),地面 0.556×UE。
  • tile 级线性扫 → 8×8 子格:23.8 → 8.2 µs;生产总计 23.9 → 8.45 µs vs UE 11.6 µs。
  • ⚠️ 全部为 MS4 地图 + Editor Development + 离线 70K 语料,不是真实 PIE 帧内收益(≥50% 目标实测「未找到」、calls=0 无样本);冷缓存约 1%/2.5% 中位数慢于 UE,30fps 长步长退化。
  • ⚠️ SweepHorizontal 整体 175~240 µs 中 99% 是 Editor 校验夹具,不是生产运行时开销。

状态

代码已落地但 CVar 默认 0 = 生产未开启;专题 README 标注未正式启用、未接生产 GP、22 文件 3114 行未提交、地图未保存;真实帧内收益未验证。

相关