bevy_input_bindings 0.0.2

High level, flexible and shareable input binding library for the Bevy game engine
Documentation
use bevy::prelude::*;

use bevy_input_bindings::prelude::*;

fn main() {
    App::new()
        .add_plugins((
            DefaultPlugins,
            // Add the keyboard plugin attached to the custom binder
            gamepad::Plugin::<MyActions, MyValues, MyGamepadBinding>::new(),
        ))
        // Add an observer to print the inputs. It will catch events for the `MyActions` actions,
        // find the `ControllerInterface` that sent it, and print the event data.
        .add_observer(
            |action: On<ActionEvent<MyActions>>, controllers: Query<&ControllerInterface>| {
                // Find the controller that sent the event
                let Ok(controller) = controllers.get(action.controller()) else {
                    return;
                };
                // Print data about this action
                println!(
                    "Action from {}({:?}): {:?}",
                    action.controller(),
                    controller.layout(),
                    action.key()
                );
            },
        )
        .add_systems(Startup, |mut commands: Commands| {
            commands.spawn(Camera3d::default());
        })
        // Log the values
        .add_systems(Update, |values: Query<&ControllerValues<MyValues>>| {
            for value in values {
                // Only log the 2 axis values
                let Some((val0, val1)) = value.get_as_axis2d(&MyValues::Move) else {
                    continue;
                };
                // Log the 2 axis values only if it is not (0.0, 0.0)
                if val0 == 0.0 && val1 == 0.0 {
                    continue;
                }
                // Log
                println!("Move: {val0:0.2}:{val1:0.2}");
            }
        })
        .run();
}

/// Custom actions for this example
#[derive(Debug)]
enum MyActions {
    Jump,
    Shoot,
}

/// Custom values for this example
#[derive(Debug, Hash, PartialEq, Eq)]
enum MyValues {
    Move,
}

/// Custom binder for this example
#[derive(Component, Reflect)]
struct MyGamepadBinding {
    jump: gamepad::triggers::ButtonPressed,
    shoot: gamepad::triggers::Hysteresis,
    character_move: gamepad::values::Direct2d,
}

/// Implement the default trait to define what will be automatically added to a connecting gamepad
impl Default for MyGamepadBinding {
    fn default() -> Self {
        Self {
            jump: gamepad::triggers::ButtonPressed::new(GamepadButton::South),
            shoot: gamepad::triggers::Hysteresis::new_above(GamepadAxis::RightStickX, 0.5, 0.9),
            character_move: gamepad::values::Direct2d::new(
                GamepadAxis::LeftStickX,
                GamepadAxis::LeftStickY,
            ),
        }
    }
}

impl gamepad::Binding<MyActions, MyValues> for MyGamepadBinding {
    fn get_action_bindings<'a>(
        &'a mut self,
    ) -> Vec<(&'a mut dyn gamepad::triggers::TriggerTrait, MyActions)> {
        return vec![(&mut self.jump, MyActions::Jump), (&mut self.shoot, MyActions::Shoot)];
    }

    fn get_value_bindings<'a>(
        &'a mut self,
    ) -> Vec<(&'a mut dyn gamepad::values::FunctionTrait, MyValues)> {
        return vec![(&mut self.character_move, MyValues::Move)];
    }
}