物理碰撞检测与触发器检测
Unity 物理碰撞检测总结
1. 物理碰撞的基本条件
要产生碰撞或触发检测,必须满足以下条件:
✔ 必要条件
- 至少一个物体拥有 Rigidbody(刚体)
- 两个物体都必须有 Collider(碰撞器)
2. Rigidbody 常用参数
2.1 基础属性
- Mass(质量):质量越大惯性越大
- Drag(空气阻力):影响移动阻力
- Angular Drag(角阻力):影响旋转阻力
- Use Gravity:是否受重力影响
2.2 Is Kinematic
- 启用后刚体不受物理引擎控制
- 可用脚本(Transform)直接移动
常用于: - 移动平台
- 配合 Joint 的受控物体
2.3 Interpolate(插值)
用于平滑刚体移动:
- None:不插值
- Interpolate:基于上一帧
- Extrapolate:基于下一帧预测
2.4 Collision Detection(碰撞检测模式)
用于防止快速物体穿透:
| 模式 | 说明 |
|---|---|
| Discrete | 默认模式,一般物体使用 |
| Continuous | 对快速物体检测静态物体 |
| Continuous Dynamic | 高成本,适用于高速物体 |
| Continuous Speculative | 成本低,推测性判断 |
2.5 Constraints(约束)
- Freeze Position:锁定位置移动
- Freeze Rotation:锁定旋转
3. Collider(碰撞器)
3.1 常用碰撞器
- BoxCollider
- SphereCollider
- CapsuleCollider
- MeshCollider(需设置 Convex 才可用于物理)
3.2 MeshCollider 使用规则
- 若用于物理碰撞,必须勾选 Convex
- 异形物体通常使用多个 Primitive Collider 组合
4. 物理材质(Physic Material)
4.1 基本属性
- Dynamic Friction(动摩擦):移动时的摩擦
- Static Friction(静摩擦):静止时的摩擦
- Bounciness(弹性):反弹能力
4.2 摩擦与弹性组合方式(Combine)
- Average:平均
- Minimum:最小
- Maximum:最大
- Multiply:相乘
5. 碰撞检测函数(Collision)
必须满足:
✔ 双方 Collider
✔ 至少一方 Rigidbody
✔ Collider 未勾选 Trigger
//物体首次碰撞发生接触 调用一次:
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.CompareTag("Player")
{
print($"和{collision.gameObject.name}碰撞了";
//获取Player物体上挂载的脚本
T t = collision.GetComponent<T>();
}
}
//物体碰撞接触后 每帧调用:
private void OnCollisionStay(Collision collision) {}
//物体分离碰撞接触时 调用一次:
private void OnCollisionExit(Collision collision) {}
6. 触发器检测函数(Trigger)
必须满足:
✔ 双方 Collider
✔ 至少一方 Rigidbody
✔ 一方 Collider 勾选 Trigger
//首次进入触发器范围 调用一次:
private void OnTriggerEnter(Collider other)
{
if(other.gameObject.CompareTag("Player")
{
print($"和{other.gameObject.name}碰撞了";
//获取Player物体上挂载的脚本
T t = other.GetComponent<T>();
}}
}
//进入触发器范围后 每帧调用
private void OnTriggerStay(Collider other) {}
//离开触发器范围时 调用一次
private void OnTriggerExit(Collider other) {}
7. 重要规则(非常关键)
✔(1)异形物体检测规则
1.父物体挂载刚体组件,父物体有 Rigidbody 后,物理引擎会把这个 Rigidbody 当作整个父子层级的刚体
2.子物体挂载碰撞器,并且设置为想要触发的标签,子物体可以挂载多个相同或不同碰撞器进行组合,使得符合子物体形状
3.进行if(other.gameObject.CompareTag("Player"))检测,检测的结果 other 是子物体
4.逻辑脚本挂载父物体还是子物体由游戏实际情况决定
可以挂载在父物体上,将脚本设置为单例,直接通过单例获取脚本,解决other获取的是子物体而不是父物体
可以挂载在子物体上,通过other.GetComponent获取脚本,不过要注意子物体是否是预制体,在多个场景下复用时,脚本的Update是否符合想要的效果
8. Trigger触发器检测和范围检测的区别
| 特性 | 范围检测 (Overlap/Check) | 触发检测 (Trigger) |
|---|---|---|
| 触发方式 | 玩家或逻辑主动调用,每帧检测 | 物理引擎自动调用,事件驱动 |
| 依赖组件 | 不依赖 Rigidbody | 必须有 Rigidbody(父物体或自身) |
| 灵活性 | 高,可自定义形状、范围、条件 | 中,受物理组件限制 |
| 典型应用 | 按键后技能释放、按键后玩家主动范围交互(按空格进入传送门) | 自动拾取道具、自动触发传送门 |
| 是否需要按键触发 | 非常建议使用,如果不使用就和自动触发一样,不如使用Trigger | 不需要,进入触发器就自动触发 |
| 控制权 | 由玩家完全控制 | 由物理事件控制 |

浙公网安备 33010602011771号