Added keyboard scan input event (#5495)
# Objective - I wanted to have controls independent from keyboard layout and found that bevy doesn't have a proper implementation for that ## Solution - I created a `ScanCode` enum with two hundreds scan codes and updated `keyboard_input_system` to include and update `ResMut<Input<ScanCode>>` - closes both https://github.com/bevyengine/bevy/issues/2052 and https://github.com/bevyengine/bevy/issues/862 Co-authored-by: Bleb1k <91003089+Bleb1k@users.noreply.github.com>
This commit is contained in:
parent
c37939d322
commit
115211161b
@ -24,25 +24,29 @@ pub struct KeyboardInput {
|
|||||||
///
|
///
|
||||||
/// ## Differences
|
/// ## Differences
|
||||||
///
|
///
|
||||||
/// The main difference between the [`KeyboardInput`] event and the [`Input<KeyCode>`] resource is that
|
/// The main difference between the [`KeyboardInput`] event and the [`Input<KeyCode>`] or [`Input<ScanCode>`] resources is that
|
||||||
/// the latter has convenient functions like [`Input::pressed`], [`Input::just_pressed`] and [`Input::just_released`].
|
/// the latter have convenient functions such as [`Input::pressed`], [`Input::just_pressed`] and [`Input::just_released`].
|
||||||
pub fn keyboard_input_system(
|
pub fn keyboard_input_system(
|
||||||
mut keyboard_input: ResMut<Input<KeyCode>>,
|
mut scan_input: ResMut<Input<ScanCode>>,
|
||||||
|
mut key_input: ResMut<Input<KeyCode>>,
|
||||||
mut keyboard_input_events: EventReader<KeyboardInput>,
|
mut keyboard_input_events: EventReader<KeyboardInput>,
|
||||||
) {
|
) {
|
||||||
keyboard_input.clear();
|
scan_input.clear();
|
||||||
|
key_input.clear();
|
||||||
for event in keyboard_input_events.iter() {
|
for event in keyboard_input_events.iter() {
|
||||||
if let KeyboardInput {
|
let KeyboardInput {
|
||||||
key_code: Some(key_code),
|
scan_code, state, ..
|
||||||
state,
|
} = event;
|
||||||
..
|
if let Some(key_code) = event.key_code {
|
||||||
} = event
|
|
||||||
{
|
|
||||||
match state {
|
match state {
|
||||||
ButtonState::Pressed => keyboard_input.press(*key_code),
|
ButtonState::Pressed => key_input.press(key_code),
|
||||||
ButtonState::Released => keyboard_input.release(*key_code),
|
ButtonState::Released => key_input.release(key_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
match state {
|
||||||
|
ButtonState::Pressed => scan_input.press(ScanCode(*scan_code)),
|
||||||
|
ButtonState::Released => scan_input.release(ScanCode(*scan_code)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +55,7 @@ pub fn keyboard_input_system(
|
|||||||
/// ## Usage
|
/// ## Usage
|
||||||
///
|
///
|
||||||
/// It is used as the generic `T` value of an [`Input`](crate::Input) to create a `Res<Input<KeyCode>>`.
|
/// It is used as the generic `T` value of an [`Input`](crate::Input) to create a `Res<Input<KeyCode>>`.
|
||||||
/// The resource stores the data of the buttons of a keyboard and can be accessed inside of a system.
|
/// The resource values are mapped to the current layout of the keyboard and correlate to an [`ScanCode`](ScanCode).
|
||||||
///
|
///
|
||||||
/// ## Updating
|
/// ## Updating
|
||||||
///
|
///
|
||||||
@ -407,3 +411,17 @@ pub enum KeyCode {
|
|||||||
/// The `Cut` key.
|
/// The `Cut` key.
|
||||||
Cut,
|
Cut,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The scan code of a [`KeyboardInput`](crate::keyboard::KeyboardInput).
|
||||||
|
///
|
||||||
|
/// ## Usage
|
||||||
|
///
|
||||||
|
/// It is used as the generic <T> value of an [`Input`](crate::Input) to create a `Res<Input<ScanCode>>`.
|
||||||
|
/// The resource values are mapped to the physical location of a key on the keyboard and correlate to an [`KeyCode`](KeyCode)
|
||||||
|
///
|
||||||
|
/// ## Updating
|
||||||
|
///
|
||||||
|
/// The resource is updated inside of the [`keyboard_input_system`](crate::keyboard::keyboard_input_system).
|
||||||
|
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
|
||||||
|
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||||
|
pub struct ScanCode(pub u32);
|
||||||
|
@ -16,7 +16,7 @@ pub mod prelude {
|
|||||||
Gamepad, GamepadAxis, GamepadAxisType, GamepadButton, GamepadButtonType, GamepadEvent,
|
Gamepad, GamepadAxis, GamepadAxisType, GamepadButton, GamepadButtonType, GamepadEvent,
|
||||||
GamepadEventType, Gamepads,
|
GamepadEventType, Gamepads,
|
||||||
},
|
},
|
||||||
keyboard::KeyCode,
|
keyboard::{KeyCode, ScanCode},
|
||||||
mouse::MouseButton,
|
mouse::MouseButton,
|
||||||
touch::{TouchInput, Touches},
|
touch::{TouchInput, Touches},
|
||||||
Axis, Input,
|
Axis, Input,
|
||||||
@ -24,7 +24,7 @@ pub mod prelude {
|
|||||||
}
|
}
|
||||||
|
|
||||||
use bevy_app::prelude::*;
|
use bevy_app::prelude::*;
|
||||||
use keyboard::{keyboard_input_system, KeyCode, KeyboardInput};
|
use keyboard::{keyboard_input_system, KeyCode, KeyboardInput, ScanCode};
|
||||||
use mouse::{mouse_button_input_system, MouseButton, MouseButtonInput, MouseMotion, MouseWheel};
|
use mouse::{mouse_button_input_system, MouseButton, MouseButtonInput, MouseMotion, MouseWheel};
|
||||||
use prelude::Gamepads;
|
use prelude::Gamepads;
|
||||||
use touch::{touch_screen_input_system, TouchInput, Touches};
|
use touch::{touch_screen_input_system, TouchInput, Touches};
|
||||||
@ -47,6 +47,7 @@ impl Plugin for InputPlugin {
|
|||||||
// keyboard
|
// keyboard
|
||||||
.add_event::<KeyboardInput>()
|
.add_event::<KeyboardInput>()
|
||||||
.init_resource::<Input<KeyCode>>()
|
.init_resource::<Input<KeyCode>>()
|
||||||
|
.init_resource::<Input<ScanCode>>()
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PreUpdate,
|
CoreStage::PreUpdate,
|
||||||
keyboard_input_system.label(InputSystem),
|
keyboard_input_system.label(InputSystem),
|
||||||
|
Loading…
Reference in New Issue
Block a user