Crate avian3d

source ·
Expand description

§Avian Physics

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.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 flags

FeatureDescriptionDefault feature
2dEnables 2D physics. Incompatible with 3d.Yes (avian2d)
3dEnables 3D physics. Incompatible with 2d.Yes (avian3d)
f32Enables f32 precision for physics. Incompatible with f64.Yes
f64Enables f64 precision for physics. Incompatible with f32.No
default-colliderEnables the default Collider. Required for spatial queries. Requires either the parry-f32 or parry-f64 feature.Yes
parry-f32Enables the f32 version of the Parry collision detection library. Also enables the default-collider feature.Yes
parry-f64Enables the f64 version of the Parry collision detection library. Also enables the default-collider feature.No
collider-from-meshAllows you to create Colliders from Meshes.Yes
bevy_sceneEnables ColliderConstructorHierarchy to wait until a [Scene] has loaded before processing it.Yes
debug-pluginEnables physics debug rendering using the PhysicsDebugPlugin. The plugin must be added separately.Yes
enhanced-determinismEnables increased determinism.No
parallelEnables some extra multithreading, which improves performance for larger simulations but can add some overhead for smaller ones.Yes
simdEnables SIMD optimizations.No
serializeEnables 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

See the dynamics module for more details about rigid body dynamics in Avian.

§Collision detection

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

§Scheduling

§Architecture

§Frequently asked questions

§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 did my rigid body suddenly vanish?

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.

§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 my camera following jitter?

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:

  • Run after physics so that it has the up-to-date position of the player.
  • Run before transform propagation so that your changes to the camera’s 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),
);

§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 of Transform.
  • 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 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.

§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 a avian thread on the crate-help channel where you can ask questions.

§License

Avian is free and open source. All code in the Avian repository is dual-licensed under either:

at your option.

Re-exports§

Modules§

  • Collision detection for Colliders.
  • Renders physics objects and properties for debugging purposes.
  • Rigid body dynamics, handling the motion and physical interactions of non-deformable objects.
  • Math types and traits used by the crate.
  • Components for physics positions and rotations.
  • Re-exports common components, bundles, resources, plugins and types.
  • Runs systems that prepare and initialize components used by physics.
  • Sets up the default scheduling, system set configuration, and time resources for physics.
  • Functionality for performing ray casts, shape casts, and other spatial queries.
  • Responsible for synchronizing physics components with other data, like keeping Position and Rotation in sync with Transform.

Structs§