| Crates.io | bevy_ahoy |
| lib.rs | bevy_ahoy |
| version | 0.0.2 |
| created_at | 2025-11-23 14:56:09.086354+00 |
| updated_at | 2026-01-03 16:13:29.000281+00 |
| description | A fun 3D Kinematic Character Controller for Bevy + Avian + BEI. |
| homepage | |
| repository | https://github.com/janhohenheim/bevy_ahoy |
| max_upload_size | |
| id | 1946652 |
| size | 313,810 |
[!IMPORTANT]
Bevy Ahoy makes use of an unreleased avian version.To ensure it works you'll need to add a patch in your Cargo.toml
[patch.crates-io] avian3d = { git = "https://github.com/avianphysics/avian" }
A fun 3D Kinematic Character Controller for Bevy + Avian + BEI.
https://github.com/user-attachments/assets/ad1648d9-8a3d-43a6-9e20-886d6bb2eaad
Surf gameplay by Boonie, who kindly converted the Utopia surf map to a compatible format. See assets/maps/license.md for licensing information
Character controller means that this crate allows you to move characters in a video game around. This can be either player characters or NPCs.
Kinematic means that the controller intentionally does not fully obey the simulation rules of the physics engine. That means that the character will, for example, ignore any forces. This tradeoff allows Ahoy to fully define its own separate model of how a character should move regardless of what the laws of physics say. The goal is not realism, the goal is ~ fun ~
CharacterControllerCameraOf to a camera to have out-of-the-box first person camera behavioruse bevy::prelude::*;
use bevy_enhanced_input::prelude::*;
use bevy_ahoy::prelude::*;
// app.add_plugins((
// DefaultPlugins,
// EnhancedInputPlugin,
// PhysicsPlugins::default(),
// AhoyPlugin::default(),
// ))
// .add_input_context::<PlayerInput>();
#[derive(Component)]
struct PlayerInput;
fn spawn_player(mut commands: Commands) {
// Spawn the player entity
let player = commands
.spawn((
// The character controller configuration
CharacterController::default(),
Transform::from_xyz(0.0, 20.0, 0.0),
// Configure inputs
PlayerInput,
actions!(PlayerInput[
(
Action::<Movement>::new(),
DeadZone::default(),
Bindings::spawn((
Cardinal::wasd_keys(),
Axial::left_stick()
))
),
(
Action::<Jump>::new(),
bindings![KeyCode::Space, GamepadButton::South],
),
(
Action::<Crouch>::new(),
bindings![KeyCode::ControlLeft, GamepadButton::LeftTrigger],
),
(
Action::<RotateCamera>::new(),
Scale::splat(0.04),
Bindings::spawn((
Spawn(Binding::mouse_motion()),
Axial::right_stick()
))
),
]),
))
.id();
// Spawn the camera
commands.spawn((
Camera3d::default(),
// Enable the optional builtin camera controller
CharacterControllerCameraOf::new(player),
));
}
KCCs are incredibly closely tied to their games. At the same time, a lot of games or prototypes need something that Just Works. For this reason, many KCC libraries try to be extremely configurable. However, I found that in my personal projects, I never really vibed with all that API baggage. For most use-cases, I just wanted a sensible set of defaults that Just Worked, thank you kindly. On the other hand, features that the library didn't plan for, like wall running, often lead me to explore the guts of the library anyways, and a fork was more practical than indirectly charming the library into doing my bidding through its configuration.
As such, I designed Bevy Ahoy to be what I wished existed when I started Bevy: something simple that I don't need to spend much time learning, that I can just plug in and use if I need basic first person movement. To enable this, I consciously decided to limit the configurability of Ahoy. If you need specific features to your game that Ahoy doesn't bring out of the box, I encourage you to fork it. Feel free to open an issue or ping me on the Bevy Discord if you need help with that :)
With that said, here are some goals of Ahoy:
bevy_enhanced_input
In contrast, here are some deliberate non-goals:
bevy_enhanced_input| bevy | bevy_ahoy |
|---|---|
| 0.17 | main |