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!
This short guide should help you get started with Avian.
First, add avian2d
or avian3d
to the dependencies in your Cargo.toml
:
# For 2D applications:
[dependencies]
avian2d = "0.1"
# For 3D applications:
[dependencies]
avian3d = "0.1"
# 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.1", default-features = false, features = ["3d", "f64", "parry-f64"] }
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 |
debug-plugin | Enables physics debug rendering using the PhysicsDebugPlugin . The plugin must be added separately. | Yes |
enhanced-determinism | Enables increased determinism. | 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 |
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.
Below is a structured overview of the documentation for the various features of the engine.
See the dynamics
module for more details about rigid body dynamics in Avian.
ColliderConstructor
and ColliderConstructorHierarchy
See the collision
module for more details about collision detection and colliders in Avian.
Joint motors and articulations are not supported yet, but they will be implemented in a future release.
PhysicsSet
PhysicsSchedule
and PhysicsStepSet
SubstepSchedule
SolverSet
and SubstepSolverSet
PostProcessCollisions
schedulePrepareSet
Position
and Rotation
components?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:
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.
Make sure you have added the PhysicsPlugins
plugin group and you have given your rigid bodies
a RigidBody
component. See the getting started section.
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.
Make sure to give your rigid bodies some mass, either by adding a Collider
or a MassPropertiesBundle
. If your bodies don’t have any mass, any physical interaction is likely to
instantly give them infinite velocity.
Avian should automatically print warnings when it detects bodies with an invalid mass or inertia.
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
When you write a system that makes the camera follow a physics entity, you might notice some jitter.
To fix this, the system needs to:
Transform
are written
to the camera’s GlobalTransform
before the end of the frame.The following ordering constraints should resolve the issue.
app.add_systems(
PostUpdate,
camera_follow_player
.after(PhysicsSet::Sync)
.before(TransformSystem::TransformPropagate),
);
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.
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.
f64
version of Transform
.Transform
(yet), and having a 2D version can optimize several computations.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.
Yes! Networking often requires running the simulation in a specific schedule, and in Avian you can set the schedule that runs physics and configure the timestep to whatever you want.
One configuration is to run the client in FixedUpdate
, and to use a fixed timestep for Time<Physics>
on both the server and the client to make sure the physics simulation is only advanced by one step
each time the schedule runs.
Note that while Avian should be locally deterministic (at least when single-threaded), it can produce slightly different results on different machines.
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 a avian thread on the crate-help channel where you can ask questions.
Avian is free and open source. All code in the Avian repository is dual-licensed under either:
at your option.
pub extern crate parry3d as parry;
Collider
s.TypeRegistry
resource in bevy_reflect
.