Getting started
Bevy is an efficient, simple-to-use, and fast-to-compile data-driven game engine written in Rust. It is based on the ECS (Entity-Component-System) paradigm and allows the definition of plugins, i.e., sets of components, systems, and resources that share a common objective.
The bevy_rapier2d and bevy_rapier3d crates which integrate Rapier to Bevy using their plugin system. To get the best of bevy-rapier multiple features can be enabled optionally:
debug-render-2d
/debug-render-3d
: enables the debug-renderer plugin.simd-stable
: enables explicit SIMD optimizations using thewide
crate. Has limited cross-platform support but can be used with a stable version of the Rust compiler.simd-nightly
: enables explicit SIMD optimizations using thepacked_simd
crate. Has a great cross-platform support but requires a nightly version of the Rust compiler.parallel
: enables parallelism of the physics pipeline with therayon
crate.serde-serialize
: enables serialization of the physics components withserde
.enhanced-determinism
: enables cross-platform determinism (assuming the rest of your code is also deterministic) across all 32-bit and 64-bit platforms that implements the IEEE 754-2008 standard strictly. This includes most modern processors as well as WASM targets.wasm-bindgen
: enables usage ofrapier
as a dependency of a WASM crate that is compiled withwasm-bindgen
.
Cargo example
To use these crates, the first step is to add a dependency to your Cargo.toml
:
- Example 2D
- Example 3D
[dependencies]
# TODO: Replace the * by the latest version numbers.
bevy = "*"
bevy_rapier2d = "*"
[dependencies]
# TODO: Replace the * by the latest version numbers.
bevy = "*"
bevy_rapier3d = "*"
If you need to enable some Rapier features like SIMD, parallelism, serialization, or determinism, you can enable them on bevy_rapier directly.
- Example 2D
- Example 3D
[dependencies]
# TODO: Replace the * by the latest version numbers.
bevy = "*"
bevy_rapier2d = { version = "*", features = [ "simd-stable", "debug-render-2d" ] }
[dependencies]
# TODO: Replace the * by the latest version numbers.
bevy = "*"
bevy_rapier3d = { version = "*", features = [ "simd-stable", "debug-render-3d" ] }
Basic simulation example
Here is a basic example of main.rs
file. This creates a ball bouncing on a fixed ground. Details about the
elements used in this examples are given in subsequent pages of this guide.
The use bevy_rapier2d::prelude::*
or use bevy_rapier3d::prelude::*
will import all the most common types
needed to work with bevy_rapier
.
- Example 2D
- Example 3D
use bevy::prelude::*;
use bevy_rapier2d::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(100.0))
.add_plugins(RapierDebugRenderPlugin::default())
.add_systems(Startup, setup_graphics)
.add_systems(Startup, setup_physics)
.add_systems(Update, print_ball_altitude)
.run();
}
fn setup_graphics(mut commands: Commands) {
// Add a camera so we can see the debug-render.
commands.spawn(Camera2dBundle::default());
}
fn setup_physics(mut commands: Commands) {
/* Create the ground. */
commands
.spawn(Collider::cuboid(500.0, 50.0))
.insert(TransformBundle::from(Transform::from_xyz(0.0, -100.0, 0.0)));
/* Create the bouncing ball. */
commands
.spawn(RigidBody::Dynamic)
.insert(Collider::ball(50.0))
.insert(Restitution::coefficient(0.7))
.insert(TransformBundle::from(Transform::from_xyz(0.0, 400.0, 0.0)));
}
fn print_ball_altitude(positions: Query<&Transform, With<RigidBody>>) {
for transform in positions.iter() {
println!("Ball altitude: {}", transform.translation.y);
}
}
use bevy::prelude::*;
use bevy_rapier3d::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(RapierPhysicsPlugin::<NoUserData>::default())
.add_plugins(RapierDebugRenderPlugin::default())
.add_systems(Startup, setup_graphics)
.add_systems(Startup, setup_physics)
.add_systems(Update, print_ball_altitude)
.run();
}
fn setup_graphics(mut commands: Commands) {
// Add a camera so we can see the debug-render.
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(-3.0, 3.0, 10.0).looking_at(Vec3::ZERO, Vec3::Y),
..Default::default()
});
}
fn setup_physics(mut commands: Commands) {
/* Create the ground. */
commands
.spawn(Collider::cuboid(100.0, 0.1, 100.0))
.insert(TransformBundle::from(Transform::from_xyz(0.0, -2.0, 0.0)));
/* Create the bouncing ball. */
commands
.spawn(RigidBody::Dynamic)
.insert(Collider::ball(0.5))
.insert(Restitution::coefficient(0.7))
.insert(TransformBundle::from(Transform::from_xyz(0.0, 4.0, 0.0)));
}
fn print_ball_altitude(mut positions: Query<&mut Transform, With<RigidBody>>) {
for mut transform in positions.iter_mut() {
dbg!(transform.rotation.to_axis_angle());
transform.rotation = Quat::from_rotation_z(270_f32.to_radians());
//println!("Ball altitude: {}", transform.translation.y);
}
}
The debug renderer
The bevy_rapier
plugin comes with a debug-render (either debug-render-2d
or debug-render-3d
) to help visualize exactly what the physics-engine sees. This
can help fixing some bugs like colliders not being properly aligned with your graphics representation.
The debug-renderer is be enabled by:
- Enabling the
debug-render-2d
ordebug-render-3d
cargo feature of bevy-rapier. - Adding the plugin
RapierDebugRenderPlugin
to the Bevy app.