An input action plugin for Bevy
A tiny abstraction layer for input handling in Bevy that decouples input sources from game logic through clean action-based interfaces.
Raw input handling leads to:
- Tight coupling between devices and game logic
- Code duplication across input methods
- Messy state management
InputActionDrain
is a system parameter, that is the vassel into which the systems pour input action state.
For example a system would read keyboard input and pour the state into the appropriate
InputActionDrain
.
InputActionState
is a system parameter, that is the source of current input action state. The gameplay system
(i.e. movement, jump) would read the input action state from this.
InputActionReader
is a system parameter, that provides an event based interface, similar to EventReader
(actually it
uses an event reader under the hood). The read values are of type InputActionStatus
—an InputActionStatus
can be one of:
Started
when the input action has just started to be active,Updated
when the input action has already been active, but the value has changed,Stopped
when the input action had been active, but now is not.
This library provides several input action based system run conditions. Those are:
input_action_active
: The system will run each frame the input action is activeinput_action_started
: Similar toButtonInput
'sjust_pressed
—will make your system run at the frame on which the action has startedinput_action_updated
: The system will run if the state of an input action has changed (i.e. an axis changed direction)input_action_stopped
: The system will run once the input action gets stopped (i.e. a button has been released)
use bevy::{prelude::*, input::InputSystem};
use bevy_actify::prelude::*;
// 1. Define your action
#[derive(InputAction, Clone, PartialEq)]
struct Jump(f32); // f32 for analog sensetivity
// 2. Map inputs to actions
fn keyboard_input(keyboard: Res<ButtonInput<KeyCode>>, mut action: InputActionDrain<Jump>) {
if keyboard.pressed(KeyCode::Space) {
action.pour(Jump(1f32));
}
}
// 3. Use in game systems
fn character_jump(action: InputActionState<Jump>) {
if let Some(state) = action.state() {
let jump_power = state.0;
// Apply force...
}
}
// 4. Register the input action and systems
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_input_action::<Jump>()
.add_systems(PreUpdate, keyboard_input.after(InputSystem).before(InputActionSystem)) // properly order your systems to avoid 1 frame delay!
.add_systems(Update, character_jump)
.run();
}
Fork repository, make changes, and send us a pull request.
We will review your changes and apply them to the main branch shortly, provided they don't violate our quality standards.
This project is dual-licensed under:
You may choose either license at your option.