diff --git a/crates/bevy_input/src/keyboard.rs b/crates/bevy_input/src/keyboard.rs index 40eec4b35a66b..98abd1bdd025b 100644 --- a/crates/bevy_input/src/keyboard.rs +++ b/crates/bevy_input/src/keyboard.rs @@ -24,25 +24,29 @@ pub struct KeyboardInput { /// /// ## Differences /// -/// The main difference between the [`KeyboardInput`] event and the [`Input`] resource is that -/// the latter has convenient functions like [`Input::pressed`], [`Input::just_pressed`] and [`Input::just_released`]. +/// The main difference between the [`KeyboardInput`] event and the [`Input`] or [`Input`] resources is that +/// the latter have convenient functions such as [`Input::pressed`], [`Input::just_pressed`] and [`Input::just_released`]. pub fn keyboard_input_system( - mut keyboard_input: ResMut>, + mut scan_input: ResMut>, + mut key_input: ResMut>, mut keyboard_input_events: EventReader, ) { - keyboard_input.clear(); + scan_input.clear(); + key_input.clear(); for event in keyboard_input_events.iter() { - if let KeyboardInput { - key_code: Some(key_code), - state, - .. - } = event - { + let KeyboardInput { + scan_code, state, .. + } = event; + if let Some(key_code) = event.key_code { match state { - ButtonState::Pressed => keyboard_input.press(*key_code), - ButtonState::Released => keyboard_input.release(*key_code), + ButtonState::Pressed => key_input.press(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 /// /// It is used as the generic `T` value of an [`Input`](crate::Input) to create a `Res>`. -/// 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 /// @@ -407,3 +411,17 @@ pub enum KeyCode { /// The `Cut` key. Cut, } + +/// The scan code of a [`KeyboardInput`](crate::keyboard::KeyboardInput). +/// +/// ## Usage +/// +/// It is used as the generic value of an [`Input`](crate::Input) to create a `Res>`. +/// 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); diff --git a/crates/bevy_input/src/lib.rs b/crates/bevy_input/src/lib.rs index 625b8ed746a61..dca26c3edaaa2 100644 --- a/crates/bevy_input/src/lib.rs +++ b/crates/bevy_input/src/lib.rs @@ -16,7 +16,7 @@ pub mod prelude { Gamepad, GamepadAxis, GamepadAxisType, GamepadButton, GamepadButtonType, GamepadEvent, GamepadEventType, Gamepads, }, - keyboard::KeyCode, + keyboard::{KeyCode, ScanCode}, mouse::MouseButton, touch::{TouchInput, Touches}, Axis, Input, @@ -24,7 +24,7 @@ pub mod 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 prelude::Gamepads; use touch::{touch_screen_input_system, TouchInput, Touches}; @@ -47,6 +47,7 @@ impl Plugin for InputPlugin { // keyboard .add_event::() .init_resource::>() + .init_resource::>() .add_system_to_stage( CoreStage::PreUpdate, keyboard_input_system.label(InputSystem),