rigid_body_forces_and_impulses
In addition to gravity, it is possible to add custom forces (or torques) or apply impulses (or torque impulses) to dynamic rigid-bodies in order to make them move in specific ways. Forces affect the rigid-body's acceleration whereas impulses affect the rigid-body's velocity. They are both based on the familiar equations:
- Forces: the acceleration change is equal to the force divided by the mass:
- Impulses: the velocity change is equal to the impulse divided by the mass:
Forces can be added, and impulses can be applied, to a rigid-body when it is created or after its creation. Added forces are persistent across simulation steps, and can be cleared manually.
- Example 2D
- Example 3D
commands
.spawn(RigidBody::Dynamic)
.insert(ExternalForce {
force: Vec2::new(1000.0, 2000.0),
torque: 140.0,
})
.insert(ExternalImpulse {
impulse: Vec2::new(100.0, 200.0),
torque_impulse: 14.0,
});
/* Apply forces and impulses inside of a system. */
fn apply_forces(
mut ext_forces: Query<&mut ExternalForce>,
mut ext_impulses: Query<&mut ExternalImpulse>,
) {
// Apply forces.
for mut ext_force in ext_forces.iter_mut() {
ext_force.force = Vec2::new(1000.0, 2000.0);
ext_force.torque = 0.4;
}
// Apply impulses.
for mut ext_impulse in ext_impulses.iter_mut() {
ext_impulse.impulse = Vec2::new(100.0, 200.0);
ext_impulse.torque_impulse = 0.4;
}
}
/* Apply forces when the rigid-body is created. */
commands
.spawn(RigidBody::Dynamic)
.insert(ExternalForce {
force: Vec3::new(10.0, 20.0, 30.0),
torque: Vec3::new(1.0, 2.0, 3.0),
})
.insert(ExternalImpulse {
impulse: Vec3::new(1.0, 2.0, 3.0),
torque_impulse: Vec3::new(0.1, 0.2, 0.3),
});
/* Apply forces and impulses inside of a system. */
fn apply_forces(
mut ext_forces: Query<&mut ExternalForce>,
mut ext_impulses: Query<&mut ExternalImpulse>,
) {
// Apply forces.
for mut ext_force in ext_forces.iter_mut() {
ext_force.force = Vec3::new(1000.0, 2000.0, 3000.0);
ext_force.torque = Vec3::new(0.4, 0.5, 0.6);
}
// Apply impulses.
for mut ext_impulse in ext_impulses.iter_mut() {
ext_impulse.impulse = Vec3::new(100.0, 200.0, 300.0);
ext_impulse.torque_impulse = Vec3::new(0.4, 0.5, 0.6);
}
}
Keep in mind that a dynamic rigid-body with a zero mass won't be affected by a linear force/impulse, and a rigid-body with a zero angular inertia won't be affected by torques/torque impulses. So if your force doesn't appear to do anything, make sure that:
- The rigid-body is dynamic.
- It is strong enough to make the rigid-body move (try a very large value and see if it does something).
- The rigid-body has a non-zero mass or angular inertia either because they were set explicitly, or because they were computed automatically from colliders with non-zero densities.