Expand description
Avian is an ECS-driven 2D and 3D physics engine for the Bevy game engine.
Check out the GitHub repository for more information about the design, read the Getting Started guide below to get up to speed, and take a look at the Table of Contents for an overview of the engine’s features and their documentation.
You can also check out the FAQ, and if you encounter any further problems, consider saying hello on the Bevy Discord!
§Getting Started
This short guide should help you get started with Avian.
§Add the Dependency
First, add avian2d
or avian3d
to the dependencies in your Cargo.toml
:
# For 2D applications:
[dependencies]
avian2d = "0.2"
# For 3D applications:
[dependencies]
avian3d = "0.2"
# If you want to use the most up-to-date version, you can follow the main branch:
[dependencies]
avian3d = { git = "https://github.com/Jondolf/avian", branch = "main" }
You can specify features by disabling the default features and manually adding the feature flags you want:
[dependencies]
# Add 3D Avian with double-precision floating point numbers.
# `parry-f64` enables collision detection using Parry.
avian3d = { version = "0.2", default-features = false, features = ["3d", "f64", "parry-f64"] }
§Feature Flags
Feature | Description | Default feature |
---|---|---|
2d | Enables 2D physics. Incompatible with 3d . | Yes (avian2d ) |
3d | Enables 3D physics. Incompatible with 2d . | Yes (avian3d ) |
f32 | Enables f32 precision for physics. Incompatible with f64 . | Yes |
f64 | Enables f64 precision for physics. Incompatible with f32 . | No |
default-collider | Enables the default Collider . Required for spatial queries. Requires either the parry-f32 or parry-f64 feature. | Yes |
parry-f32 | Enables the f32 version of the Parry collision detection library. Also enables the default-collider feature. | Yes |
parry-f64 | Enables the f64 version of the Parry collision detection library. Also enables the default-collider feature. | No |
collider-from-mesh | Allows you to create Collider s from Mesh es. | Yes |
bevy_scene | Enables ColliderConstructorHierarchy to wait until a Scene has loaded before processing it. | Yes |
bevy_picking | Enables physics picking support for bevy_picking using the PhysicsPickingPlugin . The plugin must be added separately. | Yes |
debug-plugin | Enables physics debug rendering using the PhysicsDebugPlugin . The plugin must be added separately. | Yes |
enhanced-determinism | Enables cross-platform deterministic math, improving determinism across architectures at a small performance cost. | No |
parallel | Enables some extra multithreading, which improves performance for larger simulations but can add some overhead for smaller ones. | Yes |
simd | Enables SIMD optimizations. | No |
serialize | Enables support for serialization and deserialization using Serde. | No |
§Add the Plugins
Avian is designed to be very modular. It is built from several plugins that
manage different parts of the engine. These plugins can be easily initialized and configured through
the PhysicsPlugins
plugin group.
use avian3d::prelude::*;
use bevy::prelude::*;
fn main() {
App::new()
.add_plugins((DefaultPlugins, PhysicsPlugins::default()))
// ...your other plugins, systems and resources
.run();
}
Now you can use all of Avian’s components and resources to build whatever you want!
For example, adding a rigid body with a collider is as simple as spawning an entity
with the RigidBody
and Collider
components:
use avian3d::prelude::*;
use bevy::prelude::*;
fn setup(mut commands: Commands) {
commands.spawn((RigidBody::Dynamic, Collider::sphere(0.5)));
}
You can find lots of usage examples in the project’s repository.
§Table of Contents
Below is a structured overview of the documentation for the various features of the engine.
§Rigid Body Dynamics
- Rigid body types
- Creating rigid bodies
- Movement
- Gravity and gravity scale
- Mass properties
- Linear and angular velocity damping
- Lock translational and rotational axes
- Dominance
- Continuous Collision Detection (CCD)
Transform
interpolation and extrapolation- Temporarily disabling a rigid body
- Automatic deactivation with sleeping
See the dynamics
module for more details about rigid body dynamics in Avian.
§Collision Detection
- Colliders
- Creation
- Density
- Friction and restitution (bounciness)
- Collision layers
- Sensors
- Generating colliders for meshes and scenes with
ColliderConstructor
andColliderConstructorHierarchy
- Get colliding entities
- Collision events
- Accessing, filtering and modifying collisions
- Manual contact queries
- Temporarily disabling a collider
See the collision
module for more details about collision detection and colliders in Avian.
§Constraints and Joints
Joint motors and articulations are not supported yet, but they will be implemented in a future release.
§Spatial Queries
§Configuration
- Gravity
Transform
interpolation and extrapolation- Physics speed
- Configure simulation fidelity with substeps
- Render physics objects for debugging
§Scheduling
- Schedules and sets
PhysicsSet
PhysicsSchedule
andPhysicsStepSet
SubstepSchedule
SolverSet
andSubstepSolverSet
PostProcessCollisions
schedulePrepareSet
- Many more internal system sets
- Configure the schedule used for running physics
- Pausing, resuming and stepping physics
- Usage on servers
§Architecture
- List of plugins and their responsibilities
- Extending and modifying the engine
§Frequently Asked Questions
- How does Avian compare to Rapier and bevy_rapier?
- Why is nothing happening?
- Why is everything moving so slowly?
- Why did my rigid body suddenly vanish?
- Why is performance so bad?
- Why does movement look choppy?
- Is there a character controller?
- Why are there separate
Position
andRotation
components? - Can the engine be used on servers?
- Something else?
§How does Avian compare to Rapier and bevy_rapier?
Rapier is the biggest and most used physics engine in the Rust ecosystem, and it is currently the most mature and feature-rich option.
bevy_rapier
is a great physics integration for Bevy, but it does have several problems:
- It has to maintain a separate physics world and synchronize a ton of data with Bevy each frame
- The source code is difficult to inspect, as the vast majority of it is glue code and wrappers for Bevy
- It has poor docs.rs documentation, and the documentation on rapier.rs is often outdated and missing features
- It is hard to extend as it’s not very modular or composable in design
- Overall, it doesn’t have a native ECS-like feel outside of its public API
Avian on the other hand is built for Bevy with Bevy, and it uses the ECS for both the internals and the public API. This removes the need for a separate physics world, reduces overhead, and makes the source code much more approachable and easy to inspect for Bevy users.
In part thanks to Bevy’s modular architecture and the ECS, Avian is also highly composable, as it consists of several independent plugins and provides lots of options for configuration and extensions, from custom schedules and plugins to custom joints and constraints.
One disadvantage of Avian is that it is still relatively young, so it can have more bugs, some missing features, and fewer community resources and third party crates. However, it is growing quite rapidly, and it is already pretty close to feature-parity with Rapier.
At the end of the day, both engines are solid options. If you are looking for a more mature and tested
physics integration, bevy_rapier
is the better choice, but if you prefer an engine with less overhead
and a more native Bevy integration, consider using Avian. Their core APIs are also quite similar,
so switching between them shouldn’t be too difficult.
§Why is nothing happening?
Make sure you have added the PhysicsPlugins
plugin group and you have given your rigid bodies
a RigidBody
component. See the getting started section.
§Why is everything moving so slowly?
If your application is in 2D, you might be using pixels as length units. This will require you to use
larger velocities and forces than you would in 3D. Make sure you set Gravity
to some larger value
as well, because its magnitude is 9.81
by default, which is tiny in pixels.
§Why is performance so bad?
Make sure you are building your project in release mode using cargo build --release
.
You can further optimize builds by setting the number of codegen units in your Cargo.toml
to 1,
although this will also increase build times.
[profile.release]
codegen-units = 1
§Why does movement look choppy?
To produce consistent, frame rate independent behavior, physics by default runs
in the FixedPostUpdate
schedule with a fixed timestep, meaning that the time between
physics ticks remains constant. On some frames, physics can either not run at all or run
more than once to catch up to real time. This can lead to visible stutter for movement.
This stutter can be resolved by interpolating or extrapolating the positions of physics objects
in between physics ticks. Avian has built-in support for this through the PhysicsInterpolationPlugin
,
which is included in the PhysicsPlugins
by default.
Interpolation can be enabled for an individual entity by adding the TransformInterpolation
component:
fn setup(mut commands: Commands) {
// Enable interpolation for this rigid body.
commands.spawn((
RigidBody::Dynamic,
Transform::default(),
TransformInterpolation,
));
}
To make all rigid bodies interpolated by default, use PhysicsInterpolationPlugin::interpolate_all()
:
fn main() {
App::new()
.add_plugins(PhysicsPlugins::default().set(PhysicsInterpolationPlugin::interpolate_all()))
// ...
.run();
}
See the PhysicsInterpolationPlugin
for more information.
If this does not fix the choppiness, the problem could also be related to system ordering.
If you have a system for camera following, make sure it runs after physics,
but before Bevy’s transform propagation in PostUpdate
.
app.add_systems(
PostUpdate,
camera_follow_player.before(TransformSystem::TransformPropagate),
);
§Is there a character controller?
Avian does not have a built-in character controller, so if you need one,
you will need to implement it yourself. However, third party character controllers
like bevy_tnua
support Avian, and bevy_mod_wanderlust
and others are also likely to get Avian support soon.
For custom character controllers, you can take a look at the
dynamic_character_3d
and kinematic_character_3d
examples to get started.
§Why are there separate Position
and Rotation
components?
While Transform
can be used for the vast majority of things, Avian internally
uses separate Position
and Rotation
components. These are automatically
kept in sync by the SyncPlugin
.
There are several reasons why the separate components are currently used.
- Position and rotation should be global from the physics engine’s point of view.
- Transform scale and shearing can cause issues and rounding errors in physics.
- Transform hierarchies can be problematic.
- There is no
f64
version ofTransform
. - There is no 2D version of
Transform
(yet), and having a 2D version can optimize several computations. - When position and rotation are separate, we can technically have more systems running in parallel.
- Only rigid bodies have rotation, particles typically don’t (although we don’t make a distinction yet).
In external projects however, using Position
and Rotation
is only necessary when you
need to manage positions within PhysicsSet::StepSimulation
. Elsewhere, you should be able to use Transform
.
There is also a possibility that we will revisit this if/when Bevy has a Transform2d
component.
Using Transform
feels more idiomatic and simple, so it would be nice if it could be used directly
as long as we can get around the drawbacks.
§Can the engine be used on servers?
Yes! Networking often requires running the simulation in a specific schedule, and in Avian it is straightforward
to set the schedule that runs physics and configure the timestep if needed.
By default, physics runs at a fixed timestep in FixedPostUpdate
.
§Something else?
Physics engines are very large and Avian is young, so stability issues and bugs are to be expected.
If you encounter issues, please consider first taking a look at the issues on GitHub and open a new issue if there already isn’t one regarding your problem.
You can also come and say hello on the Bevy Discord server.
There, you can find an Avian Physics topic on the #ecosystem-crates
channel where you can ask questions.
§License
Avian is free and open source. All code in the Avian repository is dual-licensed under either:
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
at your option.
Re-exports§
pub extern crate parry3d as parry;
Modules§
- collision
- Collision detection for
Collider
s. - debug_
render - Renders physics objects and properties for debugging purposes.
- dynamics
- Rigid body dynamics, handling the motion and physical interactions of non-deformable objects.
- interpolation
- Physics interpolation and extrapolation for rigid bodies.
- math
- Math types and traits used by the crate.
- picking
- A physics picking backend for
bevy_picking
. - position
- Components for physics positions and rotations.
- prelude
- Re-exports common components, bundles, resources, plugins and types.
- prepare
- Runs systems that prepare and initialize components used by physics.
- schedule
- Sets up the default scheduling, system set configuration, and time resources for physics.
- spatial_
query - Functionality for performing ray casts, shape casts, and other spatial queries.
- sync
- Responsible for synchronizing physics components with other data, like keeping
Position
andRotation
in sync withTransform
.
Structs§
- Physics
Plugins - A plugin group containing all of Avian’s plugins.
- Physics
Type Registration Plugin - Registers physics types to the
TypeRegistry
resource inbevy_reflect
.