# Bevy Input Bindings
Bevy Input Bindings is a layer built on top of Bevy's input system to simplify input integration in
your projects.
It serves as an alternative to
[Bevy enhanced input](https://github.com/simgine/bevy_enhanced_input). If Bevy Input Bindings
doesn’t meet your needs, consider exploring Bevy Enhanced Input.
## Bevy compatibility
`bevy_input_bindings` is compatible only with bevy `0.17`.
## Getting started
Check out the [examples](examples) to see how it works.
## Keywords
### Controller
A controller interface is a component that identifies a controller. It is automatically attached to
either a gamepad or a keyboard binding.
### Action
An action is a named "event" that happened on a controller. For instance, a player pressed the `A`
key on the keyboard will trigger the `Jump` action.
#### Trigger
A trigger is what defines "When the action will happen". For instance the keyboard
`ButtonJustPressed` will trigger the action event when the selected button has just been pressed.
#### Action key
An action key is what allows to identify the action that has been triggered. It is a user-defined
rust type, often an enum.
For instance:
```rust
enum MyActionKey {
Jump,
Shoot,
}
```
### Value
A value is a continuous representation of the controller state. For instance the boolean state of
a button or the value of a gamepad axis. This value can be accessed thanks to the
`ControllerValues<_>` component that is automatically added to each controllers.
#### Function
A function what transfers the gamepad state to a defined `VariantValue`. For instance the
`ButtonPressed` value function will load the boolean state of a button in the `ControllerValues`.
#### Value key
An value key is what allows to identify the value that has been computed. It is a user-defined
rust type, often an enum.
For instance:
```rust
enum MyValueKey {
Move,
}
```
## Features
### Abstract actions
Bevy Input Bindings translates input commands — such as those from a keyboard or gamepad — into
custom Bevy actions, which are then sent as events. Your game needs to listen for these actions
to respond accordingly.
```rust
#[derive(Debug)]
enum MyAction {
Jump,
Shoot,
}
app.add_observer(|action: On<ActionEvent<MyAction>>| {
info!("Action from entity {}: {:?}", action.controller(), action.action_key());
});
```
Checkout the [Keyboard example](examples/keyboard.rs) or the [Gamepad example](examples/gamepad.rs).
### Abstract values
Bevy Input Bindings also translates input commands into component values, enabling continuous input
reading and reducing event spam.
```rust
#[derive(Debug, Hash, PartialEq, Eq)]
enum MyValues {
Move,
}
app.add_systems(Update, |values: Query<&ControllerValues<MyValues>>|{
for controller_value in controller_values {
// Values are variants that have to be deconstructed
match &controller_value.get(&MyValues::Move) {
Some(VariantValue::Axis2d(val0, val1)) => {
// Print only if the values are not 0
if *val0 == 0.0 && *val1 == 0.0 {
continue;
}
info!("Move: {val0:0.2}:{val1:0.2}");
}
_ => (),
}
}
})
```
Checkout the [Keyboard example](examples/keyboard.rs) or the [Gamepad example](examples/gamepad.rs).
### One Keyboard, multiple players
One of the primary goals of Bevy Input Bindings is to allow two players to use the same keyboard.
This is achieved through the keyboard binder. Refer to the examples to learn how to implement this
feature.
Checkout the [Split keyboard example](examples/split_keyboard.rs).
### Gamepad connection and deconnection handling
If a gamepad gets connected, binders will automatically be attached to it. This is why the default
trait has to be implemented for the keyboard binder.
If a controller disconnect during a game and gets reconnected, it should be binded to the same
player. This is native in Bevy but Bevy input binding have to keep this consistency.
### Inputs conversion
Bevy Input Bindings supports input conversion, such as turning a button press into a float value or
converting a float value into a boolean using a hysteresis function.
This is particularly useful for player movement based on axes and directional inputs.
### Conditional binding
Bevy Input Bindings allows bindings to change dynamically based on external values or conditions.
Checkout the [Conditional binding example](examples/conditional_binding.rs).
### Control relationship
The library includes a tool to mark entities as being controlled by a specific controller.
This makes it easier to identify which entity is targeted by triggered actions or which values to
read.
The list of the controlled entities is stored inside each actions.
Checkout the [Relation example](examples/relation.rs) and the
[Gamepad relation example](examples/gamepad_relation.rs).
### Splitscreen UI controlling
Bevy Input Bindings enables multiple players on a single screen to control either the main UI or
specific parts of it, such as character selection menus.
### On the shelf binders
A lot of game will use the same bindings, for instance most game will have gamepads controlling the
UI in a similar manner. This is why OTS binder can be provided directly in this crate.
Checkout the [On the shelf UI example](examples/ots_ui.rs).
### Multiple bindings on one controller
To keep your code clean and shareable, multiple binders can be combined on a single controller. This
would allow for instance to use the OTS binder for the UI while developping a custom for the game.
Checkout the [Mutli binder example](examples/multi_binder.rs).
## Limitations
### Mouse
The mouse controllers are not yet implemented.
### ControlledBy two controllers
You may want to have two controllers (e.g. a gamepad and a keyboard) controlling the same entity
(a character). Due to the one-to-many nature of the bevy relationships, the `ControlledBy` component
will not help you doing this.
This is a niche application, but in case you want to do it, checkout the
[Mutli controller example](examples/multi_controller.rs).
## License
Licensed under the [MPL2 license](LICENSE.MPL2)