# 刚体 Rigidbody

只有具有刚体组件的物体才会在物理模拟阶段受到物理系统控制而发生位移或旋转。

初始情况下,刚体会受重力影响。用户可以在脚本内手动为其施加额外的力,来控制刚体的移动。

# 重要属性和方法

属性名 描述
mass 刚体的质量,用于在受力情况下计算加速度。
inertiaTensor 刚体的转动惯量,用于在受力矩的情况下计算角速度的变化率。
position 刚体的位置。*详见下一节
rotation 刚体的旋转。*详见下一节
velocity 刚体的线性速度。
angularVelocity 刚体的角速度。
isKinematic 是否为运动学刚体。*详见运动学刚体
方法名 描述
addForce 为刚体施加力。
wakeUp 唤醒刚体。*详见休眠状态
movePosition 移动运动学刚体

# 刚体的位置和旋转

除了刚体组件依附的节点上的Transform上的位置和旋转之外,刚体组件自己也有positionrotation属性,你可能会对此感到困惑。

实际上这可能是小游戏框架独有的现象,因为在小游戏框架里物理系统是使用 native 加速的,节点系统物理系统并不能实时地共享物体的位置和旋转。物体位置同步的时机其实是在每次的物理模拟的开始和结束时。

# ▌一般情况下移动刚体的方法

为了让刚体看起来符合物理规律,一般情况下不建议手动修改Transform的位置或者刚体的position
可以考虑使用addForce方法,来为刚体施加一个持续性的力;或是一个爆发性的力,来让刚体的速度产生突变。

# ▌什么时候需要修改刚体的position

想要让物体瞬移的话,几乎任何时候都只需要修改Transform上的位置就可以了。
但是也有例外的时候:如果你想让手动修改的位置立刻在物理世界中产生效果(在下一次物理模拟前),比如说想让另一个物理角色控制器能立刻在move()的过程中被移动后的刚体阻挡,那么就需要手动修改刚体的position

# 运动学刚体

有时候会想让刚体的运动和旋转完全处于自己的控制之下,这时候可以开启isKinematic属性,开启后的刚体称为运动学刚体

想要理解运动学刚体,可以等效地把刚体看成一个质量无穷大的物体,于是任何的力都无法使其产生加速度;同样的,运动学刚体在移动时,可以挤开任何其他的(非运动学)刚体,而自己不受任何影响。

# ▌运动学刚体的移动

由于运动学刚体不受力的影响,所以没办法像普通刚体一样使用addForce来移动。
如果想要让运动学刚体进行瞬移,可以直接修改Transform的位置。
如果想让运动学刚体沿直线移动到某点,可以调用movePosition方法。

# ▌运动学刚体和静态碰撞体的区别

带有碰撞体的运动学刚体,和无刚体的静态碰撞体,都可以和其他(非运动学)刚体发生碰撞,而自己不受影响。两者在表现上几乎一致。
为了防止混淆,这里列举一下两者的区别:

  1. 运动学刚体可以使用movePosition,而静态碰撞体只能瞬移;
  2. 运动学刚体可以和静态碰撞体触发Trigger事件,而两个静态碰撞体之间无法触发;
  3. 运动学刚体在 Physx 内部被设计为经常移动的物体,因此对移动这一行为有优化;静态碰撞体经常移动的话,性能比较差。

# 休眠状态

刚体的动能如果持续性地小于一定阈值,在几次物理模拟之后,刚体就会进入休眠状态,来节省性能。

休眠状态下,刚体不会主动地在物理模拟阶段发生移动或旋转。但是会参与碰撞检测,如果有另一个刚体与休眠的刚体发生了碰撞,那休眠的刚体会自动醒来。

可以使用wakeUp方法来主动唤醒休眠的刚体。

# 层级结构下的表现

原则上应该尽量避免两个刚体组件的节点存在父子关系,否则可能会出现预料之外的情况。

但是实际使用中,可能会需要为骨骼模型中的某个部位创造一个碰撞体,来挤开其他碰撞体(或是触发 Trigger 事件)。这时候可以使用运动学刚体