Integration of bevy gamepad support
Until the beginning of my game all controle where hard coded in the code that handle the logic.
I need to do two things with my controller code:
Split it inside the client code.
Send the client code action to the shared code.
Use abstraction to handle gamepad and input for each player
For now i will only two the second one for the gamepad and latter on i will split the input and the logic code. Also i need to prepare my code for local multiplayer and replace all the case that handle ressource considering that only one set can exists , of the player one, but it all need to loop on each player.
Starting gamepad support
I added issue at first to get things to work. I try to integrate the events but none where triggering.
All because inside my Cargo.yaml
i had default-features: false
so the package that i needed for
gamepad support bevy_gilrs
was not compilling. I added it and now it’s working fine.
So what i did is a written a small struct with an implementation similar to Input<> of bevy that contains a reference to all input source needed and depending on the player configure and it’s input configuration to get the input event.
I then write a ugly as fuck typealias with an tuple to store the mapping for each type on controller and i use this.
pub type GameButton = (KeyCode, MouseButton, GamepadButtonType);
pub const CHANGE_WEAPON_BTN: GameButton = (KeyCode::Tab, MouseButton::Middle, GamepadButtonType::North);
pub const RELOAD_WEAPON_BTN: GameButton = (KeyCode::R, MouseButton::Right, GamepadButtonType::West);
pub const FIRED_WEAPON_BTN: GameButton = (KeyCode::Space, MouseButton::Left, GamepadButtonType::RightTrigger);
pub const INTERACTION_BTN: GameButton = (KeyCode::F, MouseButton::Other(0), GamepadButtonType::South);
pub struct PlayerInputs<'a> {
pub keyboard_input: &'a Res<'a,Input<KeyCode>>,
pub buttons_mouse: &'a Res<'a, Input<MouseButton>>,
pub buttons_gamepad: &'a Res<'a, Input<GamepadButton>>,
pub current_controller: &'a PlayerCurrentInput,
}
impl <'a> PlayerInputs <'a> {
pub fn pressed(&self, button: &GameButton) -> bool {
return if self.current_controller.input_source == SupportedController::Keyboard {
return self.keyboard_input.pressed(button.0) || self.buttons_mouse.pressed(button.1);
} else {
let gamepad_button = GamepadButton(self.current_controller.gamepad.unwrap(), button.2);
return self.buttons_gamepad.pressed(gamepad_button);
}
}
pub fn just_pressed(&self, button: &GameButton) -> bool {
return if self.current_controller.input_source == SupportedController::Keyboard {
return self.keyboard_input.just_pressed(button.0) || self.buttons_mouse.just_pressed(button.1);
} else {
let gamepad_button = GamepadButton(self.current_controller.gamepad.unwrap(), button.2);
return self.buttons_gamepad.just_pressed(gamepad_button);
}
}
}
What i need to do is have to only receive the Input source but it’s more complicated and i would have to deal with dynamic implementation so i did this simple solution instead for now. Very not clean but it does the job.
Also i modified my LookingAt
component to have a mode with instead of receive a point where you look it’s only
a direction of where you are looking at. Usefull for my gamepad support to translate the mouse point location to
the right joystick.