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: enables the debug-renderer plugin.
  • simd-stable: enables explicit SIMD optimizations using the wide 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 the packed_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 the rayon crate.
  • serde-serialize: enables serialization of the physics components with serde.
  • 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 of rapier as a dependency of a WASM crate that is compiled with wasm-bindgen.

Cargo example#

To use these crates, the first step is to add a dependency to your Cargo.toml:

[dependencies]
# TODO: Replace the * by the latest version numbers.
bevy = "*"
bevy_rapier2d = "*"

If you need to enable some Rapier features like SIMD, parallelism, serialization, or determinism, you can enable them on bevy_rapier directly.

[dependencies]
# TODO: Replace the * by the latest version numbers.
bevy = "*"
bevy_rapier2d = { version = "*", features = [ "simd-stable", "debug-render" ] }

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.

info

The use bevy_rapier2d::prelude::* or use bevy_rapier3d::prelude::* will import all the most common types needed to work with bevy_rapier.

use bevy::prelude::*;
use bevy_rapier2d::prelude::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(100.0))
.add_plugin(RapierDebugRenderPlugin::default())
.add_startup_system(setup_graphics)
.add_startup_system(setup_physics)
.add_system(print_ball_altitude)
.run();
}
fn setup_graphics(mut commands: Commands) {
// Add a camera so we can see the debug-render.
commands.spawn_bundle(OrthographicCameraBundle::new_2d());
}
fn setup_physics(mut commands: Commands) {
/* Create the ground. */
commands
.spawn()
.insert(Collider::cuboid(500.0, 50.0))
.insert_bundle(TransformBundle::from(Transform::from_xyz(0.0, -100.0, 0.0)));
/* Create the bouncing ball. */
commands
.spawn()
.insert(RigidBody::Dynamic)
.insert(Collider::ball(50.0))
.insert(Restitution::coefficient(0.7))
.insert_bundle(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);
}
}

The debug renderer#

The bevy_rapier plugin comes with a debug-render 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:

  1. Enabling the debug-render cargo feature of bevy-rapier.
  2. Adding the plugin RapierDebugRenderPlugin to the Bevy app.

debug-render