Expand description
External forces, impulses, and acceleration for dynamic rigid bodies.
§Overview
In addition to Gravity
, it is possible to apply your own forces, impulses, and acceleration
to dynamic rigid bodies to simulate various effects such as force fields, motors, and thrusters.
They have the following relationships:
Type | Formula | Relation to Velocity | Unit |
---|---|---|---|
Force | F = m * a | Δa = F / m | kg⋅m/s² (N) |
Impulse | J = F * Δt | Δv = J / m | kg⋅m/s (N⋅s) |
Acceleration | a = F / m | Δv = a * Δt | m/s² |
A force applies an acceleration to a body, which in turn modifies its velocity over time, while an impulse applies an immediate change in velocity. Both forces and impulses consider mass properties, while acceleration by itself is independent of mass.
The rotational equivalents are torques, angular impulses, and angular acceleration, which work similarly.
§Constant Forces
Constant forces and accelerations that persist across time steps can be applied using the following components:
ConstantForce
: Applies a constant force in world space.ConstantTorque
: Applies a constant torque in world space.ConstantLinearAcceleration
: Applies a constant linear acceleration in world space.ConstantAngularAcceleration
: Applies a constant angular acceleration in world space.
They also have local space equivalents:
ConstantLocalForce
: Applies a constant force in local space.ConstantLocalLinearAcceleration
: Applies a constant linear acceleration in local space.
These components are useful for simulating continuously applied forces that are expected to remain the same across time steps, such as per-body gravity or force fields.
You can use constant forces by adding the components to your entities:
commands.spawn((
RigidBody::Dynamic,
Collider::capsule(0.5, 1.0),
// Apply a constant force of 10 N in the positive Y direction.
ConstantForce::new(0.0, 10.0),
));
The forces are only constant in the sense that they persist across time steps. They can still be modified in systems like normal.
§One-Time Forces and Impulses
It is common to apply many individual forces and impulses to dynamic rigid bodies,
and to clear them afterwards. This can be done using the Forces
helper QueryData
.
To use Forces
, add it to a Query
(without &
or &mut
), and use the associated methods
to apply forces, impulses, and accelerations to the rigid bodies.
fn apply_forces(mut query: Query<Forces>) {
for mut forces in &mut query {
// Apply a force of 10 N in the positive Y direction to the entity.
forces.apply_force(Vec2::new(0.0, 10.0));
}
}
The force is applied continuously during the physics step, and cleared automatically after the step is complete.
By default, applying forces to sleeping bodies will wake them up. If this is not desired,
the non_waking
method can be used to fetch a NonWakingForcesItem
that allows applying forces to a body without waking it up.
// Apply a force without waking up the body if it is sleeping.
forces.non_waking().apply_force(force);
Forces
can also apply forces and impulses at a specific point in the world. If the point is not aligned
with the center of mass, it will apply a torque to the body.
// Apply an impulse at a specific point in the world.
// Unlike forces, impulses are applied immediately to the velocity.
forces.apply_linear_impulse_at_point(force, point);
As an example, you could implement radial gravity that pulls rigid bodies towards the world origin with a system like the following:
fn radial_gravity(mut query: Query<(Forces, &GlobalTransform)>) {
for (mut forces, global_transform) in &mut query {
// Compute the direction towards the center of the world.
let direction = -global_transform.translation().normalize_or_zero();
// Apply a linear acceleration of 9.81 m/s² towards the center of the world.
forces.apply_linear_acceleration(direction.truncate() * 9.81);
}
}
§Applying Forces vs. Modifying Velocity
It is possible to achieve similar effects by directly modifying the LinearVelocity
or AngularVelocity
components instead of using the force APIs. For example, you could
implement gravity by simply modifying the velocity of the rigid bodies in a system:
// In `FixedUpdate`
fn gravity(mut bodies: Query<&mut LinearVelocity>, time: Res<Time>) {
for mut velocity in &mut bodies {
// Apply a constant acceleration of 9.81 m/s² in the negative Y direction.
velocity.y -= 9.81 * time.delta_secs();
}
}
However, using the force APIs has several advantages:
- Forces and accelerations are spread out over several substeps, which provides higher simulation fidelity than modifying velocity once per time step.
- Forces and impulses consider mass properties and delta time for you, simplifying code.
- The force APIs make it straightforward to apply forces at specific points in the world.
Modifying velocity directly can still be useful and simpler in some cases, and the difference in simulation fidelity tends to be small for most applications. Notably, it is currently not possible to apply forces to kinematic bodies, as they have infinite mass.
Still, for convenience and best results, it is generally recommended to use the force APIs for most cases where you want to apply forces, impulses, or acceleration to dynamic rigid bodies.
Structs§
- Accumulated
Local Acceleration - A component with the user-applied local acceleration accumulated for a rigid body before the physics step.
- Constant
Angular Acceleration - A component for applying a constant angular acceleration to a dynamic rigid body in world space. The unit is typically rad/s².
- Constant
Force - A component for applying a constant force to a dynamic rigid body in world space. The unit is typically N or kg⋅m/s².
- Constant
Linear Acceleration - A component for applying a constant linear acceleration to a dynamic rigid body in world space. The unit is typically m/s².
- Constant
Local Force - A component for applying a constant force to a dynamic rigid body in local space. The unit is typically N or kg⋅m/s².
- Constant
Local Linear Acceleration - A component for applying a constant linear acceleration to a dynamic rigid body in local space. The unit is typically m/s².
- Constant
Torque - A component for applying a constant torque to a dynamic rigid body in world space. The unit is typically N⋅m or kg⋅m²/s².
- Force
Plugin - A plugin for managing and applying external forces, torques, and accelerations for rigid bodies.
- Forces
- A helper
QueryData
for applying forces, impulses, and accelerations to dynamic rigid bodies. - Forces
Item - Automatically generated [
WorldQuery
](:: bevy :: ecs::query::WorldQuery) item type forForces
, returned when iterating over query results. - NonWaking
Forces Item - A
ForcesItem
that does not wake up the body when applying forces, torques, impulses, or accelerations. Returned byForcesItem::non_waking
.
Enums§
- Force
Systems - System sets for managing and applying forces, torques, and accelerations for rigid bodies.
Traits§
- Rigid
Body Forces - A trait for applying forces, impulses, and accelerations to a dynamic rigid body.