场景物体穿插是指两个或多个三维模型在运行时出现了几何体重叠,从摄像机视角看就像互相挤进对方内部,这种现象在游戏、仿真和数字孪生中非常破坏真实感。造成穿插的核心原因通常有两种:一是逻辑层直接设置坐标时未做边界判断;二是物理引擎的步长过大,导致快速移动的物体在一帧之内跨过了另一物体的表面。要从根本上解决,必须同时理解碰撞检测与物理模拟两套机制,并让它们协同工作。

碰撞检测的基础方法与适用边界
碰撞检测负责回答“两个物体现在是否相交”这个问题。最基础的办法是轴对齐包围盒(AABB),它用物体在三个轴上的最大最小值构成一个长方体,只要两个长方体的区间在任意轴上不重叠,就判定为分离。AABB计算极快,适合大量动态物体做粗筛,但它的缺点是无法贴合倾斜或细长模型,容易产生误报。
当AABB通过之后,通常会进入更精细的阶段,例如有向包围盒(OBB)或凸包(Convex Hull)检测。OBB允许盒子随物体旋转,贴合度更高;凸包则把复杂网格简化成最少顶点的凸多面体,用分离轴定理(SAT)判断穿插。需要注意的是,凹多边形不能直接用SAT,必须先拆成多个凸部件。下面是一段用伪代码表达AABB相交判断的逻辑:
struct AABB {
float minX, minY, minZ;
float maxX, maxY, maxZ;
};
bool isOverlap(const AABB& a, const AABB& b) {
// 任意轴上区间不重叠则分离
if (a.maxX < b.minX || a.minX > b.maxX) return false;
if (a.maxY < b.minY || a.minY > b.maxY) return false;
if (a.maxZ < b.minZ || a.minZ > b.maxZ) return false;
return true; // 所有轴均重叠,判定相交
}
在实际项目中,往往会组合使用:先用AABB做全局 broad phase,再用OBB或凸包做 narrow phase。这种分层方式既控制了性能开销,也保证了精度。如果场景里物体数量极大,还可以引入空间哈希或八叉树,减少不必要的两两比对。
物理模拟如何消除已发生的穿插
物理模拟不只是检测,它会根据碰撞结果主动修改物体的速度与位置。在引擎中,每个参与模拟的网格会被挂上刚体(Rigidbody)组件,并赋予质量、阻力和碰撞体(Collider)。当求解器发现两个碰撞体重叠,会计算穿透深度与法线,然后施加一个将物体沿法线推开的修正位移,同时生成反弹或摩擦的冲量。
如果仅依赖离散检测(Discrete),物体以极高速度移动时,可能在上一帧还在外侧、下一帧已深陷内部,求解器虽能推出去但会出现明显抖动。此时应开启连续碰撞检测(CCD),引擎会为快速物体生成扫掠体(swept volume),提前在轨迹上做相交测试。以下代码展示了在常见引擎中开启刚体连续检测属性的写法:
using UnityEngine;
public class MoveSetup : MonoBehaviour {
void Start() {
Rigidbody rb = GetComponent<Rigidbody>();
// 开启连续动态检测,防止高速穿透
rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
rb.mass = 1.2f;
rb.drag = 0.1f;
}
}
除了参数设置,物理层的层级(Layer)过滤也很关键。可以把地面、墙体设为静态碰撞体,把角色和道具设为动态,并通过碰撞矩阵关闭不重要的交互,例如飘落的树叶不需要和子弹做检测。这样既能减少计算量,也能避免无关物体被意外推开。当多物体堆叠时,适当增大求解器迭代次数可让分离更稳定,代价是单帧耗时略有上升。
综合方案与常见误区
很多团队在看到物体穿插后,第一反应是每帧手动把坐标拉回边界,这种做法属于逻辑补丁,没有考虑速度方向,物体会被卡在表面无法自然滑动。正确思路应是:碰撞检测提供“是否相交”的信号,物理模拟接收信号并输出符合力学规律的响应。二者缺一不可,仅检测不模拟会看见物体互相嵌入,仅模拟不检测则求解器无事可做。
另一个常见误区是认为碰撞体形状必须和可见网格完全一致。高精度网格碰撞体开销巨大,通常做法是使用简化网格或基本几何体组合。例如一个弯曲的管道可用多个胶囊体拼接,角色可用胶囊体加球体的混合。下面给出一张常见碰撞体选型参考:
| 物体特征 | 推荐碰撞体 | 说明 |
|---|---|---|
| 方形箱子 | 盒体 | 贴合且计算便宜 |
| 圆形角色 | 胶囊体 | 支持站立与滚动 |
| 不规则静态场景 | 凸包或网格 | 静态可承受更高精度 |
在调试阶段,应打开引擎的碰撞体可视化,确认简化形状覆盖了关键区域。若仍有偶发穿插,优先检查物理步长是否过长,或刚体是否误设为运动学(Kinematic)而导致不参与求解。把检测频率与渲染频率解耦,用固定时间步推进物理,能显著提升稳定性。
collision_detectionphysics_simulationobject_interpenetration修改时间:2026-08-17 19:46:17