Skip to content

Commit 1152111

Browse files
committed
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 #2052 and #862 Co-authored-by: Bleb1k <[email protected]>
1 parent c37939d commit 1152111

File tree

2 files changed

+34
-15
lines changed

2 files changed

+34
-15
lines changed

crates/bevy_input/src/keyboard.rs

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,29 @@ pub struct KeyboardInput {
2424
///
2525
/// ## Differences
2626
///
27-
/// The main difference between the [`KeyboardInput`] event and the [`Input<KeyCode>`] resource is that
28-
/// the latter has convenient functions like [`Input::pressed`], [`Input::just_pressed`] and [`Input::just_released`].
27+
/// The main difference between the [`KeyboardInput`] event and the [`Input<KeyCode>`] or [`Input<ScanCode>`] resources is that
28+
/// the latter have convenient functions such as [`Input::pressed`], [`Input::just_pressed`] and [`Input::just_released`].
2929
pub fn keyboard_input_system(
30-
mut keyboard_input: ResMut<Input<KeyCode>>,
30+
mut scan_input: ResMut<Input<ScanCode>>,
31+
mut key_input: ResMut<Input<KeyCode>>,
3132
mut keyboard_input_events: EventReader<KeyboardInput>,
3233
) {
33-
keyboard_input.clear();
34+
scan_input.clear();
35+
key_input.clear();
3436
for event in keyboard_input_events.iter() {
35-
if let KeyboardInput {
36-
key_code: Some(key_code),
37-
state,
38-
..
39-
} = event
40-
{
37+
let KeyboardInput {
38+
scan_code, state, ..
39+
} = event;
40+
if let Some(key_code) = event.key_code {
4141
match state {
42-
ButtonState::Pressed => keyboard_input.press(*key_code),
43-
ButtonState::Released => keyboard_input.release(*key_code),
42+
ButtonState::Pressed => key_input.press(key_code),
43+
ButtonState::Released => key_input.release(key_code),
4444
}
4545
}
46+
match state {
47+
ButtonState::Pressed => scan_input.press(ScanCode(*scan_code)),
48+
ButtonState::Released => scan_input.release(ScanCode(*scan_code)),
49+
}
4650
}
4751
}
4852

@@ -51,7 +55,7 @@ pub fn keyboard_input_system(
5155
/// ## Usage
5256
///
5357
/// It is used as the generic `T` value of an [`Input`](crate::Input) to create a `Res<Input<KeyCode>>`.
54-
/// The resource stores the data of the buttons of a keyboard and can be accessed inside of a system.
58+
/// The resource values are mapped to the current layout of the keyboard and correlate to an [`ScanCode`](ScanCode).
5559
///
5660
/// ## Updating
5761
///
@@ -407,3 +411,17 @@ pub enum KeyCode {
407411
/// The `Cut` key.
408412
Cut,
409413
}
414+
415+
/// The scan code of a [`KeyboardInput`](crate::keyboard::KeyboardInput).
416+
///
417+
/// ## Usage
418+
///
419+
/// It is used as the generic <T> value of an [`Input`](crate::Input) to create a `Res<Input<ScanCode>>`.
420+
/// The resource values are mapped to the physical location of a key on the keyboard and correlate to an [`KeyCode`](KeyCode)
421+
///
422+
/// ## Updating
423+
///
424+
/// The resource is updated inside of the [`keyboard_input_system`](crate::keyboard::keyboard_input_system).
425+
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
426+
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
427+
pub struct ScanCode(pub u32);

crates/bevy_input/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ pub mod prelude {
1616
Gamepad, GamepadAxis, GamepadAxisType, GamepadButton, GamepadButtonType, GamepadEvent,
1717
GamepadEventType, Gamepads,
1818
},
19-
keyboard::KeyCode,
19+
keyboard::{KeyCode, ScanCode},
2020
mouse::MouseButton,
2121
touch::{TouchInput, Touches},
2222
Axis, Input,
2323
};
2424
}
2525

2626
use bevy_app::prelude::*;
27-
use keyboard::{keyboard_input_system, KeyCode, KeyboardInput};
27+
use keyboard::{keyboard_input_system, KeyCode, KeyboardInput, ScanCode};
2828
use mouse::{mouse_button_input_system, MouseButton, MouseButtonInput, MouseMotion, MouseWheel};
2929
use prelude::Gamepads;
3030
use touch::{touch_screen_input_system, TouchInput, Touches};
@@ -47,6 +47,7 @@ impl Plugin for InputPlugin {
4747
// keyboard
4848
.add_event::<KeyboardInput>()
4949
.init_resource::<Input<KeyCode>>()
50+
.init_resource::<Input<ScanCode>>()
5051
.add_system_to_stage(
5152
CoreStage::PreUpdate,
5253
keyboard_input_system.label(InputSystem),

0 commit comments

Comments
 (0)