RigidBody2D
这个节点实现了模拟的2D物理。你不能直接控制一个RigidBody2D。相反,您可以对它施加力(重力、脉冲等),物理模拟会根据它的质量、摩擦力和其他物理属性计算出运动结果。
一个RigidBody2D有4种行为模式。RigidBody2D有4种行为模式:Rigid、Static、Character和Kinematic。
注意:你不应该每一帧都改变一个RigidBody2D的位置或线性速度,甚至不应该经常改变。如果你需要直接影响身体的状态,请使用_integrate_forces,它允许你直接访问物理状态。
还请记住,物理体管理自己的变换,它会覆盖你设置的变换。因此,任何直接或间接的变换(包括节点或其父体的缩放)都将只在编辑器中可见,并在运行时立即重置。
如果你需要覆盖默认的物理行为或在运行时添加一个变换,你可以写一个自定义的力集成。请参阅 custom_integrator。
您可以通过 “质量”、"摩擦 "或 "反弹 "等属性来修改刚体的行为,这些属性可以在检查器中设置。
Mode mode
刚体可以设置为以下四种模式之一:
- 刚性 – -- 身体表现为一个物理物体。它与其他物体发生碰撞,并对施加在它身上的力作出反应。这是默认模式。
- 静态 - 本体的行为就像一个StaticBody2D,不会移动。
- Character - 类似于 "Rigid "模式,但物体体不能旋转。
- Kinematic - 本体的行为就像KinematicBody2D,必须通过代码来移动。
float weight
物体的重量,基于它的质量和 “项目”>“项目设置”>“物理学”>"2d "中的默认重力值。
PhysicsMaterial physics_material_override
物体的物理材质覆盖。
如果一个材质被分配给这个属性,它将被用来代替任何其他物理材质,例如继承的材质。
float gravity_scale
乘以施加到物体的重力。 根据“项目”>“项目设置”>“物理”>“ 2d”中的“默认重力”值和/或由Area2Ds应用的任何额外的重力向量来计算物体的重力。bool custom_integrator
如果为真,则该物体的内力整合被禁用。除了碰撞响应外,该物体只会按照_integrate_forces函数的决定移动。CCDMode continuous_cd 连续碰撞检测模式。
连续碰撞检测试图预测移动物体将在哪里碰撞,而不是移动它,并在碰撞后纠正它的运动。连续碰撞检测速度较慢,但更精确,与快速移动的小物体的碰撞漏失更少。有Raycasting和shapecasting方法。有关详细信息,请参阅CCDMode。
int contacts_reported 记录的最大接触物体数量。要求 contact_monitor 设置为 true。 注意:
接触的数量与碰撞的数量不同。平行边之间的碰撞将导致两个接触点(两端各一个),平行面之间的碰撞将导致四个接触点(每个角一个)。
bool contact_monitor
如果为真,当本体与另一个RigidBody2D碰撞时,本体将发出信号。参见 contacts_reported。
bool sleeping
如果为"true",物体不会移动,也不会计算力,直到被另一个物体通过碰撞等方式唤醒,或者使用apply_impulse或add_force来唤醒。
bool can_sleep
如果为true,则物体不运动时可以进入睡眠模式。 见sleeping。
float linear_damp
衰减物体的线性速度。如果是-1,主体将在项目>项目设置>物理> 2d中使用默认的线性阻尼。
float angular_damp
衰减物体的角速度。如果是-1,body将使用在Project >项目设置> Physics > 2d中定义的默认Angular阻尼。
Vector2 applied_force
物体的总作用力
float applied_torque
物体的总施加扭矩。
物体的行为也会受到世界属性的影响,如在项目设置->物理学中设置,或者进入一个覆盖全局物理学属性的Area2D。
当一个刚体处于静止状态,有一段时间没有移动,它就会进入睡眠状态。沉睡的物体就像一个静态的物体,它的力不会被物理引擎计算。当力被施加时,无论是通过碰撞还是通过代码,该体都会被唤醒。
使用RigidBody2D
使用刚体的好处之一是可以 "免费 "拥有很多行为,而无需编写任何代码。例如,如果你要做一个 "愤怒的小鸟 "风格的游戏,其中有掉落的积木,你只需要创建RigidBody2Ds并调整它们的属性。堆叠、坠落和弹跳将由物理引擎自动计算。
然而,如果你希望对物体有一定的控制权,你应该注意–改变一个刚体的位置、线性速度或其他物理属性可能会导致意外的行为。如果你需要改变任何与物理相关的属性,你应该使用 _integrate_forces() 回调而不是 _physics_process() 。在这个回调中,您可以访问物体的Physics2DDirectBodyState,它允许安全地改变属性并与物理引擎同步。
例如,下面是“小行星”风格飞船的代码:
extends RigidBody2D
var thrust = Vector2(0, 250)
var torque = 20000
func _integrate_forces(state):
if Input.is_action_pressed("ui_up"):
applied_force = thrust.rotated(rotation)
else:
applied_force = Vector2()
var rotation_dir = 0
if Input.is_action_pressed("ui_right"):
rotation_dir += 1
if Input.is_action_pressed("ui_left"):
rotation_dir -= 1
applied_torque = rotation_dir * torque
void _integrate_forces ( Physics2DDirectBodyState state ) virtual
允许你读取并安全地修改对象的模拟状态。如果你需要直接改变物体的位置或其他物理属性,请使用它来代替Node._physics_process。默认情况下,它除了通常的物理行为外,还可以工作,但custom_integrator允许你禁用默认行为,并为一个体编写自定义的力集成。
需要注意的是,我们并不是直接设置linear_velocity或angular_velocity属性,而是对物体施加力(推力和扭矩),让物理引擎计算出结果的运动。
注意
当一个刚体进入睡眠状态时,_integrate_forces()函数将不会被调用。要重写这一行为,您需要通过创建碰撞、对其施加力或禁用 can_sleep 属性来保持刚体的清醒。请注意,这可能会对性能产生负面影响。
方法
void apply_impulse ( Vector2 offset, Vector2 impulse )
对身体施加一个定位冲力。冲力与时间无关!对每一帧施加一个脉冲,就会产生与帧数相关的力。因此,它只能在模拟一次性影响时使用(否则使用“_force”函数)。该位置使用了全球坐标系统的旋转,但以物体的原点为中心。
void apply_torque_impulse ( float torque )
对物体施加旋转冲力。
void add_force ( Vector2 offset, Vector2 force )
在物体上添加一个位置的力。力和与物体原点的偏移都是全局坐标。
void add_torque ( float torque )
增加恒定的旋转力。