mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Add GamepadButtonInput
event (#9008)
# Objective Add `GamepadButtonInput` event Resolves #8988 ## Solution - Add `GamepadButtonInput` type - Emit `GamepadButtonInput` events whenever `Input<GamepadButton>` is written to - Update example --------- Co-authored-by: François <mockersf@gmail.com>
This commit is contained in:
parent
a024a1f3b9
commit
140d9612e6
3 changed files with 59 additions and 14 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::{Axis, Input};
|
||||
use crate::{Axis, ButtonState, Input};
|
||||
use bevy_ecs::event::{Event, EventReader, EventWriter};
|
||||
use bevy_ecs::{
|
||||
change_detection::DetectChangesMut,
|
||||
|
@ -265,6 +265,21 @@ impl GamepadButton {
|
|||
}
|
||||
}
|
||||
|
||||
/// A gamepad button input event.
|
||||
#[derive(Event, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
|
||||
#[reflect(Debug, PartialEq)]
|
||||
#[cfg_attr(
|
||||
feature = "serialize",
|
||||
derive(serde::Serialize, serde::Deserialize),
|
||||
reflect(Serialize, Deserialize)
|
||||
)]
|
||||
pub struct GamepadButtonInput {
|
||||
/// The gamepad button assigned to the event.
|
||||
pub button: GamepadButton,
|
||||
/// The pressed state of the button.
|
||||
pub state: ButtonState,
|
||||
}
|
||||
|
||||
/// A type of a [`GamepadAxis`].
|
||||
///
|
||||
/// ## Usage
|
||||
|
@ -1159,20 +1174,35 @@ pub fn gamepad_axis_event_system(
|
|||
|
||||
/// Uses [`GamepadButtonChangedEvent`]s to update the relevant [`Input`] and [`Axis`] values.
|
||||
pub fn gamepad_button_event_system(
|
||||
mut button_events: EventReader<GamepadButtonChangedEvent>,
|
||||
mut button_changed_events: EventReader<GamepadButtonChangedEvent>,
|
||||
mut button_input: ResMut<Input<GamepadButton>>,
|
||||
mut button_input_events: EventWriter<GamepadButtonInput>,
|
||||
settings: Res<GamepadSettings>,
|
||||
) {
|
||||
for button_event in button_events.iter() {
|
||||
for button_event in button_changed_events.iter() {
|
||||
let button = GamepadButton::new(button_event.gamepad, button_event.button_type);
|
||||
let value = button_event.value;
|
||||
let button_property = settings.get_button_settings(button);
|
||||
|
||||
if button_property.is_released(value) {
|
||||
// We don't have to check if the button was previously pressed
|
||||
// Check if button was previously pressed
|
||||
if button_input.pressed(button) {
|
||||
button_input_events.send(GamepadButtonInput {
|
||||
button,
|
||||
state: ButtonState::Released,
|
||||
});
|
||||
}
|
||||
// We don't have to check if the button was previously pressed here
|
||||
// because that check is performed within Input<T>::release()
|
||||
button_input.release(button);
|
||||
} else if button_property.is_pressed(value) {
|
||||
// Check if button was previously not pressed
|
||||
if !button_input.pressed(button) {
|
||||
button_input_events.send(GamepadButtonInput {
|
||||
button,
|
||||
state: ButtonState::Pressed,
|
||||
});
|
||||
}
|
||||
button_input.press(button);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ use gamepad::{
|
|||
gamepad_axis_event_system, gamepad_button_event_system, gamepad_connection_system,
|
||||
gamepad_event_system, AxisSettings, ButtonAxisSettings, ButtonSettings, Gamepad, GamepadAxis,
|
||||
GamepadAxisChangedEvent, GamepadAxisType, GamepadButton, GamepadButtonChangedEvent,
|
||||
GamepadButtonType, GamepadConnection, GamepadConnectionEvent, GamepadEvent,
|
||||
GamepadButtonInput, GamepadButtonType, GamepadConnection, GamepadConnectionEvent, GamepadEvent,
|
||||
GamepadRumbleRequest, GamepadSettings, Gamepads,
|
||||
};
|
||||
|
||||
|
@ -75,6 +75,7 @@ impl Plugin for InputPlugin {
|
|||
// gamepad
|
||||
.add_event::<GamepadConnectionEvent>()
|
||||
.add_event::<GamepadButtonChangedEvent>()
|
||||
.add_event::<GamepadButtonInput>()
|
||||
.add_event::<GamepadAxisChangedEvent>()
|
||||
.add_event::<GamepadEvent>()
|
||||
.add_event::<GamepadRumbleRequest>()
|
||||
|
@ -131,6 +132,7 @@ impl Plugin for InputPlugin {
|
|||
.register_type::<GamepadConnection>()
|
||||
.register_type::<GamepadButtonType>()
|
||||
.register_type::<GamepadButton>()
|
||||
.register_type::<GamepadButtonInput>()
|
||||
.register_type::<GamepadAxisType>()
|
||||
.register_type::<GamepadAxis>()
|
||||
.register_type::<GamepadSettings>()
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
use bevy::{
|
||||
input::gamepad::{
|
||||
GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadConnectionEvent, GamepadEvent,
|
||||
GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadButtonInput,
|
||||
GamepadConnectionEvent, GamepadEvent,
|
||||
},
|
||||
prelude::*,
|
||||
};
|
||||
|
@ -15,25 +16,37 @@ fn main() {
|
|||
}
|
||||
|
||||
fn gamepad_events(
|
||||
mut gamepad_connection_events: EventReader<GamepadConnectionEvent>,
|
||||
mut gamepad_axis_events: EventReader<GamepadAxisChangedEvent>,
|
||||
mut gamepad_button_events: EventReader<GamepadButtonChangedEvent>,
|
||||
mut connection_events: EventReader<GamepadConnectionEvent>,
|
||||
mut axis_changed_events: EventReader<GamepadAxisChangedEvent>,
|
||||
// Handles the continuous measure of how far a button has been pressed down, as measured
|
||||
// by `Axis<GamepadButton>`. Whenever that value changes, this event is emitted.
|
||||
mut button_changed_events: EventReader<GamepadButtonChangedEvent>,
|
||||
// Handles the boolean measure of whether a button is considered pressed or unpressed, as
|
||||
// defined by the thresholds in `GamepadSettings::button_settings` and measured by
|
||||
// `Input<GamepadButton>`. When the threshold is crossed and the button state changes,
|
||||
// this event is emmitted.
|
||||
mut button_input_events: EventReader<GamepadButtonInput>,
|
||||
) {
|
||||
for connection_event in gamepad_connection_events.iter() {
|
||||
for connection_event in connection_events.iter() {
|
||||
info!("{:?}", connection_event);
|
||||
}
|
||||
for axis_event in gamepad_axis_events.iter() {
|
||||
for axis_changed_event in axis_changed_events.iter() {
|
||||
info!(
|
||||
"{:?} of {:?} is changed to {}",
|
||||
axis_event.axis_type, axis_event.gamepad, axis_event.value
|
||||
axis_changed_event.axis_type, axis_changed_event.gamepad, axis_changed_event.value
|
||||
);
|
||||
}
|
||||
for button_event in gamepad_button_events.iter() {
|
||||
for button_changed_event in button_changed_events.iter() {
|
||||
info!(
|
||||
"{:?} of {:?} is changed to {}",
|
||||
button_event.button_type, button_event.gamepad, button_event.value
|
||||
button_changed_event.button_type,
|
||||
button_changed_event.gamepad,
|
||||
button_changed_event.value
|
||||
);
|
||||
}
|
||||
for button_input_event in button_input_events.iter() {
|
||||
info!("{:?}", button_input_event);
|
||||
}
|
||||
}
|
||||
|
||||
// If you require in-frame relative event ordering, you can also read the `Gamepad` event
|
||||
|
|
Loading…
Reference in a new issue