Files
g4borg 325e278af1 Scaffold bevy plugin with bevy-0.19 and bevy-upgrade skills
Add plugin skeleton with versioned skill directories, TODO SKILL.md
scaffolds with goals for skill-creator, and copy over bevy-skill-research
reports from spacecraft into docs/workpad/research/.
2026-07-07 17:52:00 +02:00

3.4 KiB

Bevy Skill Research: Input System

Bevy version: 0.18, with 0.19 notes
Date: 2026-07-07

Keyboard Input (Res<ButtonInput<KeyCode>>)

Method Returns Purpose
pressed(KeyCode) bool Held this frame
just_pressed(KeyCode) bool First frame pressed
just_released(KeyCode) bool First frame released
any_pressed(impl IntoIterator) bool Any of these held
any_just_pressed(...) bool Any of these just pressed
all_pressed(...) bool All of these held
get_pressed() impl Iterator Iterate all held keys
get_just_pressed() impl Iterator Iterate newly pressed
clear_just_pressed(KeyCode) bool Consume the event

Also available: ButtonInput<Key> for logical/locale-aware keys.

Updated by keyboard_input_system from KeyboardInput events.

Mouse Input

Buttons: Res<ButtonInput<MouseButton>> — same API as keyboard.
Variants: Left, Right, Middle, Back, Forward, Other(u16).

Motion:

Type Kind Purpose
MouseMotion Event delta: Vec2 per raw motion event
AccumulatedMouseMotion Resource Total delta this frame, reset each frame
MouseWheel Event Scroll with MouseScrollUnit (Line/Pixel)
AccumulatedMouseScroll Resource Total scroll this frame

Cursor position: Read from Window component:

fn cursor(windows: Query<&Window>) {
    if let Ok(window) = windows.single() {
        if let Some(pos) = window.cursor_position() {
            // pos is Vec2 in logical pixels, origin top-left
        }
    }
}

Gamepad Input

Buttons: Res<ButtonInput<GamepadButton>> — same pressed/just_pressed API.

Axes: Res<Axis<GamepadAxis>>:

  • get(GamepadAxis) -> Option<f32> — range [-1.0, 1.0]
  • GamepadButton mapped range [0.0, 1.0] (triggers are analog)

Events: GamepadButtonStateChangedEvent, GamepadButtonChangedEvent, GamepadAxisChangedEvent, GamepadConnectionEvent.

Settings: GamepadSettings component for deadzone/threshold configuration.

Touch Input

  • TouchInput (Event) — touch event with TouchPhase (Began/Moved/Ended)
  • Touches (Resource) — query active touches, analogous to ButtonInput pattern
  • ForceTouch — pressure-sensitive data on supported devices
  • Requires touch feature flag in 0.18

Action Mapping

No built-in action mapping system in Bevy 0.18. Community crate leafwing-input-manager fills this role.

0.18 Change

Input sources (mouse, keyboard, gamepad, touch, gestures) are now feature-gated. Enabled by default with bevy_window/bevy_gilrs, but must be explicit with default-features = false.

Common Patterns

fn movement(
    keys: Res<ButtonInput<KeyCode>>,
    mouse: Res<ButtonInput<MouseButton>>,
) {
    if keys.just_pressed(KeyCode::Space) { /* fire */ }
    if mouse.pressed(MouseButton::Left) { /* hold fire */ }
    
    let mut dir = Vec3::ZERO;
    if keys.pressed(KeyCode::KeyW) { dir.z -= 1.0; }
    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; }
}

fn read_motion(mut motion: MessageReader<MouseMotion>) {
    for ev in motion.read() {
        // ev.delta.x, ev.delta.y
    }
}

Note: MouseMotion uses MessageReader (not EventReader) in 0.18+.