mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 21:53:07 +00:00
Separate gamepad state code from gamepad event code and other customizations (#700)
Separated gamepad event and gamepad state code and made gamepad input more customizable
This commit is contained in:
parent
0f43fb066f
commit
d01ba9e4fc
8 changed files with 354 additions and 232 deletions
|
@ -230,6 +230,10 @@ path = "examples/input/keyboard_input_events.rs"
|
|||
name = "gamepad_input"
|
||||
path = "examples/input/gamepad_input.rs"
|
||||
|
||||
[[example]]
|
||||
name = "gamepad_input_event"
|
||||
path = "examples/input/gamepad_input_event.rs"
|
||||
|
||||
[[example]]
|
||||
name = "touch_input"
|
||||
path = "examples/input/touch_input.rs"
|
||||
|
|
|
@ -2,88 +2,52 @@ use crate::converter::{convert_axis, convert_button, convert_gamepad_id};
|
|||
use bevy_app::Events;
|
||||
use bevy_ecs::{Resources, World};
|
||||
use bevy_input::prelude::*;
|
||||
use gilrs::{Button, EventType, Gilrs};
|
||||
use gilrs::{EventType, Gilrs};
|
||||
|
||||
pub fn gilrs_startup_system(_world: &mut World, resources: &mut Resources) {
|
||||
pub fn gilrs_event_startup_system(_world: &mut World, resources: &mut Resources) {
|
||||
let gilrs = resources.get_thread_local::<Gilrs>().unwrap();
|
||||
let mut gamepad_event = resources.get_mut::<Events<GamepadEvent>>().unwrap();
|
||||
let mut inputs = resources.get_mut::<Input<GamepadButton>>().unwrap();
|
||||
let mut axes = resources.get_mut::<Axis<GamepadAxis>>().unwrap();
|
||||
let mut button_axes = resources.get_mut::<Axis<GamepadButton>>().unwrap();
|
||||
gamepad_event.update();
|
||||
inputs.update();
|
||||
for (gilrs_id, gilrs_gamepad) in gilrs.gamepads() {
|
||||
connect_gamepad(
|
||||
gilrs_gamepad,
|
||||
convert_gamepad_id(gilrs_id),
|
||||
&mut gamepad_event,
|
||||
&mut inputs,
|
||||
&mut axes,
|
||||
&mut button_axes,
|
||||
);
|
||||
let mut event = resources.get_mut::<Events<GamepadEvent>>().unwrap();
|
||||
event.update();
|
||||
for (id, _) in gilrs.gamepads() {
|
||||
event.send(GamepadEvent(
|
||||
convert_gamepad_id(id),
|
||||
GamepadEventType::Connected,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gilrs_update_system(_world: &mut World, resources: &mut Resources) {
|
||||
pub fn girls_event_system(_world: &mut World, resources: &mut Resources) {
|
||||
let mut gilrs = resources.get_thread_local_mut::<Gilrs>().unwrap();
|
||||
let mut gamepad_event = resources.get_mut::<Events<GamepadEvent>>().unwrap();
|
||||
let mut inputs = resources.get_mut::<Input<GamepadButton>>().unwrap();
|
||||
let mut axes = resources.get_mut::<Axis<GamepadAxis>>().unwrap();
|
||||
let mut button_axes = resources.get_mut::<Axis<GamepadButton>>().unwrap();
|
||||
|
||||
gamepad_event.update();
|
||||
inputs.update();
|
||||
let mut event = resources.get_mut::<Events<GamepadEvent>>().unwrap();
|
||||
event.update();
|
||||
while let Some(gilrs_event) = gilrs.next_event() {
|
||||
match gilrs_event.event {
|
||||
EventType::Connected => {
|
||||
connect_gamepad(
|
||||
gilrs.gamepad(gilrs_event.id),
|
||||
event.send(GamepadEvent(
|
||||
convert_gamepad_id(gilrs_event.id),
|
||||
&mut gamepad_event,
|
||||
&mut inputs,
|
||||
&mut axes,
|
||||
&mut button_axes,
|
||||
);
|
||||
GamepadEventType::Connected,
|
||||
));
|
||||
}
|
||||
EventType::Disconnected => {
|
||||
disconnect_gamepad(
|
||||
event.send(GamepadEvent(
|
||||
convert_gamepad_id(gilrs_event.id),
|
||||
&mut gamepad_event,
|
||||
&mut inputs,
|
||||
&mut axes,
|
||||
&mut button_axes,
|
||||
);
|
||||
}
|
||||
EventType::ButtonPressed(gilrs_button, _) => {
|
||||
if let Some(button_type) = convert_button(gilrs_button) {
|
||||
inputs.press(GamepadButton(
|
||||
convert_gamepad_id(gilrs_event.id),
|
||||
button_type,
|
||||
));
|
||||
}
|
||||
}
|
||||
EventType::ButtonReleased(gilrs_button, _) => {
|
||||
if let Some(button_type) = convert_button(gilrs_button) {
|
||||
inputs.release(GamepadButton(
|
||||
convert_gamepad_id(gilrs_event.id),
|
||||
button_type,
|
||||
));
|
||||
}
|
||||
GamepadEventType::Disconnected,
|
||||
));
|
||||
}
|
||||
EventType::ButtonChanged(gilrs_button, value, _) => {
|
||||
if let Some(button_type) = convert_button(gilrs_button) {
|
||||
button_axes.set(
|
||||
GamepadButton(convert_gamepad_id(gilrs_event.id), button_type),
|
||||
value,
|
||||
);
|
||||
event.send(GamepadEvent(
|
||||
convert_gamepad_id(gilrs_event.id),
|
||||
GamepadEventType::ButtonChanged(button_type, value),
|
||||
));
|
||||
}
|
||||
}
|
||||
EventType::AxisChanged(gilrs_axis, value, _) => {
|
||||
if let Some(axis_type) = convert_axis(gilrs_axis) {
|
||||
axes.set(
|
||||
GamepadAxis(convert_gamepad_id(gilrs_event.id), axis_type),
|
||||
value,
|
||||
);
|
||||
event.send(GamepadEvent(
|
||||
convert_gamepad_id(gilrs_event.id),
|
||||
GamepadEventType::AxisChanged(axis_type, value),
|
||||
));
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
|
@ -91,88 +55,3 @@ pub fn gilrs_update_system(_world: &mut World, resources: &mut Resources) {
|
|||
}
|
||||
gilrs.inc();
|
||||
}
|
||||
|
||||
const ALL_GILRS_BUTTONS: [Button; 19] = [
|
||||
Button::South,
|
||||
Button::East,
|
||||
Button::North,
|
||||
Button::West,
|
||||
Button::C,
|
||||
Button::Z,
|
||||
Button::LeftTrigger,
|
||||
Button::LeftTrigger2,
|
||||
Button::RightTrigger,
|
||||
Button::RightTrigger2,
|
||||
Button::Select,
|
||||
Button::Start,
|
||||
Button::Mode,
|
||||
Button::LeftThumb,
|
||||
Button::RightThumb,
|
||||
Button::DPadUp,
|
||||
Button::DPadDown,
|
||||
Button::DPadLeft,
|
||||
Button::DPadRight,
|
||||
];
|
||||
|
||||
const ALL_GILRS_AXES: [gilrs::Axis; 8] = [
|
||||
gilrs::Axis::LeftStickX,
|
||||
gilrs::Axis::LeftStickY,
|
||||
gilrs::Axis::LeftZ,
|
||||
gilrs::Axis::RightStickX,
|
||||
gilrs::Axis::RightStickY,
|
||||
gilrs::Axis::RightZ,
|
||||
gilrs::Axis::DPadX,
|
||||
gilrs::Axis::DPadY,
|
||||
];
|
||||
|
||||
fn connect_gamepad(
|
||||
gilrs_gamepad: gilrs::Gamepad,
|
||||
gamepad: Gamepad,
|
||||
events: &mut Events<GamepadEvent>,
|
||||
inputs: &mut Input<GamepadButton>,
|
||||
axes: &mut Axis<GamepadAxis>,
|
||||
button_axes: &mut Axis<GamepadButton>,
|
||||
) {
|
||||
for gilrs_button in ALL_GILRS_BUTTONS.iter() {
|
||||
if let Some(button_type) = convert_button(*gilrs_button) {
|
||||
if let Some(button_data) = gilrs_gamepad.button_data(*gilrs_button) {
|
||||
let gamepad_button = GamepadButton(gamepad, button_type);
|
||||
inputs.reset(gamepad_button);
|
||||
if button_data.is_pressed() {
|
||||
inputs.press(gamepad_button);
|
||||
}
|
||||
button_axes.set(gamepad_button, button_data.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
for gilrs_axis in ALL_GILRS_AXES.iter() {
|
||||
if let Some(axis_type) = convert_axis(*gilrs_axis) {
|
||||
let gamepad_axis = GamepadAxis(gamepad, axis_type);
|
||||
axes.set(gamepad_axis, gilrs_gamepad.value(*gilrs_axis));
|
||||
}
|
||||
}
|
||||
events.send(GamepadEvent(gamepad, GamepadEventType::Connected));
|
||||
}
|
||||
|
||||
fn disconnect_gamepad(
|
||||
gamepad: Gamepad,
|
||||
events: &mut Events<GamepadEvent>,
|
||||
inputs: &mut Input<GamepadButton>,
|
||||
axes: &mut Axis<GamepadAxis>,
|
||||
button_axes: &mut Axis<GamepadButton>,
|
||||
) {
|
||||
for gilrs_button in ALL_GILRS_BUTTONS.iter() {
|
||||
if let Some(button_type) = convert_button(*gilrs_button) {
|
||||
let gamepad_button = GamepadButton(gamepad, button_type);
|
||||
inputs.reset(gamepad_button);
|
||||
button_axes.remove(&gamepad_button);
|
||||
}
|
||||
}
|
||||
for gilrs_axis in ALL_GILRS_AXES.iter() {
|
||||
if let Some(axis_type) = convert_axis(*gilrs_axis) {
|
||||
let gamepad_axis = GamepadAxis(gamepad, axis_type);
|
||||
axes.remove(&gamepad_axis);
|
||||
}
|
||||
}
|
||||
events.send(GamepadEvent(gamepad, GamepadEventType::Disconnected));
|
||||
}
|
||||
|
|
|
@ -3,21 +3,23 @@ mod gilrs_system;
|
|||
|
||||
use bevy_app::prelude::*;
|
||||
use bevy_ecs::prelude::*;
|
||||
use gilrs_system::{gilrs_startup_system, gilrs_update_system};
|
||||
use gilrs::GilrsBuilder;
|
||||
use gilrs_system::{gilrs_event_startup_system, girls_event_system};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct GilrsPlugin;
|
||||
|
||||
impl Plugin for GilrsPlugin {
|
||||
fn build(&self, app: &mut AppBuilder) {
|
||||
match gilrs::Gilrs::new() {
|
||||
match GilrsBuilder::new()
|
||||
.with_default_filters(false)
|
||||
.set_update_state(false)
|
||||
.build()
|
||||
{
|
||||
Ok(gilrs) => {
|
||||
app.add_thread_local_resource(gilrs)
|
||||
.add_startup_system(gilrs_startup_system.thread_local_system())
|
||||
.add_system_to_stage(
|
||||
stage::EVENT_UPDATE,
|
||||
gilrs_update_system.thread_local_system(),
|
||||
);
|
||||
.add_startup_system(gilrs_event_startup_system.thread_local_system())
|
||||
.add_system_to_stage(stage::FIRST, girls_event_system.thread_local_system());
|
||||
}
|
||||
Err(err) => log::error!("Failed to start Gilrs. {}", err),
|
||||
}
|
||||
|
|
|
@ -24,11 +24,11 @@ where
|
|||
self.axis_data.insert(axis, value)
|
||||
}
|
||||
|
||||
pub fn get(&self, axis: &T) -> Option<f32> {
|
||||
self.axis_data.get(axis).copied()
|
||||
pub fn get(&self, axis: T) -> Option<f32> {
|
||||
self.axis_data.get(&axis).copied()
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, axis: &T) -> Option<f32> {
|
||||
self.axis_data.remove(axis)
|
||||
pub fn remove(&mut self, axis: T) -> Option<f32> {
|
||||
self.axis_data.remove(&axis)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
use crate::{Axis, Input};
|
||||
use bevy_app::{EventReader, Events};
|
||||
use bevy_ecs::{Local, Res, ResMut};
|
||||
use bevy_utils::HashMap;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct Gamepad(pub usize);
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub enum GamepadEventType {
|
||||
Connected,
|
||||
Disconnected,
|
||||
ButtonChanged(GamepadButtonType, f32),
|
||||
AxisChanged(GamepadAxisType, f32),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct GamepadEvent(pub Gamepad, pub GamepadEventType);
|
||||
|
||||
|
@ -57,3 +64,230 @@ pub enum GamepadAxisType {
|
|||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct GamepadAxis(pub Gamepad, pub GamepadAxisType);
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct GamepadSetting {
|
||||
pub default_button_setting: ButtonSetting,
|
||||
pub default_axis_setting: AxisSetting,
|
||||
pub default_button_axis_setting: ButtonAxisSetting,
|
||||
pub button_settings: HashMap<GamepadButton, ButtonSetting>,
|
||||
pub axis_settings: HashMap<GamepadAxis, AxisSetting>,
|
||||
pub button_axis_settings: HashMap<GamepadButton, ButtonAxisSetting>,
|
||||
}
|
||||
|
||||
impl GamepadSetting {
|
||||
pub fn get_button_setting(&self, button: GamepadButton) -> &ButtonSetting {
|
||||
self.button_settings
|
||||
.get(&button)
|
||||
.unwrap_or(&self.default_button_setting)
|
||||
}
|
||||
|
||||
pub fn get_axis_setting(&self, axis: GamepadAxis) -> &AxisSetting {
|
||||
self.axis_settings
|
||||
.get(&axis)
|
||||
.unwrap_or(&self.default_axis_setting)
|
||||
}
|
||||
|
||||
pub fn get_button_axis_setting(&self, button: GamepadButton) -> &ButtonAxisSetting {
|
||||
self.button_axis_settings
|
||||
.get(&button)
|
||||
.unwrap_or(&self.default_button_axis_setting)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ButtonSetting {
|
||||
pub press: f32,
|
||||
pub release: f32,
|
||||
}
|
||||
|
||||
impl Default for ButtonSetting {
|
||||
fn default() -> Self {
|
||||
ButtonSetting {
|
||||
press: 0.75,
|
||||
release: 0.65,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ButtonSetting {
|
||||
fn is_pressed(&self, value: f32) -> bool {
|
||||
value >= self.press
|
||||
}
|
||||
|
||||
fn is_released(&self, value: f32) -> bool {
|
||||
value <= self.release
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AxisSetting {
|
||||
pub positive_high: f32,
|
||||
pub positive_low: f32,
|
||||
pub negative_high: f32,
|
||||
pub negative_low: f32,
|
||||
pub threshold: f32,
|
||||
}
|
||||
|
||||
impl Default for AxisSetting {
|
||||
fn default() -> Self {
|
||||
AxisSetting {
|
||||
positive_high: 0.95,
|
||||
positive_low: 0.05,
|
||||
negative_high: -0.95,
|
||||
negative_low: -0.05,
|
||||
threshold: 0.01,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AxisSetting {
|
||||
fn filter(&self, new_value: f32, old_value: Option<f32>) -> f32 {
|
||||
if let Some(old_value) = old_value {
|
||||
if (new_value - old_value).abs() <= self.threshold {
|
||||
return old_value;
|
||||
}
|
||||
}
|
||||
if new_value <= self.positive_low && new_value >= self.negative_low {
|
||||
return 0.0;
|
||||
}
|
||||
if new_value >= self.positive_high {
|
||||
return 1.0;
|
||||
}
|
||||
if new_value <= self.negative_high {
|
||||
return -1.0;
|
||||
}
|
||||
new_value
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ButtonAxisSetting {
|
||||
pub high: f32,
|
||||
pub low: f32,
|
||||
pub threshold: f32,
|
||||
}
|
||||
|
||||
impl Default for ButtonAxisSetting {
|
||||
fn default() -> Self {
|
||||
ButtonAxisSetting {
|
||||
high: 0.95,
|
||||
low: 0.05,
|
||||
threshold: 0.01,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ButtonAxisSetting {
|
||||
fn filter(&self, new_value: f32, old_value: Option<f32>) -> f32 {
|
||||
if let Some(old_value) = old_value {
|
||||
if (new_value - old_value).abs() <= self.threshold {
|
||||
return old_value;
|
||||
}
|
||||
}
|
||||
if new_value <= self.low {
|
||||
return 0.0;
|
||||
}
|
||||
if new_value >= self.high {
|
||||
return 1.0;
|
||||
}
|
||||
new_value
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct GamepadEventState {
|
||||
gamepad_event_reader: EventReader<GamepadEvent>,
|
||||
}
|
||||
|
||||
pub fn gamepad_event_system(
|
||||
mut state: Local<GamepadEventState>,
|
||||
mut button_input: ResMut<Input<GamepadButton>>,
|
||||
mut axis: ResMut<Axis<GamepadAxis>>,
|
||||
mut button_axis: ResMut<Axis<GamepadButton>>,
|
||||
events: Res<Events<GamepadEvent>>,
|
||||
settings: Res<GamepadSetting>,
|
||||
) {
|
||||
button_input.update();
|
||||
for event in state.gamepad_event_reader.iter(&events) {
|
||||
let (gamepad, event) = (&event.0, &event.1);
|
||||
match event {
|
||||
GamepadEventType::Connected => {
|
||||
for button_type in ALL_BUTTON_TYPES.iter() {
|
||||
let gamepad_button = GamepadButton(*gamepad, *button_type);
|
||||
button_input.reset(gamepad_button);
|
||||
button_axis.set(gamepad_button, 0.0);
|
||||
}
|
||||
for axis_type in ALL_AXIS_TYPES.iter() {
|
||||
axis.set(GamepadAxis(*gamepad, *axis_type), 0.0);
|
||||
}
|
||||
}
|
||||
GamepadEventType::Disconnected => {
|
||||
for button_type in ALL_BUTTON_TYPES.iter() {
|
||||
let gamepad_button = GamepadButton(*gamepad, *button_type);
|
||||
button_input.reset(gamepad_button);
|
||||
button_axis.remove(gamepad_button);
|
||||
}
|
||||
for axis_type in ALL_AXIS_TYPES.iter() {
|
||||
axis.remove(GamepadAxis(*gamepad, *axis_type));
|
||||
}
|
||||
}
|
||||
GamepadEventType::AxisChanged(axis_type, value) => {
|
||||
let gamepad_axis = GamepadAxis(*gamepad, *axis_type);
|
||||
let value = settings
|
||||
.get_axis_setting(gamepad_axis)
|
||||
.filter(*value, axis.get(gamepad_axis));
|
||||
axis.set(gamepad_axis, value);
|
||||
}
|
||||
GamepadEventType::ButtonChanged(button_type, value) => {
|
||||
let gamepad_button = GamepadButton(*gamepad, *button_type);
|
||||
let filtered_value = settings
|
||||
.get_button_axis_setting(gamepad_button)
|
||||
.filter(*value, button_axis.get(gamepad_button));
|
||||
button_axis.set(gamepad_button, filtered_value);
|
||||
|
||||
let button_property = settings.get_button_setting(gamepad_button);
|
||||
if button_input.pressed(gamepad_button) {
|
||||
if button_property.is_released(*value) {
|
||||
button_input.release(gamepad_button);
|
||||
}
|
||||
} else if button_property.is_pressed(*value) {
|
||||
button_input.press(gamepad_button);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ALL_BUTTON_TYPES: [GamepadButtonType; 19] = [
|
||||
GamepadButtonType::South,
|
||||
GamepadButtonType::East,
|
||||
GamepadButtonType::North,
|
||||
GamepadButtonType::West,
|
||||
GamepadButtonType::C,
|
||||
GamepadButtonType::Z,
|
||||
GamepadButtonType::LeftTrigger,
|
||||
GamepadButtonType::LeftTrigger2,
|
||||
GamepadButtonType::RightTrigger,
|
||||
GamepadButtonType::RightTrigger2,
|
||||
GamepadButtonType::Select,
|
||||
GamepadButtonType::Start,
|
||||
GamepadButtonType::Mode,
|
||||
GamepadButtonType::LeftThumb,
|
||||
GamepadButtonType::RightThumb,
|
||||
GamepadButtonType::DPadUp,
|
||||
GamepadButtonType::DPadDown,
|
||||
GamepadButtonType::DPadLeft,
|
||||
GamepadButtonType::DPadRight,
|
||||
];
|
||||
|
||||
const ALL_AXIS_TYPES: [GamepadAxisType; 8] = [
|
||||
GamepadAxisType::LeftStickX,
|
||||
GamepadAxisType::LeftStickY,
|
||||
GamepadAxisType::LeftZ,
|
||||
GamepadAxisType::RightStickX,
|
||||
GamepadAxisType::RightStickY,
|
||||
GamepadAxisType::RightZ,
|
||||
GamepadAxisType::DPadX,
|
||||
GamepadAxisType::DPadY,
|
||||
];
|
||||
|
|
|
@ -27,7 +27,7 @@ use mouse::{mouse_button_input_system, MouseButton, MouseButtonInput, MouseMotio
|
|||
use touch::{touch_screen_input_system, TouchInput, Touches};
|
||||
|
||||
use bevy_ecs::IntoQuerySystem;
|
||||
use gamepad::{GamepadAxis, GamepadButton, GamepadEvent};
|
||||
use gamepad::{gamepad_event_system, GamepadAxis, GamepadButton, GamepadEvent, GamepadSetting};
|
||||
|
||||
/// Adds keyboard and mouse input to an App
|
||||
#[derive(Default)]
|
||||
|
@ -50,9 +50,15 @@ impl Plugin for InputPlugin {
|
|||
mouse_button_input_system.system(),
|
||||
)
|
||||
.add_event::<GamepadEvent>()
|
||||
.init_resource::<GamepadSetting>()
|
||||
.init_resource::<Input<GamepadButton>>()
|
||||
.init_resource::<Axis<GamepadAxis>>()
|
||||
.init_resource::<Axis<GamepadButton>>()
|
||||
.add_startup_system_to_stage(
|
||||
bevy_app::startup_stage::POST_STARTUP,
|
||||
gamepad_event_system.system(),
|
||||
)
|
||||
.add_system_to_stage(bevy_app::stage::EVENT_UPDATE, gamepad_event_system.system())
|
||||
.add_event::<TouchInput>()
|
||||
.init_resource::<Touches>()
|
||||
.add_system_to_stage(
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_input::gamepad::{Gamepad, GamepadButton, GamepadEvent, GamepadEventType};
|
||||
use std::collections::HashSet;
|
||||
use bevy_utils::HashSet;
|
||||
|
||||
fn main() {
|
||||
App::build()
|
||||
.add_default_plugins()
|
||||
.init_resource::<GamepadLobby>()
|
||||
.add_startup_system(connection_system.system())
|
||||
.add_system(connection_system.system())
|
||||
.add_system(button_system.system())
|
||||
.add_system(axis_system.system())
|
||||
.init_resource::<GamepadLobby>()
|
||||
.add_system(gamepad_system.system())
|
||||
.run();
|
||||
}
|
||||
|
||||
|
@ -24,85 +23,49 @@ fn connection_system(mut lobby: ResMut<GamepadLobby>, gamepad_event: Res<Events<
|
|||
match &event {
|
||||
GamepadEvent(gamepad, GamepadEventType::Connected) => {
|
||||
lobby.gamepads.insert(*gamepad);
|
||||
println!("Connected {:?}", gamepad);
|
||||
println!("{:?} Connected", gamepad);
|
||||
}
|
||||
GamepadEvent(gamepad, GamepadEventType::Disconnected) => {
|
||||
lobby.gamepads.remove(gamepad);
|
||||
println!("Disconnected {:?}", gamepad);
|
||||
println!("{:?} Disconnected", gamepad);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn button_system(
|
||||
fn gamepad_system(
|
||||
lobby: Res<GamepadLobby>,
|
||||
inputs: Res<Input<GamepadButton>>,
|
||||
button_inputs: Res<Input<GamepadButton>>,
|
||||
button_axes: Res<Axis<GamepadButton>>,
|
||||
axes: Res<Axis<GamepadAxis>>,
|
||||
) {
|
||||
let button_types = [
|
||||
GamepadButtonType::South,
|
||||
GamepadButtonType::East,
|
||||
GamepadButtonType::North,
|
||||
GamepadButtonType::West,
|
||||
GamepadButtonType::C,
|
||||
GamepadButtonType::Z,
|
||||
GamepadButtonType::LeftTrigger,
|
||||
GamepadButtonType::LeftTrigger2,
|
||||
GamepadButtonType::RightTrigger,
|
||||
GamepadButtonType::RightTrigger2,
|
||||
GamepadButtonType::Select,
|
||||
GamepadButtonType::Start,
|
||||
GamepadButtonType::Mode,
|
||||
GamepadButtonType::LeftThumb,
|
||||
GamepadButtonType::RightThumb,
|
||||
GamepadButtonType::DPadUp,
|
||||
GamepadButtonType::DPadDown,
|
||||
GamepadButtonType::DPadLeft,
|
||||
GamepadButtonType::DPadRight,
|
||||
];
|
||||
for gamepad in lobby.gamepads.iter() {
|
||||
for button_type in button_types.iter() {
|
||||
if inputs.just_pressed(GamepadButton(*gamepad, *button_type)) {
|
||||
println!("Pressed {:?}", GamepadButton(*gamepad, *button_type));
|
||||
} else if inputs.just_released(GamepadButton(*gamepad, *button_type)) {
|
||||
println!("Released {:?}", GamepadButton(*gamepad, *button_type));
|
||||
}
|
||||
if let Some(value) = button_axes.get(&GamepadButton(*gamepad, *button_type)) {
|
||||
if value_check(value) {
|
||||
println!(
|
||||
"Button as Axis {:?} is {}",
|
||||
GamepadButton(*gamepad, *button_type),
|
||||
value
|
||||
);
|
||||
}
|
||||
}
|
||||
let south_button = GamepadButton(*gamepad, GamepadButtonType::South);
|
||||
if button_inputs.just_pressed(south_button) {
|
||||
println!(
|
||||
"{:?} of {:?} is just pressed",
|
||||
GamepadButtonType::South,
|
||||
gamepad
|
||||
);
|
||||
} else if button_inputs.just_released(south_button) {
|
||||
println!(
|
||||
"{:?} of {:?} is just released",
|
||||
GamepadButtonType::South,
|
||||
gamepad
|
||||
);
|
||||
}
|
||||
|
||||
println!(
|
||||
"For {:?}: {:?} is {:.4}, {:?} is {:.4}",
|
||||
gamepad,
|
||||
GamepadButtonType::RightTrigger2,
|
||||
button_axes
|
||||
.get(GamepadButton(*gamepad, GamepadButtonType::RightTrigger2))
|
||||
.unwrap_or(0.0),
|
||||
GamepadAxisType::LeftStickX,
|
||||
axes.get(GamepadAxis(*gamepad, GamepadAxisType::LeftStickX))
|
||||
.unwrap_or(0.0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn axis_system(lobby: Res<GamepadLobby>, axes: Res<Axis<GamepadAxis>>) {
|
||||
let axis_types = [
|
||||
GamepadAxisType::LeftStickX,
|
||||
GamepadAxisType::LeftStickY,
|
||||
GamepadAxisType::LeftZ,
|
||||
GamepadAxisType::RightStickX,
|
||||
GamepadAxisType::RightStickY,
|
||||
GamepadAxisType::RightZ,
|
||||
GamepadAxisType::DPadX,
|
||||
GamepadAxisType::DPadY,
|
||||
];
|
||||
for gamepad in lobby.gamepads.iter() {
|
||||
for axis_type in axis_types.iter() {
|
||||
if let Some(value) = axes.get(&GamepadAxis(*gamepad, *axis_type)) {
|
||||
if value_check(value) {
|
||||
println!("Axis {:?} is {}", GamepadAxis(*gamepad, *axis_type), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn value_check(value: f32) -> bool {
|
||||
let value = value.abs();
|
||||
value > 0.1f32 && value < 0.9f32
|
||||
}
|
||||
|
|
34
examples/input/gamepad_input_event.rs
Normal file
34
examples/input/gamepad_input_event.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_input::gamepad::{GamepadEvent, GamepadEventType};
|
||||
|
||||
fn main() {
|
||||
App::build()
|
||||
.add_default_plugins()
|
||||
.add_startup_system(gamepad_raw_events.system())
|
||||
.add_system(gamepad_raw_events.system())
|
||||
.run();
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct State {
|
||||
gamepad_event_reader: EventReader<GamepadEvent>,
|
||||
}
|
||||
|
||||
fn gamepad_raw_events(mut state: Local<State>, gamepad_event: Res<Events<GamepadEvent>>) {
|
||||
for event in state.gamepad_event_reader.iter(&gamepad_event) {
|
||||
match &event {
|
||||
GamepadEvent(gamepad, GamepadEventType::Connected) => {
|
||||
println!("{:?} Connected", gamepad);
|
||||
}
|
||||
GamepadEvent(gamepad, GamepadEventType::Disconnected) => {
|
||||
println!("{:?} Disconnected", gamepad);
|
||||
}
|
||||
GamepadEvent(gamepad, GamepadEventType::ButtonChanged(button_type, value)) => {
|
||||
println!("{:?} of {:?} is changed to {}", button_type, gamepad, value);
|
||||
}
|
||||
GamepadEvent(gamepad, GamepadEventType::AxisChanged(axis_type, value)) => {
|
||||
println!("{:?} of {:?} is changed to {}", axis_type, gamepad, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue