RigidBody3D
继承: PhysicsBody3D < CollisionObject3D < Node3D < Node < Object
派生: VehicleBody3D
由物理仿真进行移动的 3D 物理体。
描述
RigidBody3D 实现了完整的 3D 物理。这个物理体无法直接控制,必须对其施加力(重力、冲量等),物理仿真将计算由此产生的移动、旋转、对碰撞的反应以及对沿路其他物理体的影响等。
可以使用 lock_rotation、freeze 和 freeze_mode 调整该物理体的行为。通过修改该对象的 mass 等属性,你可以控制物理仿真对其的影响。
即使施加了力,刚体也会始终维持自身的形状和大小。适用于环境中可交互的对象,例如能够推倒的树木或者能够被推动的一堆箱子。
如果你需要覆盖默认的物理行为,你可以编写自定义的力整合函数。见 custom_integrator。
注意:频繁修改 RigidBody3D 的 3D 变换或 linear_velocity 可能导致无法预期的行为。如果你需要直接影响物理体,请优先使用 _integrate_forces,能够直接访问物理状态。
教程
属性
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
| ||
|
方法
void | _integrate_forces(state: PhysicsDirectBodyState3D) virtual |
void | add_constant_central_force(force: Vector3) |
void | add_constant_force(force: Vector3, position: Vector3 = Vector3(0, 0, 0)) |
void | add_constant_torque(torque: Vector3) |
void | apply_central_force(force: Vector3) |
void | apply_central_impulse(impulse: Vector3) |
void | apply_force(force: Vector3, position: Vector3 = Vector3(0, 0, 0)) |
void | apply_impulse(impulse: Vector3, position: Vector3 = Vector3(0, 0, 0)) |
void | apply_torque(torque: Vector3) |
void | apply_torque_impulse(impulse: Vector3) |
get_colliding_bodies() const | |
get_contact_count() const | |
get_inverse_inertia_tensor() const | |
void | set_axis_velocity(axis_velocity: Vector3) |
信号
当与另一个 PhysicsBody3D 或 GridMap 发生碰撞时发出。需要将 contact_monitor 设置为 true
,并将 max_contacts_reported 设置得足够高以检测所有碰撞。如果 MeshLibrary 具有碰撞 Shape3D,则 GridMap 会被检测。
body
是其他 PhysicsBody3D 或 GridMap 的 Node,如果该节点存在于树中。
当与另一个 PhysicsBody3D 或 GridMap 的碰撞结束时发出。需要将 contact_monitor 设置为 true
,并将 max_contacts_reported 设置得足够高以检测所有碰撞。如果 MeshLibrary 具有碰撞 Shape3D,则 GridMap 会被检测。
body
是其他 PhysicsBody3D 或 GridMap 的 Node,如果该节点存在于树中。
body_shape_entered(body_rid: RID, body: Node, body_shape_index: int, local_shape_index: int) 🔗
当该 RigidBody3D 的一个 Shape3D 与另一个 PhysicsBody3D 或 GridMap 的 Shape3D 碰撞时发出。需要将 contact_monitor 设置为 true
,并将 max_contacts_reported 设置得足够高以检测所有碰撞。如果 MeshLibrary 具有 Collision Shape3D,则 GridMap 会被检测到。
body_rid
由 PhysicsServer3D 使用的其他 PhysicsBody3D 或 MeshLibrary 的 CollisionObject3D 的 RID。
body
其他 PhysicsBody3D 或 GridMap 的 Node,如果该节点存在于树中。
body_shape_index
由 PhysicsServer3D 使用的其他 PhysicsBody3D 或 GridMap 的 Shape3D 的索引。该 CollisionShape3D 节点可以使用 body.shape_owner_get_owner(body.shape_find_owner(body_shape_index))
获取。
local_shape_index
由 PhysicsServer3D 使用的该 RigidBody3D 的 Shape3D 的索引。该 CollisionShape3D 节点可以使用 self.shape_owner_get_owner(self.shape_find_owner(local_shape_index))
获取。
body_shape_exited(body_rid: RID, body: Node, body_shape_index: int, local_shape_index: int) 🔗
当该 RigidBody3D 的一个 Shape3D 与另一个 PhysicsBody3D 或 GridMap 的 Shape3D 之间的碰撞结束时发出。需要将 contact_monitor 设置为 true
,并将 max_contacts_reported 设置得足够高以检测所有碰撞。如果 MeshLibrary 具有碰撞 Shape3D,则 GridMap 将被检测。
body_rid
由 PhysicsServer3D 使用的其他 PhysicsBody3D 或 MeshLibrary 的 CollisionObject3D 的 RID。如果网格具有 Shape3D,则 GridMap 将被检测。
body
其他 PhysicsBody3D 或 GridMap 的 Node,如果该节点存在于树中。
body_shape_index
由 PhysicsServer3D 使用的其他 PhysicsBody3D 或GridMap 的Shape3D 的索引。该 CollisionShape3D 节点可以使用 body.shape_owner_get_owner(body.shape_find_owner(body_shape_index))
获取。
local_shape_index
由 PhysicsServer3D 使用的该 RigidBody3D 的 Shape3D 的索引。该 CollisionShape3D 节点可以使用 self.shape_owner_get_owner(self.shape_find_owner(local_shape_index))
获取。
sleeping_state_changed() 🔗
当物理引擎改变物体的睡眠状态时发出。
注意:改变 sleeping 的值不会触发这个信号。只有当物理引擎改变了睡眠状态或者使用了 emit_signal("sleeping_state_changed")
时,它才会被发出。
枚举
enum FreezeMode: 🔗
FreezeMode FREEZE_MODE_STATIC = 0
静态物体冻结模式(默认)。物体不受重力和力的影响。它只能由用户的代码移动,并且其他物体沿其路径运动时,不会与之发生碰撞。
FreezeMode FREEZE_MODE_KINEMATIC = 1
运动物体的冻结模式。类似于 FREEZE_MODE_STATIC ,但是在移动时会与其路径上的其他物体发生碰撞。适用于需要动画的冻结物体。
enum CenterOfMassMode: 🔗
CenterOfMassMode CENTER_OF_MASS_MODE_AUTO = 0
在此模式下,该物体的质心将基于其形状自动计算。此处的前提是各个形状的原点也是对应的质心。
CenterOfMassMode CENTER_OF_MASS_MODE_CUSTOM = 1
在此模式下,物体的质心通过 center_of_mass 设置。默认为物体的原点位置。
enum DampMode: 🔗
DampMode DAMP_MODE_COMBINE = 0
在这种模式下,物体的阻尼值将被加到区域中设置的任何值或默认值。
DampMode DAMP_MODE_REPLACE = 1
在这种模式下,物体的阻尼值将替换掉区域中设置的任何值或默认值。
属性说明
阻碍物体的旋转。默认情况下,物体将使用 项目 > 项目设置 > 物理 > 3d 中的默认角度阻尼,或物体所在的 Area3D 中设置的任何覆盖值。取决于 angular_damp_mode,可以设置 angular_damp 以增加或替换物体的阻尼值。
有关阻尼的更多详细信息,请参阅 ProjectSettings.physics/3d/default_angular_damp。
DampMode angular_damp_mode = 0
🔗
定义如何应用 angular_damp。可能的取值见 DampMode。
Vector3 angular_velocity = Vector3(0, 0, 0)
🔗
该 RigidBody3D 的旋转速度,单位为弧度每秒。
如果为 true
,则物体未运动时可以进入睡眠模式。见 sleeping 。
Vector3 center_of_mass = Vector3(0, 0, 0)
🔗
当 center_of_mass_mode 设置为 CENTER_OF_MASS_MODE_CUSTOM 时,物体的自定义质心相对于物体原点位置的位置。这是物体的平衡点,只有施加在质心内的力才会引起线性加速度。施加在质心之外的力会引起角加速度。
当 center_of_mass_mode 设置为 CENTER_OF_MASS_MODE_AUTO(默认值)时,会自动计算质心。
CenterOfMassMode center_of_mass_mode = 0
🔗
void set_center_of_mass_mode(value: CenterOfMassMode)
CenterOfMassMode get_center_of_mass_mode()
定义设置物体质心的方式。可能的取值见 CenterOfMassMode。
Vector3 constant_force = Vector3(0, 0, 0)
🔗
在每个物理更新期间施加到物体的总恒定位置的力。
见 add_constant_force 和 add_constant_central_force 。
Vector3 constant_torque = Vector3(0, 0, 0)
🔗
在每个物理更新期间施加的物体的总恒定旋转力。
bool contact_monitor = false
🔗
如果为 true
,则该 RigidBody3D 将在与其他物体碰撞时发出信号。
注意:默认情况下,报告的最大接触数被设置为 0,表示不会记录任何内容,见 max_contacts_reported。
void set_use_continuous_collision_detection(value: bool)
bool is_using_continuous_collision_detection()
如果为 true
,则使用连续碰撞检测。
连续碰撞检测尝试预测一个移动的物体会在哪里碰撞,而不是移动它并在它发生碰撞时纠正它的运动。连续碰撞检测更精确,并且错过了较小的、快速移动的物体的撞击。不使用连续碰撞检测的计算速度更快,但可能会错过小的、快速移动的物体。
bool custom_integrator = false
🔗
如果为 true
,则该物体的标准力积分(如重力或阻尼)将被禁用。除了碰撞响应之外,如果覆盖了 _integrate_forces 方法,则物体将仅按照该方法确定的方式移动。
设置该属性将在内部调用方法 PhysicsServer3D.body_set_omit_force_integration。
如果为 true
,则该物体被冻结。不再施加重力和力。
要设置冻结时物体的行为,见 freeze_mode。
对于始终冻结的物体,请改用 StaticBody3D 或 AnimatableBody3D。
FreezeMode freeze_mode = 0
🔗
void set_freeze_mode(value: FreezeMode)
FreezeMode get_freeze_mode()
物体的冻结模式。可用于设置启用 freeze 时物体的行为。可能的取值见 FreezeMode 。
对于始终冻结的物体,请使用 StaticBody3D 或 AnimatableBody3D。
此值将乘以在 项目 > 项目设置 > 物理 > 3D 中获取的全局 3D 重力设置,以产生 RigidBody3D 的重力。例如,值为 1 表示正常重力,值为 2 将施加双倍重力,而值为 0.5 将施加一半重力到该对象。
Vector3 inertia = Vector3(0, 0, 0)
🔗
该物体的转动惯量。与质量类似,但用于旋转:用于确定各个轴上需要施加多少力矩才能让该物体旋转。通常会自动根据质量和形状计算转动惯量,但这个属性能够让你设置自定义的值。
设置为 Vector3.ZERO 时,会自动计算惯量(默认值)。
注意:自动计算出惯量后,这个值不会改变。请使用 PhysicsServer3D 获取计算出的惯量。
GDScriptC#
@onready var ball = $Ball
func get_ball_inertia():
return PhysicsServer3D.body_get_direct_state(ball.get_rid()).inverse_inertia.inverse()
private RigidBody3D _ball;
public override void _Ready()
{
_ball = GetNode<RigidBody3D>("Ball");
}
private Vector3 GetBallInertia()
{
return PhysicsServer3D.BodyGetDirectState(_ball.GetRid()).InverseInertia.Inverse();
}
阻碍物体的运动。默认情况下,物体将使用 项目 > 项目设置 > 物理 > 3d 中的默认线性阻尼,或物体所在的 Area3D 中设置的任何覆盖值。取决于 linear_damp_mode,可以设置 linear_damp 以增加或替换物体的阻尼值。
有关阻尼的更多详细信息,请参阅 ProjectSettings.physics/3d/default_linear_damp。
DampMode linear_damp_mode = 0
🔗
定义如何应用 linear_damp。有关可能的值,请参阅 DampMode。
Vector3 linear_velocity = Vector3(0, 0, 0)
🔗
物体的线速度,单位为单位每秒。可以偶尔使用,但是不要每一帧都设置它,因为物理可能在另一个线程中运行,并且以不同的间隔。使用 _integrate_forces 作为你的进程循环,以精确控制物体状态。
如果为 true
,则该物体不能旋转。重力和力只施加线性运动。
实体的质量。
int max_contacts_reported = 0
🔗
将记录的最大接触点数。需要一个大于 0 的值,并将 contact_monitor 设置为 true
以开始注册接触。使用 get_contact_count 检索计数或使用 get_colliding_bodies 检索已发生碰撞的物体。
注意:接触点的数量不同于碰撞的数量。平行边之间的碰撞将导致两个接触点(每个端点一个),平行面之间的碰撞将导致四个接触点(每个角落一个)。
PhysicsMaterial physics_material_override 🔗
void set_physics_material_override(value: PhysicsMaterial)
PhysicsMaterial get_physics_material_override()
物体的物理材质。
如果为该属性指定了一种材质,则将使用该材质代替任何其他物理材质,例如继承的材质。
如果为 true
,该刚体将不会移动,也不会计算受力,直到被另一个物体唤醒,例如通过碰撞或使用 apply_impulse 或 apply_force 方法。
方法说明
void _integrate_forces(state: PhysicsDirectBodyState3D) virtual 🔗
在物理处理过程中被调用,允许你读取并安全地修改对象的模拟状态。默认情况下,它在标准力积分之前调用,但 custom_integrator 属性允许你禁用标准力积分并对物体进行完全自定义的力积分。
void add_constant_central_force(force: Vector3) 🔗
在不影响旋转的情况下,添加一个恒定的定向力,该力会随着时间的推移而持续施加,直到使用 constant_force = Vector3(0, 0, 0)
清除。
这相当于在物体的质心处,使用 add_constant_force。
void add_constant_force(force: Vector3, position: Vector3 = Vector3(0, 0, 0)) 🔗
向实体添加一个恒定的定位力,持续施加,直到用 constant_force = Vector3(0, 0, 0)
清除。
position
是在全局坐标中距实体原点的偏移量。
void add_constant_torque(torque: Vector3) 🔗
在不影响位置的情况下,添加一个恒定的旋转力,该力会随着时间的推移而持续施加,直到使用 constant_torque = Vector3(0, 0, 0)
清除。
void apply_central_force(force: Vector3) 🔗
施加一个不影响旋转的定向力。该力是时间相关的,意味着每次物理更新都会施加。
这相当于在物体的质心处,使用 apply_force。
void apply_central_impulse(impulse: Vector3) 🔗
施加一个不影响的旋转定向冲量。
冲量与时间无关!每帧应用一个冲量,会产生一个依赖于帧速率的力。出于这个原因,它应该只在模拟一次性影响时使用(否则使用 “_force”函数)。
这相当于在物体的质心处,使用 apply_impulse。
void apply_force(force: Vector3, position: Vector3 = Vector3(0, 0, 0)) 🔗
对实体施加一个定位力。力是时间相关的,意味着每次物理更新都会被施加。
position
是在全局坐标中距实体原点的偏移量。
void apply_impulse(impulse: Vector3, position: Vector3 = Vector3(0, 0, 0)) 🔗
向实体施加一个定位冲量。
冲量是时间无关的!每帧施加一个冲量将产生一个依赖于帧速率的力。出于这个原因,它应该只在模拟一次性影响时使用(否则使用“_force”函数)。
position
是在全局坐标中距实体原点的偏移量。
void apply_torque(torque: Vector3) 🔗
施加旋转力但不影响位置。力是与时间相关的,应该每次物理更新时都要进行施加。
注意:有 inertia 才能正常工作。要让 inertia 存在,必须有一个 CollisionShape3D 作为该节点的子节点,或者你也可以手动设置 inertia。
void apply_torque_impulse(impulse: Vector3) 🔗
在不影响位置的情况下,向实体施加一个旋转冲量。
冲量是时间无关的!每帧施加一个冲量将产生一个依赖于帧速率的力。出于这个原因,它应该只在模拟一次性影响时使用(否则使用“_force”函数)。
注意:需要 inertia 才能发挥作用。要具有 inertia,活动的 CollisionShape3D 必须是该节点的一个子节点,或者可以手动设置 inertia。
Array[Node3D] get_colliding_bodies() const 🔗
返回与此物体发生碰撞的物体的列表。需要将 contact_monitor 设置为 true
,并将 max_contacts_reported 设置足够高以侦测所有碰撞。
注意:此测试的结果不会立即在移动物体后得出。为了提高性能,碰撞列表每帧更新一次,且在物理迭代之前进行。可考虑改用信号来代替。
int get_contact_count() const 🔗
返回此物体与其他物体的接触数。默认情况下,除非配置监视接触的物体(见 contact_monitor),否则返回 0。
注意:要获取正在碰撞的物体,请使用 get_colliding_bodies。
Basis get_inverse_inertia_tensor() const 🔗
返回逆惯性张量基础。这用于计算施加到 RigidBody3D 上的力矩产生的角加速度。
void set_axis_velocity(axis_velocity: Vector3) 🔗
设置轴速度。给定向量轴上的速度将被设置为给定向量长度。这对跳跃行为很有用。