Files
reliquary/docs/workpad/research/bevy-skill-research/05-input.md
T
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

100 lines
3.4 KiB
Markdown

# 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:
```rust
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
```rust
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+.