mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Add Gamepads resource (#3257)
# Objective Fixes #3245 ## Solution - Move GamepadLobby to lib - Add connection_system to InputPlugin - Updated gamepad_input example Co-authored-by: CrazyRoka <rokarostuk@gmail.com> Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
parent
ca80fe65ed
commit
01e2141ce3
3 changed files with 65 additions and 37 deletions
|
@ -1,12 +1,42 @@
|
|||
use crate::{Axis, Input};
|
||||
use bevy_app::{EventReader, EventWriter};
|
||||
use bevy_ecs::system::{Res, ResMut};
|
||||
use bevy_utils::HashMap;
|
||||
use bevy_utils::{tracing::info, HashMap, HashSet};
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Gamepad(pub usize);
|
||||
|
||||
#[derive(Default)]
|
||||
/// Container of unique connected [Gamepad]s
|
||||
///
|
||||
/// [Gamepad]s are registered and deregistered in [gamepad_connection_system]
|
||||
pub struct Gamepads {
|
||||
gamepads: HashSet<Gamepad>,
|
||||
}
|
||||
|
||||
impl Gamepads {
|
||||
/// Returns true if the [Gamepads] contains a [Gamepad].
|
||||
pub fn contains(&self, gamepad: &Gamepad) -> bool {
|
||||
self.gamepads.contains(gamepad)
|
||||
}
|
||||
|
||||
/// Iterates over registered [Gamepad]s
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Gamepad> + '_ {
|
||||
self.gamepads.iter()
|
||||
}
|
||||
|
||||
/// Registers [Gamepad].
|
||||
fn register(&mut self, gamepad: Gamepad) {
|
||||
self.gamepads.insert(gamepad);
|
||||
}
|
||||
|
||||
/// Deregisters [Gamepad.
|
||||
fn deregister(&mut self, gamepad: &Gamepad) {
|
||||
self.gamepads.remove(gamepad);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub enum GamepadEventType {
|
||||
|
@ -204,6 +234,28 @@ impl ButtonAxisSettings {
|
|||
}
|
||||
}
|
||||
|
||||
/// Monitors gamepad connection and disconnection events, updating the [GamepadLobby] resource accordingly
|
||||
///
|
||||
/// By default, runs during `CoreStage::PreUpdate` when added via [InputPlugin].
|
||||
pub fn gamepad_connection_system(
|
||||
mut gamepads: ResMut<Gamepads>,
|
||||
mut gamepad_event: EventReader<GamepadEvent>,
|
||||
) {
|
||||
for event in gamepad_event.iter() {
|
||||
match &event {
|
||||
GamepadEvent(gamepad, GamepadEventType::Connected) => {
|
||||
gamepads.register(*gamepad);
|
||||
info!("{:?} Connected", gamepad);
|
||||
}
|
||||
GamepadEvent(gamepad, GamepadEventType::Disconnected) => {
|
||||
gamepads.deregister(gamepad);
|
||||
info!("{:?} Disconnected", gamepad);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gamepad_event_system(
|
||||
mut button_input: ResMut<Input<GamepadButton>>,
|
||||
mut axis: ResMut<Axis<GamepadAxis>>,
|
||||
|
|
|
@ -15,7 +15,7 @@ pub mod prelude {
|
|||
pub use crate::{
|
||||
gamepad::{
|
||||
Gamepad, GamepadAxis, GamepadAxisType, GamepadButton, GamepadButtonType, GamepadEvent,
|
||||
GamepadEventType,
|
||||
GamepadEventType, Gamepads,
|
||||
},
|
||||
keyboard::KeyCode,
|
||||
mouse::MouseButton,
|
||||
|
@ -27,11 +27,12 @@ pub mod prelude {
|
|||
use bevy_app::prelude::*;
|
||||
use keyboard::{keyboard_input_system, KeyCode, KeyboardInput};
|
||||
use mouse::{mouse_button_input_system, MouseButton, MouseButtonInput, MouseMotion, MouseWheel};
|
||||
use prelude::Gamepads;
|
||||
use touch::{touch_screen_input_system, TouchInput, Touches};
|
||||
|
||||
use gamepad::{
|
||||
gamepad_event_system, GamepadAxis, GamepadButton, GamepadEvent, GamepadEventRaw,
|
||||
GamepadSettings,
|
||||
gamepad_connection_system, gamepad_event_system, GamepadAxis, GamepadButton, GamepadEvent,
|
||||
GamepadEventRaw, GamepadSettings,
|
||||
};
|
||||
|
||||
/// Adds keyboard and mouse input to an App
|
||||
|
@ -64,6 +65,7 @@ impl Plugin for InputPlugin {
|
|||
.add_event::<GamepadEvent>()
|
||||
.add_event::<GamepadEventRaw>()
|
||||
.init_resource::<GamepadSettings>()
|
||||
.init_resource::<Gamepads>()
|
||||
.init_resource::<Input<GamepadButton>>()
|
||||
.init_resource::<Axis<GamepadAxis>>()
|
||||
.init_resource::<Axis<GamepadButton>>()
|
||||
|
@ -71,6 +73,10 @@ impl Plugin for InputPlugin {
|
|||
CoreStage::PreUpdate,
|
||||
gamepad_event_system.label(InputSystem),
|
||||
)
|
||||
.add_system_to_stage(
|
||||
CoreStage::PreUpdate,
|
||||
gamepad_connection_system.label(InputSystem),
|
||||
)
|
||||
// touch
|
||||
.add_event::<TouchInput>()
|
||||
.init_resource::<Touches>()
|
||||
|
|
|
@ -1,49 +1,19 @@
|
|||
use bevy::{
|
||||
input::gamepad::{Gamepad, GamepadButton, GamepadEvent, GamepadEventType},
|
||||
prelude::*,
|
||||
utils::HashSet,
|
||||
};
|
||||
use bevy::{input::gamepad::GamepadButton, prelude::*};
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.init_resource::<GamepadLobby>()
|
||||
.add_system_to_stage(CoreStage::PreUpdate, connection_system)
|
||||
.add_system(gamepad_system)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct GamepadLobby {
|
||||
gamepads: HashSet<Gamepad>,
|
||||
}
|
||||
|
||||
fn connection_system(
|
||||
mut lobby: ResMut<GamepadLobby>,
|
||||
mut gamepad_event: EventReader<GamepadEvent>,
|
||||
) {
|
||||
for event in gamepad_event.iter() {
|
||||
match &event {
|
||||
GamepadEvent(gamepad, GamepadEventType::Connected) => {
|
||||
lobby.gamepads.insert(*gamepad);
|
||||
info!("{:?} Connected", gamepad);
|
||||
}
|
||||
GamepadEvent(gamepad, GamepadEventType::Disconnected) => {
|
||||
lobby.gamepads.remove(gamepad);
|
||||
info!("{:?} Disconnected", gamepad);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn gamepad_system(
|
||||
lobby: Res<GamepadLobby>,
|
||||
gamepads: Res<Gamepads>,
|
||||
button_inputs: Res<Input<GamepadButton>>,
|
||||
button_axes: Res<Axis<GamepadButton>>,
|
||||
axes: Res<Axis<GamepadAxis>>,
|
||||
) {
|
||||
for gamepad in lobby.gamepads.iter().cloned() {
|
||||
for gamepad in gamepads.iter().cloned() {
|
||||
if button_inputs.just_pressed(GamepadButton(gamepad, GamepadButtonType::South)) {
|
||||
info!("{:?} just pressed South", gamepad);
|
||||
} else if button_inputs.just_released(GamepadButton(gamepad, GamepadButtonType::South)) {
|
||||
|
|
Loading…
Reference in a new issue