Module forces

Source
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:

TypeFormulaRelation to VelocityUnit
ForceF = m * aΔa = F / mkg⋅m/s² (N)
ImpulseJ = F * ΔtΔv = J / mkg⋅m/s (N⋅s)
Accelerationa = F / mΔv = a * Δtm/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:

They also have local space equivalents:

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§

AccumulatedLocalAcceleration
A component with the user-applied local acceleration accumulated for a rigid body before the physics step.
ConstantAngularAcceleration
A component for applying a constant angular acceleration to a dynamic rigid body in world space. The unit is typically rad/s².
ConstantForce
A component for applying a constant force to a dynamic rigid body in world space. The unit is typically N or kg⋅m/s².
ConstantLinearAcceleration
A component for applying a constant linear acceleration to a dynamic rigid body in world space. The unit is typically m/s².
ConstantLocalForce
A component for applying a constant force to a dynamic rigid body in local space. The unit is typically N or kg⋅m/s².
ConstantLocalLinearAcceleration
A component for applying a constant linear acceleration to a dynamic rigid body in local space. The unit is typically m/s².
ConstantTorque
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².
ForcePlugin
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.
ForcesItem
Automatically generated [WorldQuery](:: bevy :: ecs::query::WorldQuery) item type for Forces, returned when iterating over query results.
NonWakingForcesItem
A ForcesItem that does not wake up the body when applying forces, torques, impulses, or accelerations. Returned by ForcesItem::non_waking.

Enums§

ForceSystems
System sets for managing and applying forces, torques, and accelerations for rigid bodies.

Traits§

RigidBodyForces
A trait for applying forces, impulses, and accelerations to a dynamic rigid body.