Skip to content

Commit d8571c7

Browse files
author
Rene Damm
authored
NEW: Add controls for combined modifiers and method to look up keys by display name (#966).
1 parent cceab53 commit d8571c7

File tree

10 files changed

+249
-17
lines changed

10 files changed

+249
-17
lines changed

Assets/Tests/InputSystem/CoreTests_Devices.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,6 +2124,61 @@ public void Devices_CanLookUpKeyFromKeyboardUsingKeyCode()
21242124
Assert.That(keyboard[Key.A], Is.SameAs(keyboard.aKey));
21252125
}
21262126

2127+
[Test]
2128+
[Category("Devices")]
2129+
public void Devices_CanLookUpKeyFromKeyboardUsingDisplayName()
2130+
{
2131+
var keyboard = InputSystem.AddDevice<Keyboard>();
2132+
SetKeyInfo(Key.A, "q");
2133+
SetKeyInfo(Key.Q, "a");
2134+
2135+
Assert.That(keyboard.FindKeyOnCurrentKeyboardLayout("a"), Is.SameAs(keyboard.qKey));
2136+
Assert.That(keyboard.FindKeyOnCurrentKeyboardLayout("q"), Is.SameAs(keyboard.aKey));
2137+
}
2138+
2139+
[Test]
2140+
[Category("Devices")]
2141+
public void Devices_KeyboardsHaveSyntheticCombinedModifierKeys()
2142+
{
2143+
var keyboard = InputSystem.AddDevice<Keyboard>();
2144+
2145+
Assert.That(keyboard.shiftKey.synthetic, Is.True);
2146+
Assert.That(keyboard.ctrlKey.synthetic, Is.True);
2147+
Assert.That(keyboard.altKey.synthetic, Is.True);
2148+
2149+
Assert.That(keyboard.shiftKey.isPressed, Is.False);
2150+
Assert.That(keyboard.ctrlKey.isPressed, Is.False);
2151+
Assert.That(keyboard.altKey.isPressed, Is.False);
2152+
2153+
Press(keyboard.leftAltKey);
2154+
Press(keyboard.leftShiftKey);
2155+
Press(keyboard.leftCtrlKey);
2156+
2157+
Assert.That(keyboard.shiftKey.isPressed, Is.True);
2158+
Assert.That(keyboard.ctrlKey.isPressed, Is.True);
2159+
Assert.That(keyboard.altKey.isPressed, Is.True);
2160+
2161+
Assert.That(keyboard.shiftKey.ReadValue(), Is.EqualTo(1).Within(0.00001));
2162+
Assert.That(keyboard.ctrlKey.ReadValue(), Is.EqualTo(1).Within(0.00001));
2163+
Assert.That(keyboard.altKey.ReadValue(), Is.EqualTo(1).Within(0.00001));
2164+
2165+
Release(keyboard.leftAltKey);
2166+
Release(keyboard.leftShiftKey);
2167+
Release(keyboard.leftCtrlKey);
2168+
2169+
Assert.That(keyboard.shiftKey.isPressed, Is.False);
2170+
Assert.That(keyboard.ctrlKey.isPressed, Is.False);
2171+
Assert.That(keyboard.altKey.isPressed, Is.False);
2172+
2173+
Press(keyboard.rightAltKey);
2174+
Press(keyboard.rightShiftKey);
2175+
Press(keyboard.rightCtrlKey);
2176+
2177+
Assert.That(keyboard.shiftKey.isPressed, Is.True);
2178+
Assert.That(keyboard.ctrlKey.isPressed, Is.True);
2179+
Assert.That(keyboard.altKey.isPressed, Is.True);
2180+
}
2181+
21272182
[Test]
21282183
[Category("Devices")]
21292184
public void Devices_CanPerformHorizontalAndVerticalScrollWithMouse()

Packages/com.unity.inputsystem/CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,23 @@ however, it has to be formatted properly to pass verification tests.
99

1010
## [1.0.0-preview.4] - 2019-12-12
1111

12+
### Added
13+
14+
- `Keyboard` now has a `FindKeyOnCurrentKeyboardLayout` method to look up key controls by their display names.
15+
- Keyboards now have synthetic controls that combine left and right variants of modifier keys.
16+
* This means that you can bind to just "shift" now, for example, instead of having to bind to both "left shift" and "right shift".
17+
```CSharp
18+
new InputAction(binding: "<Keyboard>/shift");
19+
```
20+
* The controls are also available as properties on `Keyboard`.
21+
```CSharp
22+
if (Keyboard.current.shiftKey.isPressed) /* ... */;
23+
24+
// Is equivalent to:
25+
if (Keyboard.current.leftShiftKey.isPressed ||
26+
Keyboard.current.rightShiftKey.isPressed) /* ... */;
27+
```
28+
1229
### Changed
1330

