碰撞与查询
自动关联目录:碰撞与查询
官方依据:官方 Gameplay Systems 正文点名 Physics 包含 Collision 与 Raycasts(已核实)。
1. 定位
碰撞查询是游戏里用得最多的物理操作:射击判定、视线检测、落地检测、爆炸范围、交互拾取。
一句话定位:绝大多数项目只需要"查询",不需要"模拟"。把这两件事分开,是物理性能的第一道分水岭。
2. 碰撞设置
| 概念 | 说明 |
|---|---|
Collision Enabled | NoCollision / QueryOnly / PhysicsOnly / QueryAndPhysics |
Object Type | 对象类别(WorldStatic / Pawn / …) |
Collision Response | 对每个 Channel 的响应:Ignore / Overlap / Block |
Trace Channel | 射线使用的通道 |
Collision Preset | 以上组合的预设 |
原则:能 QueryOnly 就不要 QueryAndPhysics——不需要模拟的物体开着物理,白白付出模拟与同步成本。
通道设计要提前规划:通道数量有限,且"哪个通道检测什么"一旦混乱,后面全是 Ignore 打补丁。
3. 三种查询
| 类型 | 接口 | 用途 |
|---|---|---|
| Line Trace | LineTraceSingle / Multi | 射线(射击、视线) |
| Shape Sweep | SweepSingle / Multi | 带体积扫掠(角色移动、连续判定) |
| Overlap | OverlapBlocking / Multi | 范围检测(爆炸、拾取) |
FCollisionQueryParams Params(SCENE_QUERY_STAT(MyTrace), /*bTraceComplex=*/false);
Params.AddIgnoredActor(GetOwner()); // 忽略自身
FHitResult Hit;
bool bHit = GetWorld()->LineTraceSingleByChannel(
Hit, Start, End, ECC_GameTraceChannel1, Params);| 参数 | 说明 |
|---|---|
Trace Channel / Profile Name | 用通道还是配置 |
bTraceComplex | 用三角形精度(更准但明显更慢) |
Query Params | 忽略自身/只命中某类 |
DrawDebugType | 调试可视化(ForDuration / Persistent) |
4. 性能要点
| 要点 | 说明 |
|---|---|
| 加通道过滤 | 最便宜的优化 |
避免 bTraceComplex | 除非真的需要三角形精度 |
| 限制返回数量 | Multi 会返回全部命中 |
| 降低频率 | 不必每帧 Trace |
| 异步 Trace | 大量射线时用异步版本 |
| 简化碰撞体 | 用简单形状而非复杂网格 |
| 复杂网格做碰撞 | 慢且行为怪异(应另建简化碰撞体) |
热路径上的 Trace(如武器射线):过滤 + 非复杂 + Single 而非 Multi。
5. 代价与权衡
| 设计 | 收益 | 代价 | 什么时候不该用 |
|---|---|---|---|
QueryAndPhysics | 又能查又能模拟 | 模拟与同步成本 | 不需要模拟时必须关掉 |
bTraceComplex | 精确到三角形 | 成本显著上升 | 大多数判定用简单碰撞体足够 |
| Multi Trace | 拿到所有命中 | 数量不可控 | 只要第一个就用 Single |
| Sweep 代替 Line | 连续检测,不会穿薄物体 | 比 Line 贵 | 高速小物体才需要 |
| 异步 Trace | 不阻塞 | 结果延迟一帧或更多 | 需要同帧结果时不可用 |
| 每次都新建 QueryParams | — | 少量开销,热路径可缓存 | — |
6. 踩坑与排查
| 坑 | 现象 | 怎么验证 |
|---|---|---|
| 没忽略自身 | 打到自己 | AddIgnoredActor / AddIgnoredComponent |
| 复杂网格做碰撞体 | 慢、行为怪 | 检查碰撞体是否为简化形状 |
| Trace 通道选错 | 该命中的没命中 | 检查通道与 Response |
忘了 QueryOnly | 白付模拟成本 | 检查 Collision Enabled |
| 在构造函数里 Trace | World 还不可用(见 UObject) | 移到 BeginPlay 之后 |
| 每帧多条 Multi Trace | 卡顿 | 降频 + Single + 过滤 |
| 高速物体穿透 | 用 Line 而非 Sweep | 改用 Sweep 或加大步长检测 |
| 异步 Trace 结果用错帧 | 逻辑时序错 | 明确异步的到达时机 |
7. 排查顺序
1. 打不到?→ 通道 Response + 是否忽略自身
2. 打到自己?→ AddIgnoredActor
3. 慢?→ bTraceComplex / Multi / 频率 / 碰撞体复杂度
4. 穿透?→ 用 Sweep
5. 看不到?→ DrawDebugType 可视化确认起点终点与命中8. 调试
| 手段 | 用途 |
|---|---|
DrawDebugType | 画出射线与命中点 |
Show > Collision | 显示碰撞体 |
pxvis collision / 物理调试视图 | 物理调试绘制 |
stat physics / stat collision | 物理与碰撞统计 |
参考
- 刚体与 Chaos 破坏 · 物理与网络同步
- UObject(构造函数里不能做 Trace)
许可协议:CC BY
作者:Davids
本文链接:https://hustjjd.github.io/86f0aeca.html
更新于:2026年10月10日