碰撞预设
├─ Collision Enabled 是否参与查询或物理模拟
├─ Object Type 自己属于哪一类物体
└─ Collision Responses 遇到不同类型时如何响应
├─ Ignore
├─ Overlap
└─ Block
碰撞预设的三个核心部分
一、Collision Enable
Component->SetCollisionEnabled(
ECollisionEnabled::NoCollision
);
决定这个组件是否参与碰撞,以及参与哪一种碰撞系统。
1.No Collision
表示组件完全不参与碰撞,不会参与以下:
- Line Trace
- Sweep
- Overlap 查询
- 物理模拟
- 刚体碰撞
- Hit 检测
它不进入碰撞查询结构和物理模拟结构,所以通常是性能开销最低的设置。
2.Query Only
只参与查询,不参与刚体物理模拟
它可以检测玩家是否进入,但本身不作为一个受力、受重力影响的刚体。
查询主要包括:
- Line Trace
- Sphere Trace
- Box Trace
- Sweep
- Overlap
- 角色移动时的碰撞查询
官方文档将 Query Only 定义为只用于射线、Sweep 和 Overlap 等空间查询,不用于刚体及约束模拟。
3.Physisc Only
只参与物理模拟,不参与普通空间查询。这种模式相对少见,更多用于一些只需要物理模拟、不需要游戏查询的对象或次级运动系统。
它可以参与:
- 刚体模拟
- 物理约束
- 物理接触
但不能用于:
- Line Trace
- Sweep 查询
- Overlap 查询
4.Query and Physics
表示既参与空间查询,也参与物理模拟。适合于可被碰撞检测的带有物理属性的物体。
二、ObjectType
Component->SetCollisionObjectType(ECC_Pawn);
表示该组件再碰撞系统中被归类为什么物体(可以认为是身份标签)
1.WorldStatic
表示不会移动的世界物体,如地面、墙壁、固定场景静态网格体。
建议将不会移动的 Actor,例如大部分场景静态网格体,设置为WorldStatic。
2.WorldDynamic
表示会通过动画、程序逻辑移动的世界物体,例如:
- 自动门
- 升降平台
- 旋转机关
- 移动墙壁
- 触发区域
- 通过代码移动的方块
3.Pawn
代表玩家、AI或其他Pawn类型的实体,一般来说,ACharacter 的胶囊体会使用 Pawn 类型。
4.PhysicsBody
表示由物理模拟驱动的物体。
- 可以滚动的球
- 可以推动的箱子
- 开启物理模拟的木桶
- 可掉落道具
5.Vehicle
代表载具
6.Destructible
代表可被破坏的物体。
- 可破坏墙壁
- 可碎裂物体
- Chaos 破坏对象
三、Collision Response
当前组件对其他对象或检测的相应。
Component->SetCollisionResponseToChannel(
ECC_Pawn,
ECR_Ignore
);
1.Ignore
表示忽略,想过通常是:
- 不阻挡
- 不产生 Overlap
- 不产生 Hit
- 可以直接穿过
2.Overlap
表示允许穿过,但可以产生重叠事件。
- 不阻挡
- 不产生 Overlap
- 不产生 Hit
- 可以直接穿过
3.Block
表示阻挡
- 玩家不能穿过
- 可能发生阻挡碰撞
- 可以产生 Hit 事件
- Sweep 运动时可能停止在碰撞位置
四、Trace Responses和ObjectResponses
TraceResponses:对检测通道的响应
Visibility:Block
当一条Visibility通道的检测射线经过该对象时,该对象会阻挡这条射线。
Camera:Block
该对象的碰撞组件会阻挡Camera通道的检测。即当摄像机与碰撞组件发生碰撞时,然后会缩短摇臂长度,避免穿墙。
Object Responses:对其他对象类型的响应
如该组件WorldDynamic = Block,该碰撞组件会阻挡ObjectType为WorldDynamic的对象;若该组件Pawn = Block,该碰撞组件会阻挡ObjectType为Pawn的对象。
五、总结
Collision Enabled
└── 我是否参与碰撞和查询
Object Type
└── 我自己是什么对象类型
Collision Responses
├── Trace Responses
│ ├── Visibility:我如何响应 Visibility 检测
│ └── Camera:我如何响应 Camera 检测
│
└── Object Responses
├── WorldStatic:该对象如何响应其他 WorldStatic 对象
├── WorldDynamic:该对象如何响应其他 WorldDynamic 对象
├── Pawn:该对象如何响应其他 Pawn 对象
├── PhysicsBody:该对象如何响应其他 PhysicsBody 对象
├── Vehicle:该对象如何响应其他 Vehicle 对象
└── Destructible:该对象如何响应其他 Destructible 对象
CPP中的用法
1. Collision Enabled
MeshComp->SetCollisionEnabled(
ECollisionEnabled::QueryAndPhysics
);
MeshComp->SetSimulatePhysics(true);
若要开启物理碰撞,需要将物理模拟打开。
ECollisionEnabled::NoCollision
ECollisionEnabled::QueryOnly
ECollisionEnabled::PhysicsOnly
ECollisionEnabled::QueryAndPhysics
2. Object Type
MeshComp->SetCollisionObjectType(
ECC_WorldStatic
);
| WorldStatic | ECC_WorldStatic |
| WorldDynamic | ECC_WorldDynamic |
| Pawn | ECC_Pawn |
| PhysicsBody | ECC_PhysicsBody |
| Vehicle | ECC_Vehicle |
| Destructible | ECC_Destructible |
3. Collision Responses 统一设置
碰撞相应有三个枚举值:
| Ignore | ECR_Ignore |
| Overlap | ECR_Overlap |
| Block | ECR_Block |
若设置Collision Responses,则是对所有通道进行统一设置,例:
MeshComp->SetCollisionResponseToAllChannels(
ECR_Block
);
此时会同时设置:
Visibility Block
Camera Block
WorldStatic Block
WorldDynamic Block
Pawn Block
PhysicsBody Block
Vehicle Block
Destructible Block
自定义通道 Block
4.单独设置每一行
SetCollisionResponseToChannel()
对于TraceResponses中有两个参数Visibility和Camera,要分别设置:
MeshComp->SetCollisionResponseToChannel(
ECC_Visibility,
ECR_Block
);
MeshComp->SetCollisionResponseToChannel(
ECC_Camera,
ECR_Block
);
第一个参数为通道类型,第二个参数为通道状态。
对于ObjectResponses,有众多参数,依旧是分别设置:
MeshComp->SetCollisionResponseToChannel(
ECC_WorldStatic,
ECR_Block
);
5. 常见写法:先设置全部,再修改个别通道
// 先给所有通道一个基础响应
MeshComp->SetCollisionResponseToAllChannels(
ECR_Block
);
// 再单独修改特殊通道
MeshComp->SetCollisionResponseToChannel(
ECC_Camera,
ECR_Ignore
);
MeshComp->SetCollisionResponseToChannel(
ECC_Pawn,
ECR_Overlap
);
最终结果为:
Visibility Block
Camera Ignore
WorldStatic Block
WorldDynamic Block
Pawn Overlap
PhysicsBody Block
Vehicle Block
Destructible Block
6. 使用FCollisionResponseContainer一次性设置
可以先建立一个碰撞响应容器,再一次应用:
#include "Engine/EngineTypes.h"
FCollisionResponseContainer Responses;
// 所有通道先设置为 Block
Responses.SetAllChannels(ECR_Block);
// 单独修改某些通道
Responses.SetResponse(ECC_Camera, ECR_Ignore);
Responses.SetResponse(ECC_Pawn, ECR_Overlap);
// 应用给组件
MeshComp->SetCollisionResponseToChannels(Responses);