1431
- `InputControlExtensions.GetStatePtrFromStateEvent` no longer throws `InvalidOperationException` when the state format for the event does not match that of the device. It simply returns `null` instead (same as when control is found in the event's state).

Packages/com.unity.inputsystem/Documentation~/Keyboard.md

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ You can look up keys based on the character they produce using [Control paths](C
1111
>__Note__
1212
>* Keyboards usually have hardware limitations on both the number of simultaneous keypresses they report, and the combinations of keys they support. This means that certain simultaneous keypresses may not register correctly. For example, a given keyboard may report a simultaneous press of the "QWERT" keys correctly but may not report "QWERA" correctly.
1313
>* At the moment, the new Input System doesn't support on-screen keyboards. For now, please Unity's existing API in `UnityEngine.TouchScreenKeyboard`.
14+
>* At the moment, Unity platform backends generally do not support distinguishing between multiple keyboards. While the Input System supports having arbitray many [`Keyboard`](../api/UnityEngine.InputSystem.Keyboard.html) devices at any point, platform backends will generally only report a single keyboard and route input from all attached keyboards to the one keyboard device.
1415
1516
## Controls
1617

@@ -23,21 +24,21 @@ The [scripting API reference for the `Keyboard` class](../api/UnityEngine.InputS
2324

2425
Two special Controls, [`anyKey`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_anyKey) and [`imeSelected`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_imeSelected), don't directly map to individual keys. [`anyKey`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_anyKey) is a [synthetic](Controls.md#synthetic-controls) button Control which reports whether any key on the keyboard is pressed, and [`imeSelected`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_imeSelected) reports whether or not [IME](#ime) text processing is enabled.
2526

27+
In addition, [`Keyboard`](../api/UnityEngine.InputSystem.Keyboard.html)'s indexer and the [`Key`](../api/UnityEngine.InputSystem.Key.html) has three [synthetic](Controls.md#synthetic-controls) controls that represent combinations of modifier keys:
28+
29+
|Control|Description|
30+
|-------|-----------|
31+
|[`shiftKey`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_shiftKey)|A button that is pressed if [`leftShiftKey`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_leftShiftKey) and/or [`rightShiftKey`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_rightShiftKey) is pressed.|
32+
|[`ctrlKey`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_ctrlKey)|A button that is pressed if [`leftCtrlKey`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_leftCtrlKey) and/or [`rightCtrlKey`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_rightCtrlKey) is pressed.|
33+
|[`altKey`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_altKey)|A button that is pressed if [`leftAltKey`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_leftAltKey) and/or [`rightAltKey`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_rightAltKey) is pressed.|
34+
2635
## Text input
2736

2837
As a best practice, you shouldn't manually translate text input from key presses by trying to string together the characters corresponding to the keys. Instead, to listen to text input, hook into [`Keyboard.onTextInput`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_onTextInput). This delivers character-by-character input as reported by the platform, including input from on-screen keyboards.
2938

3039
Note that the text input API doesn't allocate GC memory because it doesn't deliver fully composed strings.
3140

32-
## Keyboard layouts
33-
34-
You can query the name of the current keyboard layout using [`Keyboard.keyboardLayout`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_keyboardLayout). Layout names are platform-specific.
35-
36-
There is no support for setting keyboard layouts from your application.
37-
38-
To monitor keyboard layout changes, hook into [`InputSystem.onDeviceChange`](../api/UnityEngine.InputSystem.InputSystem.html#UnityEngine_InputSystem_InputSystem_onDeviceChange) and check for [`InputDeviceChange.ConfigurationChanged`](../api/UnityEngine.InputSystem.InputDeviceChange.html) on a [`Keyboard`](../api/UnityEngine.InputSystem.Keyboard.html) device.
39-
40-
## IME
41+
### IME
4142

4243
Some writing systems, such as some East-Asian scripts, are too complex to represent all characters as individual keys on a keyboard. For these layouts, operating systems implement IMEs (Input Method Editors) to allow composing input strings by other methods, for instance by typing several keys to produce a single character. Unity's UI frameworks for text input support IME without any additional configuration. If you want to build your own UI for text input, the [`Keyboard`](../api/UnityEngine.InputSystem.Keyboard.html) class allows you to work with input from IMEs using the following APIs:
4344

@@ -48,3 +49,18 @@ Some writing systems, such as some East-Asian scripts, are too complex to repres
4849
* [`SetIMECursorPosition()`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_SetIMECursorPosition_Vector2_). IMEs might open system windows that let users interactively edit the text they want to input. Typically, these open next to the text editing UI. You can use the [`SetIMECursorPosition()`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_SetIMECursorPosition_Vector2_) method to tell the OS where that is.
4950

5051
* [`onIMECompositionChange`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_onIMECompositionChange) is an event you can subscribe to in order to receive all updates to the IME composition string. The composition string is the text input the user is currently editing using an IME. Typically, any UI dealing with text input displays this text (with some visual indication of it being actively edited, usually an underline) at the current text input cursor position.
52+
53+
## Keyboard layouts
54+
55+
You can query the name of the current keyboard layout using [`Keyboard.keyboardLayout`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_keyboardLayout). Layout names are platform-specific.
56+
57+
There is no support for setting keyboard layouts from your application.
58+
59+
To monitor keyboard layout changes, hook into [`InputSystem.onDeviceChange`](../api/UnityEngine.InputSystem.InputSystem.html#UnityEngine_InputSystem_InputSystem_onDeviceChange) and check for [`InputDeviceChange.ConfigurationChanged`](../api/UnityEngine.InputSystem.InputDeviceChange.html) on a [`Keyboard`](../api/UnityEngine.InputSystem.Keyboard.html) device.
60+
61+
To find the key control that corresponds to a specific display character sequence, call [`Keyboard.FindKeyOnCurrentKeyboardLayout`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_FindKeyOnCurrentKeyboardLayout_).
62+
63+
```CSharp
64+
// Find key that generates a 'q' character according to the current keyboard layout.
65+
Keyboard.current.FindKeyOnCurrentKeyboardLayout("q");
66+
```

Packages/com.unity.inputsystem/Documentation~/UISupport.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
You can use the Input System package to control any in-game UI created with the [Unity UI package](https://docs.unity3d.com/Manual/UISystem.html). The integration between the Input System and the UI system is handled by the [`InputSystemUIInputModule`](../api/UnityEngine.InputSystem.UI.InputSystemUIInputModule.html) component.
44

5+
>NOTE: At the moment, there is no support for IMGUI or for UIElements. This is being worked on.
6+
57
## `InputSystemUIInputModule` Component
68

79
The [`InputSystemUIInputModule`](../api/UnityEngine.InputSystem.UI.InputSystemUIInputModule.html) component acts as a drop-in replacement for the [`StandaloneInputModule`](https://docs.unity3d.com/Manual/script-StandaloneInputModule.html) component that the Unity UI package. [`InputSystemUIInputModule`](../api/UnityEngine.InputSystem.UI.InputSystemUIInputModule.html) provides the same kind of functionality as [`StandaloneInputModule`](https://docs.unity3d.com/Manual/script-StandaloneInputModule.html), but it uses the Input System instead of the legacy Input Manager to drive UI input.

Packages/com.unity.inputsystem/InputSystem/Controls/KeyControl.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using UnityEngine.InputSystem.LowLevel;
2+
using UnityEngine.Scripting;
23

34
namespace UnityEngine.InputSystem.Controls
45
{
@@ -14,7 +15,7 @@ namespace UnityEngine.InputSystem.Controls
1415
/// layout specific and does not need to be key-by-key. For general text input, see <see cref="Keyboard.onTextInput"/>.
1516
/// To find the text displayed on a key, use <see cref="KeyControl.displayName"/>.
1617
/// </remarks>
17-
[Scripting.Preserve]
18+
[Preserve]
1819
public class KeyControl : ButtonControl
1920
{
2021
/// <summary>

Packages/com.unity.inputsystem/InputSystem/Devices/Commands/QueryKeyNameCommand.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace UnityEngine.InputSystem.LowLevel
1010
[StructLayout(LayoutKind.Explicit, Size = kSize)]
1111
public unsafe struct QueryKeyNameCommand : IInputDeviceCommandInfo
1212
{
13-
public static FourCC Type { get { return new FourCC('K', 'Y', 'C', 'F'); } }
13+
public static FourCC Type => new FourCC('K', 'Y', 'C', 'F');
1414

1515
internal const int kMaxNameLength = 256;
1616
internal const int kSize = InputDeviceCommand.kBaseCommandSize + kMaxNameLength + 4;
@@ -32,10 +32,7 @@ public string ReadKeyName()
3232
}
3333
}
3434

35-
public FourCC typeStatic
36-
{
37-
get { return Type; }
38-
}
35+
public FourCC typeStatic => Type;
3936

4037
public static QueryKeyNameCommand Create(Key key)
4138
{

0 commit comments

Comments
 (0)