U1L13-1——物理系统之刚体
U1L13-1——物理系统之刚体
刚体 ** (Rigidbody)**
刚体 (Rigidbody) 是实现游戏对象的物理行为的主要组件。连接刚体后,对象将立即响应重力。
如果还添加了一个或多个__碰撞体__组件,则游戏对象会因发生碰撞而移动。
由于刚体组件会接管附加到的游戏对象的运动,因此不应试图借助脚本通过更改变换属性(如位置和旋转)来移动游戏对象。
相反,应该施加力来推动游戏对象并让物理引擎计算结果。
在某些情况下,可能希望游戏对象具有刚体,并让刚体的运动摆脱物理引擎的控制。
例如,可能希望直接从脚本代码控制角色,但仍允许触发器检测角色(请参阅碰撞体主题下的_触发器_)。
脚本产生的这种非物理运动称为_运动学_运动。刚体组件有一个名为 Is Kinematic 的属性,
该属性可以让刚体摆脱物理引擎的控制,并允许通过脚本以运动学方式来移动刚体。
可以通过脚本来更改 Is Kinematic 的值,从而为某个对象开启和关闭物理引擎,但这会产生性能开销,应谨慎使用。
有关这些组件的设置和脚本选项的更多详细信息,请参阅刚体和 2D 刚体参考页面。
刚体参数
碰撞产生的必要条件:两个物体都有碰撞器、至少一个物体有刚体

-
Mass - 质量(默认为千克)
质量越大惯性越大
-
Drag - 空气阻力
根据力移动对象时影响对象的空气阻力大小,0 表示没有空气阻力
-
Angular Drag - 根据扭矩旋转对象时影响对象的空气阻力大小
0 表示没有空气阻力。
-
Use Gravity - 是否受重力影响
-
Is Kinematic - 是否是运动学物体
如果启用此选项,则对象将不会被物理引擎驱动,只能通过 (
Transform) 对其进行操作。对于移动平台,或者如果要动画化附加了 HingeJoint 的刚体,此属性将非常有用。 -
Interpolate - 插值运算,让刚体物体移动更平滑
- None:不应用插值运算
- Interpolate:根据前一帧的变换来平滑变换。
- Extrapolate:差值运算,根据下一帧的估计变换来平滑变换。
-
Constraints - 约束 - 对刚体运动的限制
- Freeze Position - 有选择地停止刚体沿世界 X、Y 和 Z 轴的移动。
- Freeze Rotation - 有选择地停止刚体围绕局部 X、Y 和 Z 轴旋转。
-
Collision Detection - 碰撞检测模式
不同原理碰撞检测各有优劣,详见下方:物理碰撞检测类型

- Discrete(离散检测)
- Continuous(连续检测)
- Continuous Dynamic(连续动态检测)
- Continuous Speculative(连续推测式检测)
物理碰撞检测类型
-
Discrete(离散检测)
对场景中的所有其他碰撞体使用离散碰撞检测。其他碰撞体在测试碰撞时会使用离散碰撞检测。用于正常碰撞(这是默认值)
原理:每个物体只在 固定物理步长的采样点 检查是否与其他碰撞体重叠
- 优点:性能最好,开销最小
- 缺点:高速小物体可能在两帧之间跳过另一个碰撞体,出现穿透现象
- 适用场景:绝大多数常速移动的物体(角色、箱子、环境物件)
-
Continuous(连续检测)
对动态碰撞体(具有刚体)使用离散碰撞检测,并对静态碰撞体(没有刚体)使用连续碰撞检测。
设置为连续动态 (Continuous Dynamic) 的刚体将在测试与该刚体的碰撞时使用连续碰撞检测,其他刚体将使用离散碰撞检测。
(此属性对物理性能有很大影响,如果没有快速对象的碰撞问题,请将其保留为 Discrete 设置)原理:在两帧之间会额外做 运动轨迹的扫掠检测(sweep test),以减少穿透
- 优点:大幅降低高速物体穿透的概率
- 缺点:CPU 开销比 Discrete 高
- 适用场景:非主角的小型高速物体(例如子弹、飞镖、投射物)
-
Continuous Dynamic(连续动态检测)
性能消耗最高
对设置为连续 (Continuous) 和连续动态 (Continuous Dynamic) 碰撞的游戏对象使用连续碰撞检测。
还将对静态碰撞体(没有刚体)使用连续碰撞检测。对于所有其他碰撞体,使用离散碰撞检测。
用于快速移动的对象。原理:比 Continuous(连续检测) 更严格,专门用于高速移动的刚体,它会检测所有 Continuous (连续检测)、Continuous Dynamic (连续动态检测)的物体
- 优点:最稳妥地避免穿透
- 缺点:开销最高,不适合大规模使用
- 适用场景:关键的高速动态物体(例如主角手里的高速挥舞武器、主角发射的重要投射物)
-
Continuous Speculative(连续推测检测)
对刚体和碰撞体使用推测性连续碰撞检测。该方法通常比连续碰撞检测的成本更低。
原理:一种相对新的模式(比 Continuous(连续检测) 更轻量),会在下一帧前预测可能的碰撞,即使物体很小很快,也能避免大多数穿透
- 优点:比 Continuous Dynamic(连续动态检测) 更省性能;避免了很多小物体穿透
- 缺点:推测结果可能带来误判(没撞上也认为撞上了),偶尔出现虚假碰撞
- 适用场景:中高速物体,既需要避免穿透,又不想消耗太多性能的情况
不同碰撞检测类型碰撞体相互使用的碰撞检测类型如下
| 无刚体碰撞盒 | Discrete (离散检测) |
Continuous (连续检测) |
Continuous Dynamic (连续动态检测) |
Continuous Speculative (连续推测检测) |
|
|---|---|---|---|---|---|
| 无刚体碰撞盒 | 不检测碰撞 | Discrete | Continuous | Continuous | Continuous Speculative |
| Discrete (离散检测) |
Discrete | Discrete | Discrete | Discrete | Continuous Speculative |
| Continuous (连续检测) |
Continuous | Discrete | Discrete | Continuous | Continuous Speculative |
| Continuous Dynamic (连续动态检测) |
Continuous | Discrete | Continuous | Continuous | Continuous Speculative |
| Continuous Speculative (连续推测检测) |
Continuous Speculative | Continuous Speculative | Continuous Speculative | Continuous Speculative | Continuous Speculative |
性能消耗关系:Continuous Dynamic > Continuous Speculative > Continuous > Discrete
刚体睡眠
当刚体移动速度低于规定的最小线性速度或转速时,物理引擎会认为刚体已经停止。
发生这种情况时,游戏对象在受到碰撞或力之前不会再次移动,因此将其设置为“睡眠”模式。
这种优化意味着,在刚体下一次被“唤醒”(即再次进入运动状态)之前,不会花费处理器时间来更新刚体。在大多数情况下,刚体组件的睡眠和唤醒是透明发生的。
但是,如果通过修改__变换__位置将静态碰撞体(即,没有刚体的碰撞体)移入游戏对象或远离游戏对象,则可能无法唤醒游戏对象。
这种情况下可能会导致问题,例如,已经从刚体游戏对象下面移走地板时,刚体游戏对象会悬在空中。
在这种情况下,可以使用WakeUp 函数显式唤醒游戏对象。有关睡眠的更多信息,请参阅刚体和2D 刚体组件页面。
解决方法:rigidBody.WakeUp()
