Replace scaffold placeholders with full skill content: - bevy-0.19: ECS cheat sheet, critical traps table, architecture guide, and 7 reference files - bevy-upgrade: version migration workflow, transition references for 0.15→0.19, and 3 per-bump reference files
2.9 KiB
Input
Keyboard — Res<ButtonInput<KeyCode>>
| Method | Purpose |
|---|---|
pressed(k) |
held this frame |
just_pressed(k) / just_released(k) |
edge detection |
any_pressed(iter) / any_just_pressed(iter) / all_pressed(iter) |
multi-key checks |
get_pressed() / get_just_pressed() |
iterate held / newly pressed |
clear_just_pressed(k) |
consume the press |
ButtonInput<Key> exists for logical/locale-aware keys (text-ish input); KeyCode is physical layout.
Mouse
Buttons: Res<ButtonInput<MouseButton>> — same API. Variants: Left, Right, Middle, Back, Forward, Other(u16).
Motion and scroll:
| Type | Kind | Purpose |
|---|---|---|
MouseMotion |
Message | raw per-event delta: Vec2 — read with MessageReader<MouseMotion> |
AccumulatedMouseMotion |
Resource | frame total, reset each frame — usually what you want |
MouseWheel |
Message | scroll with MouseScrollUnit (Line/Pixel) |
AccumulatedMouseScroll |
Resource | frame total scroll |
Cursor position — from the Window component, logical pixels, origin top-left:
fn cursor(windows: Query<&Window>) -> Result {
if let Some(pos) = windows.single()?.cursor_position() { /* ... */ }
Ok(())
}
UI click-through trap: ButtonInput<MouseButton> is raw winit input — it fires even when the click landed on a UI panel. World-click handlers must verify the click wasn't consumed by UI (e.g. a full-screen background Interaction node that only receives clicks passing through all UI).
Gamepad
- Buttons:
Res<ButtonInput<GamepadButton>>— same pressed/just_pressed API; analog buttons also map to[0.0, 1.0]. - Axes:
Res<Axis<GamepadAxis>>→get(axis) -> Option<f32>in[-1.0, 1.0]. - Messages:
GamepadButtonStateChangedEvent,GamepadButtonChangedEvent,GamepadAxisChangedEvent,GamepadConnectionEvent. - Deadzones/thresholds:
GamepadSettingscomponent.
Touch
TouchInputmessage withTouchPhase(Began/Moved/Ended).Touchesresource — active-touch queries, analogous toButtonInput.ForceTouchfor pressure-capable devices.- Requires the
touchfeature flag.
Feature gating (0.18+)
Input sources (mouse, keyboard, gamepad, touch, gestures) are feature-gated. They're on by default via bevy_window/bevy_gilrs, but with default-features = false they must be listed explicitly — missing input with no errors usually means a missing feature.
Action mapping
Bevy has no built-in action-mapping layer. The community standard is leafwing-input-manager; check the project's Cargo.toml before hand-rolling bindings.
Pattern
fn movement(keys: Res<ButtonInput<KeyCode>>) {
let mut dir = Vec3::ZERO;
if keys.pressed(KeyCode::KeyW) { dir.z -= 1.0; } // forward is -Z
if keys.pressed(KeyCode::KeyS) { dir.z += 1.0; }
if keys.pressed(KeyCode::KeyA) { dir.x -= 1.0; }
if keys.pressed(KeyCode::KeyD) { dir.x += 1.0; }
}