From 2186a85df5e5c7bb281b7682c4c69903fd19d728 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Thu, 16 May 2024 18:22:24 +0100 Subject: [PATCH 01/18] migration page improvements WIP --- .../Documentation~/Gamepad.md | 54 +++++++-- .../Documentation~/Migration.md | 112 ++---------------- .../Documentation~/Sensors.md | 48 ++++++-- .../InputSystem/Controls/ButtonControl.cs | 21 +++- .../InputSystem/Devices/Keyboard.cs | 11 ++ 5 files changed, 118 insertions(+), 128 deletions(-) diff --git a/Packages/com.unity.inputsystem/Documentation~/Gamepad.md b/Packages/com.unity.inputsystem/Documentation~/Gamepad.md index 163849e918..b64757a79a 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Gamepad.md +++ b/Packages/com.unity.inputsystem/Documentation~/Gamepad.md @@ -3,16 +3,16 @@ uid: input-system-gamepad --- # Gamepad Support -- [Gamepad Support](#gamepad-support) - - [Controls](#controls) - - [Deadzones](#deadzones) - - [Polling](#polling) - - [Rumble](#rumble) - - [Pausing, resuming, and stopping haptics](#pausing-resuming-and-stopping-haptics) - - [PlayStation controllers](#playstation-controllers) - - [Xbox controllers](#xbox-controllers) - - [Switch controllers](#switch-controllers) - - [Cursor Control](#cursor-control) +- [Controls](#controls) + - [Deadzones](#deadzones) +- [Polling](#polling) +- [Rumble](#rumble) + - [Pausing, resuming, and stopping haptics](#pausing-resuming-and-stopping-haptics) +- [PlayStation controllers](#playstation-controllers) +- [Xbox controllers](#xbox-controllers) +- [Switch controllers](#switch-controllers) +- [Cursor Control](#cursor-control) +- [Discover all connected devices](#discover-all-connected-devices) A [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) is narrowly defined as a Device with two thumbsticks, a D-pad, and four face buttons. Additionally, gamepads usually have two shoulder and two trigger buttons. Most gamepads also have two buttons in the middle. @@ -198,3 +198,37 @@ The Input System support Switch Pro controllers on desktop computers via the [`S ## Cursor Control To give gamepads and joysticks control over a hardware or software cursor, you can use the [`VirtualMouseInput`](../api/UnityEngine.InputSystem.UI.VirtualMouseInput.html) component. See [`VirtualMouseInput` component](UISupport.md#virtual-mouse-cursor-control) in the UI section of the manual. + +## Discover all connected devices + +There are various ways to discover the currently connected devices, as shown in the code samples below. + +To query a list of all connected devices (does not allocate; read-only access): +``` +InputSystem.devices +``` + +To get notified when a device is added or removed: +``` +InputSystem.onDeviceChange += + (device, change) => + { + if (change == InputDeviceChange.Added || change == InputDeviceChange.Removed) + { + Debug.Log($"Device '{device}' was {change}"); + } + } +``` + +To find all gamepads and joysticks: +``` +var devices = InputSystem.devices; +for (var i = 0; i < devices.Count; ++i) +{ + var device = devices[i]; + if (device is Joystick || device is Gamepad) + { + Debug.Log("Found " + device); + } +} +``` \ No newline at end of file diff --git a/Packages/com.unity.inputsystem/Documentation~/Migration.md b/Packages/com.unity.inputsystem/Documentation~/Migration.md index 67a6fd01f2..2c0fb48977 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Migration.md +++ b/Packages/com.unity.inputsystem/Documentation~/Migration.md @@ -37,48 +37,14 @@ All of the new APIs listed below are in the `UnityEngine.InputSystem` namespace. |Input Manager (Old)|Input System (New)| |--|--| [`Input.acceleration`](https://docs.unity3d.com/ScriptReference/Input-acceleration.html)|[`Accelerometer.current.acceleration.ReadValue()`](../api/UnityEngine.InputSystem.Accelerometer.html). -[`Input.accelerationEventCount`](https://docs.unity3d.com/ScriptReference/Input-accelerationEventCount.html)
[`Input.accelerationEvents`](https://docs.unity3d.com/ScriptReference/Input-accelerationEvents.html)|Acceleration events aren't made available separately from other input events. The following code traces all input events on the [`Accelerometer.current`](../api/UnityEngine.InputSystem.Accelerometer.html) device. -```CSharp - private InputEventTrace trace; - - void StartTrace() - { - InputSystem.EnableDevice(Accelerometer.current); - - trace = new InputEventTrace(Accelerometer.current); - trace.Enable(); - } - - void Update() - { - foreach (var e in trace) - { - //... - } - trace.Clear(); - } -``` -|Input Manager (Old)|Input System (New)| -|--|--| -[`Input.anyKey`](https://docs.unity3d.com/ScriptReference/Input-anyKey.html)|[`InputSystem.onAnyButtonPress`](../api/UnityEngine.InputSystem.InputSystem.html#UnityEngine_InputSystem_InputSystem_onAnyButtonPress)
Example:
`InputSystem.onAnyButtonPress.CallOnce(ctrl => Debug.Log($"Button {ctrl} pressed!"));` -|Input Manager (Old)|Input System (New)| -|--|--| +[`Input.accelerationEventCount`](https://docs.unity3d.com/ScriptReference/Input-accelerationEventCount.html)
[`Input.accelerationEvents`](https://docs.unity3d.com/ScriptReference/Input-accelerationEvents.html)|Acceleration events aren't made available separately from other input events. See the [accelerometer code sample on the Sensors page](Sensors.html#accelerometer). +[`Input.anyKey`](https://docs.unity3d.com/ScriptReference/Input-anyKey.html)|[`InputSystem.onAnyButtonPress`](../api/UnityEngine.InputSystem.InputSystem.html#UnityEngine_InputSystem_InputSystem_onAnyButtonPress)
[`Input.anyKeyDown`](https://docs.unity3d.com/ScriptReference/Input-anyKeyDown.html)|[`Keyboard.current.anyKey.wasUpdatedThisFrame`](../api/UnityEngine.InputSystem.Keyboard.html) [`Input.backButtonLeavesApp`](https://docs.unity3d.com/ScriptReference/Input-backButtonLeavesApp.html)|No corresponding API yet. [`Input.compass`](https://docs.unity3d.com/ScriptReference/Input-compass.html)|No corresponding API yet. [`Input.compensateSensors`](https://docs.unity3d.com/ScriptReference/Input-compensateSensors.html)|[`InputSystem.settings.compensateForScreenOrientation`](../api/UnityEngine.InputSystem.InputSettings.html#UnityEngine_InputSystem_InputSettings_compensateForScreenOrientation). [`Input.compositionCursorPos`](https://docs.unity3d.com/ScriptReference/Input-compositionCursorPos.html)|[`Keyboard.current.SetIMECursorPosition(myPosition)`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_SetIMECursorPosition_UnityEngine_Vector2_) -[`Input.compositionString`](https://docs.unity3d.com/ScriptReference/Input-compositionString.html)|Subscribe to the [`Keyboard.onIMECompositionChange`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_onIMECompositionChange) event: - -```CSharp - var compositionString = ""; - Keyboard.current.onIMECompositionChange += composition => - { - compositionString = composition.ToString(); - }; -``` -|Input Manager (Old)|Input System (New)| -|--|--| +[`Input.compositionString`](https://docs.unity3d.com/ScriptReference/Input-compositionString.html)|Subscribe to the [`Keyboard.onIMECompositionChange`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_onIMECompositionChange). [`Input.deviceOrientation`](https://docs.unity3d.com/ScriptReference/Input-deviceOrientation.html)|No corresponding API yet. [`Input.gyro`](https://docs.unity3d.com/ScriptReference/Input-gyro.html)|The `UnityEngine.Gyroscope` class is replaced by multiple separate sensor Devices in the new Input System:
[`Gyroscope`](../api/UnityEngine.InputSystem.Gyroscope.html) to measure angular velocity.
[`GravitySensor`](../api/UnityEngine.InputSystem.GravitySensor.html) to measure the direction of gravity.
[`AttitudeSensor`](../api/UnityEngine.InputSystem.AttitudeSensor.html) to measure the orientation of the device.
[`Accelerometer`](../api/UnityEngine.InputSystem.Accelerometer.html) to measure the total acceleration applied to the device.
[`LinearAccelerationSensor`](../api/UnityEngine.InputSystem.LinearAccelerationSensor.html) to measure acceleration applied to the device, compensating for gravity. [`Input.gyro.attitude`](https://docs.unity3d.com/ScriptReference/Gyroscope-attitude.html)|[`AttitudeSensor.current.orientation.ReadValue()`](../api/UnityEngine.InputSystem.AttitudeSensor.html). @@ -107,72 +73,10 @@ All of the new APIs listed below are in the `UnityEngine.InputSystem` namespace. [`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)|[`InputAction.IsPressed`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_IsPressed_) |[`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)|[`InputAction.WasPressedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasPressedThisFrame_) [`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)|[`InputAction.WasReleasedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasReleasedThisFrame_) -[`Input.GetJoystickNames`](https://docs.unity3d.com/ScriptReference/Input.GetJoystickNames.html)|There is no API that corresponds to this exactly. Here are various ways to discover connected Devices: - -``` -// Query a list of all connected Devices (does not allocate; read-only access). -InputSystem.devices - -// Get notified when a Device is added or removed. -InputSystem.onDeviceChange += - (device, change) => - { - if (change == InputDeviceChange.Added || change == InputDeviceChange.Removed) - { - Debug.Log($"Device '{device}' was {change}"); - } - } - -// Find all gamepads and joysticks. -var devices = InputSystem.devices; -for (var i = 0; i < devices.Count; ++i) -{ - var device = devices[i]; - if (device is Joystick || device is Gamepad) - { - Debug.Log("Found " + device); - } -} -``` -|Input Manager (Old)|Input System (New)| -|--|--| -[`Input.GetKey`](https://docs.unity3d.com/ScriptReference/Input.GetKey.html)|[`ButtonControl.isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding key: - -``` -// Using KeyControl property directly. -Keyboard.current.spaceKey.isPressed -Keyboard.current.aKey.isPressed // etc. - -// Using Key enum. -Keyboard.current[Key.Space].isPressed - -// Using key name. -((KeyControl)Keyboard.current["space"]).isPressed -``` - ->__Note__: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use [`KeyControl.displayName`](../api/UnityEngine.InputSystem.InputControl.html#UnityEngine_InputSystem_InputControl_displayName). - -|Input Manager (Old)|Input System (New)| -|--|--| -[`Input.GetKeyDown`](https://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html)|Use [`ButtonControl.wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding key: - -``` -// Using KeyControl property directly. -Keyboard.current.spaceKey.wasPressedThisFrame -Keyboard.current.aKey.wasPressedThisFrame // etc. - -// Using Key enum. -Keyboard.current[Key.Space].wasPressedThisFrame - -// Using key name. -((KeyControl)Keyboard.current["space"]).wasPressedThisFrame -``` - ->__Note__: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use [`KeyControl.displayName`](../api/UnityEngine.InputSystem.InputControl.html#UnityEngine_InputSystem_InputControl_displayName). - -|Input Manager (Old)|Input System (New)| -|--|--| -[`Input.GetKeyUp`](https://docs.unity3d.com/ScriptReference/Input.GetKeyUp.html)|Use [`ButtonControl.wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding key: +[`Input.GetJoystickNames`](https://docs.unity3d.com/ScriptReference/Input.GetJoystickNames.html)|There is no API that corresponds to this exactly, but there are examples of [how to read all connected devices here](Gamepad.html#discover-all-connected-devices). +[`Input.GetKey`](https://docs.unity3d.com/ScriptReference/Input.GetKey.html)|Use [`ButtonControl.isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding key. +[`Input.GetKeyDown`](https://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html)|Use [`ButtonControl.wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding key. +[`Input.GetKeyUp`](https://docs.unity3d.com/ScriptReference/Input.GetKeyUp.html)|Use [`ButtonControl.wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding key. ``` // Using KeyControl property directly. @@ -231,5 +135,5 @@ Mouse.current.middleButton.wasReleasedThisFrame |Input Manager (Old)|Input System (New)| |--|--| [`Input.GetTouch`](https://docs.unity3d.com/ScriptReference/Input.GetTouch.html)|Use [`InputSystem.EnhancedTouch.Touch.activeTouches[i]`](../api/UnityEngine.InputSystem.EnhancedTouch.Touch.html#UnityEngine_InputSystem_EnhancedTouch_Touch_activeTouches)
__Note__: Enable enhanced touch support first by calling [`InputSystem.EnhancedTouch.Enable()`](../api/UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.html#UnityEngine_InputSystem_EnhancedTouch_EnhancedTouchSupport_Enable). -[`Input.IsJoystickPreconfigured`](https://docs.unity3d.com/ScriptReference/Input.IsJoystickPreconfigured.html)|Not needed. Devices which derive from [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) always correctly implement the mapping of axes and buttons to the corresponding [`InputControl`](../api/UnityEngine.InputSystem.InputControl.html) members of the [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) class. [`Input.ResetInputAxes`](https://docs.unity3d.com/ScriptReference/Input.ResetInputAxes.html)|Not directly applicable. +[`Input.IsJoystickPreconfigured`](https://docs.unity3d.com/ScriptReference/Input.IsJoystickPreconfigured.html)|Not needed. Devices which derive from [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) always correctly implement the mapping of axes and buttons to the corresponding [`InputControl`](../api/UnityEngine.InputSystem.InputControl.html) members of the [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) class. [`Input.ResetInputAxes`](https://docs.unity3d.com/ScriptReference/Input.ResetInputAxes.html) [`UnityEngine.TouchScreenKeyboard`](https://docs.unity3d.com/ScriptReference/TouchScreenKeyboard.html)|No corresponding API yet. Use `TouchScreenKeyboard` for now. diff --git a/Packages/com.unity.inputsystem/Documentation~/Sensors.md b/Packages/com.unity.inputsystem/Documentation~/Sensors.md index f869a4d671..23a628c606 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Sensors.md +++ b/Packages/com.unity.inputsystem/Documentation~/Sensors.md @@ -3,19 +3,19 @@ uid: input-system-sensors --- # Sensor support -* [Sampling Frequency](#sampling-frequency) -* [Accelerometer](#accelerometer) -* [Gyroscope](#gyroscope) -* [GravitySensor](#gravitysensor) -* [AttitudeSensor](#attitudesensor) -* [LinearAccelerationSensor](#linearaccelerationsensor) -* [MagneticFieldSensor](#magneticfieldsensor) -* [LightSensor](#lightsensor) -* [PressureSensor](#pressuresensor) -* [ProximitySensor](#proximitysensor) -* [HumiditySensor](#humiditysensor) -* [AmbientTemperatureSensor](#ambienttemperaturesensor) -* [StepCounter](#stepcounter) +- [Sampling frequency](#sampling-frequency) +- [`Accelerometer`](#accelerometer) +- [`Gyroscope`](#gyroscope) +- [`GravitySensor`](#gravitysensor) +- [`AttitudeSensor`](#attitudesensor) +- [`LinearAccelerationSensor`](#linearaccelerationsensor) +- [`MagneticFieldSensor`](#magneticfieldsensor) +- [`LightSensor`](#lightsensor) +- [`PressureSensor`](#pressuresensor) +- [`ProximitySensor`](#proximitysensor) +- [`HumiditySensor`](#humiditysensor) +- [`AmbientTemperatureSensor`](#ambienttemperaturesensor) +- [`StepCounter`](#stepcounter) Sensors are [`InputDevices`](Devices.md) that measure environmental characteristics of the device that the content is running on. Unity currently supports sensors on iOS and Android. Android supports a wider range of sensors than iOS. @@ -84,6 +84,28 @@ Gyroscope.current.samplingFrequency = 16; Use the accelerometer to measure the acceleration of a device. This is useful to control content by moving a device around. It reports the acceleration measured on a device both due to moving the device around, and due to gravity pulling the device down. You can use `GravitySensor` and `LinearAccelerationSensor` to get separate values for these. Values are affected by the [__Compensate Orientation__](Settings.md#compensate-orientation) setting. + The following code traces all input events on the [`Accelerometer.current`](../api/UnityEngine.InputSystem.Accelerometer.html) device. +```CSharp + private InputEventTrace trace; + + void StartTrace() + { + InputSystem.EnableDevice(Accelerometer.current); + + trace = new InputEventTrace(Accelerometer.current); + trace.Enable(); + } + + void Update() + { + foreach (var e in trace) + { + //... + } + trace.Clear(); + } +``` + ## [`Gyroscope`](../api/UnityEngine.InputSystem.Gyroscope.html) Use the gyroscope to measure the angular velocity of a device. This is useful to control content by rotating a device. Values are affected by the [__Compensate Orientation__](Settings.md#compensate-orientation) setting. diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs index 6036b6d813..496bcc54f2 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs @@ -87,8 +87,26 @@ public ButtonControl() /// /// True if button is currently pressed. /// - /// A button is considered press if it's value is equal to or greater + /// A button is considered pressed if its value is equal to or greater /// than its button press threshold (). + /// + /// + /// You can us this to read whether specific keys are currently pressed by using isPressed on keys, as shown in the following examples: + /// + /// + /// // Using KeyControl property directly. + /// Keyboard.current.spaceKey.isPressed + /// Keyboard.current.aKey.isPressed // etc. + /// + /// // Using Key enum. + /// Keyboard.current[Key.Space].isPressed + /// + /// // Using key name. + /// (KeyControl)Keyboard.current["space"]).isPressed + /// + /// + /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . + /// /// /// /// @@ -117,6 +135,7 @@ public ButtonControl() /// } /// /// + /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . /// public bool wasPressedThisFrame => device.wasUpdatedThisFrame && IsValueConsideredPressed(value) && !IsValueConsideredPressed(ReadValueFromPreviousFrame()); diff --git a/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs b/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs index e400589a7d..122d3485ef 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs @@ -970,6 +970,17 @@ public event Action onTextInput /// Many IMEs cause this event to fire with a blank string when the composition is submitted or reset, however it is best /// not to rely on this behaviour since it is IME dependent. /// + /// To subscribe to the onIMECompositionChange event, use the following sample code: + /// + /// + /// var compositionString = ""; + /// Keyboard.current.onIMECompositionChange += composition => + /// { + /// compositionString = composition.ToString(); + /// }; + /// + /// + /// /// See for turning IME on/off /// public event Action onIMECompositionChange From ae672e74fdd96688b48dabfb1c6e872e9b13777c Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Fri, 17 May 2024 15:40:38 +0100 Subject: [PATCH 02/18] More WIP for improving Migration page --- .../Documentation~/Migration.md | 138 ++++++++---------- .../InputSystem/Controls/ButtonControl.cs | 62 +++++++- 2 files changed, 120 insertions(+), 80 deletions(-) diff --git a/Packages/com.unity.inputsystem/Documentation~/Migration.md b/Packages/com.unity.inputsystem/Documentation~/Migration.md index 2c0fb48977..e2a0de21a7 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Migration.md +++ b/Packages/com.unity.inputsystem/Documentation~/Migration.md @@ -3,6 +3,16 @@ uid: input-system-migration --- # Migrating from the old Input Manager +- [Read the introductory documentation first](#read-the-introductory-documentation-first) +- [Which system is enabled?](#which-system-is-enabled) +- [List of corresponding API in the old Input Manager new Input System package](#list-of-corresponding-api-in-the-old-input-manager-new-input-system-package) + - [Keyboard](#keyboard) + - [Mouse](#mouse) + - [Touch and Pen](#touch-and-pen) + - [Gamepad and Joystick](#gamepad-and-joystick) + - [Sensors](#sensors) + - [Actions](#actions) + This page is provided to help you match input-related API from Unity's old, built-in input (known as the [Input Manager](https://docs.unity3d.com/Manual/class-InputManager.html)) to the corresponding API in the new Input System package. ## Read the introductory documentation first @@ -11,7 +21,7 @@ If you're new to the Input System package and have landed on this page looking f This is because there are a number of different ways to read input using the Input System, and many of the directly corresponding API methods on this page might give you the quickest but least flexible solution, and may not be suitable for a project with more complex requirements. -### Which system is enabled? +## Which system is enabled? When installing the new Input System, Unity prompts you to enable the new input system and disable the old one. You can change this setting at any time later, by going to **Edit > Project Settings > Player > Other Settings > Active Input Handling**, [as described here](./Installation.md#enabling-the-new-input-backends). @@ -34,106 +44,76 @@ There are scripting symbols defined which allow you to use conditional compilati All of the new APIs listed below are in the `UnityEngine.InputSystem` namespace. The namespace is omitted here for brevity. `UnityEngine.InputSystem` is referenced in full for easy disambiguation. +### Keyboard |Input Manager (Old)|Input System (New)| |--|--| -[`Input.acceleration`](https://docs.unity3d.com/ScriptReference/Input-acceleration.html)|[`Accelerometer.current.acceleration.ReadValue()`](../api/UnityEngine.InputSystem.Accelerometer.html). -[`Input.accelerationEventCount`](https://docs.unity3d.com/ScriptReference/Input-accelerationEventCount.html)
[`Input.accelerationEvents`](https://docs.unity3d.com/ScriptReference/Input-accelerationEvents.html)|Acceleration events aren't made available separately from other input events. See the [accelerometer code sample on the Sensors page](Sensors.html#accelerometer). -[`Input.anyKey`](https://docs.unity3d.com/ScriptReference/Input-anyKey.html)|[`InputSystem.onAnyButtonPress`](../api/UnityEngine.InputSystem.InputSystem.html#UnityEngine_InputSystem_InputSystem_onAnyButtonPress)
+[`Input.GetKey`](https://docs.unity3d.com/ScriptReference/Input.GetKey.html)|Use [`ButtonControl.isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding key.
Example: `Input.GetKey(KeyCode.Space)` becomes: `InputSystem.Keyboard.current.spaceKey.isPressed` +[`Input.GetKeyDown`](https://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html)|Use [`ButtonControl.wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding key. +[`Input.GetKeyUp`](https://docs.unity3d.com/ScriptReference/Input.GetKeyUp.html)|Use [`ButtonControl.wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding key. +[`Input.anyKey`](https://docs.unity3d.com/ScriptReference/Input-anyKey.html)|[`onAnyButtonPress`](../api/UnityEngine.InputSystem.InputSystem.html#UnityEngine_InputSystem_InputSystem_onAnyButtonPress)
[`Input.anyKeyDown`](https://docs.unity3d.com/ScriptReference/Input-anyKeyDown.html)|[`Keyboard.current.anyKey.wasUpdatedThisFrame`](../api/UnityEngine.InputSystem.Keyboard.html) -[`Input.backButtonLeavesApp`](https://docs.unity3d.com/ScriptReference/Input-backButtonLeavesApp.html)|No corresponding API yet. -[`Input.compass`](https://docs.unity3d.com/ScriptReference/Input-compass.html)|No corresponding API yet. -[`Input.compensateSensors`](https://docs.unity3d.com/ScriptReference/Input-compensateSensors.html)|[`InputSystem.settings.compensateForScreenOrientation`](../api/UnityEngine.InputSystem.InputSettings.html#UnityEngine_InputSystem_InputSettings_compensateForScreenOrientation). [`Input.compositionCursorPos`](https://docs.unity3d.com/ScriptReference/Input-compositionCursorPos.html)|[`Keyboard.current.SetIMECursorPosition(myPosition)`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_SetIMECursorPosition_UnityEngine_Vector2_) [`Input.compositionString`](https://docs.unity3d.com/ScriptReference/Input-compositionString.html)|Subscribe to the [`Keyboard.onIMECompositionChange`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_onIMECompositionChange). -[`Input.deviceOrientation`](https://docs.unity3d.com/ScriptReference/Input-deviceOrientation.html)|No corresponding API yet. -[`Input.gyro`](https://docs.unity3d.com/ScriptReference/Input-gyro.html)|The `UnityEngine.Gyroscope` class is replaced by multiple separate sensor Devices in the new Input System:
[`Gyroscope`](../api/UnityEngine.InputSystem.Gyroscope.html) to measure angular velocity.
[`GravitySensor`](../api/UnityEngine.InputSystem.GravitySensor.html) to measure the direction of gravity.
[`AttitudeSensor`](../api/UnityEngine.InputSystem.AttitudeSensor.html) to measure the orientation of the device.
[`Accelerometer`](../api/UnityEngine.InputSystem.Accelerometer.html) to measure the total acceleration applied to the device.
[`LinearAccelerationSensor`](../api/UnityEngine.InputSystem.LinearAccelerationSensor.html) to measure acceleration applied to the device, compensating for gravity. -[`Input.gyro.attitude`](https://docs.unity3d.com/ScriptReference/Gyroscope-attitude.html)|[`AttitudeSensor.current.orientation.ReadValue()`](../api/UnityEngine.InputSystem.AttitudeSensor.html). -[`Input.gyro.enabled`](https://docs.unity3d.com/ScriptReference/Gyroscope-enabled.html)|Get: `Gyroscope.current.enabled`
Set:
`InputSystem.EnableDevice(Gyroscope.current);`
`InputSystem.DisableDevice(Gyroscope.current);`

__Note__: The new Input System replaces `UnityEngine.Gyroscope` with multiple separate sensor devices. Substitute [`Gyroscope`](../api/UnityEngine.InputSystem.Gyroscope.html) with other sensors in the sample as needed. See the notes for `Input.gyro` above for details. -[`Input.gyro.gravity`](https://docs.unity3d.com/ScriptReference/Gyroscope-gravity.html)|[`GravitySensor.current.gravity.ReadValue()`](../api/UnityEngine.InputSystem.GravitySensor.html) -[`Input.gyro.rotationRate`](https://docs.unity3d.com/ScriptReference/Gyroscope-rotationRate.html)|[`Gyroscope.current.angularVelocity.ReadValue()`](../api/UnityEngine.InputSystem.Gyroscope.html). -[`Input.gyro.rotationRateUnbiased`](https://docs.unity3d.com/ScriptReference/Gyroscope-rotationRateUnbiased.html)|No corresponding API yet. -[`Input.gyro.updateInterval`](https://docs.unity3d.com/ScriptReference/Gyroscope-updateInterval.html)|[`Sensor.samplingFrequency`](../api/UnityEngine.InputSystem.Sensor.html#UnityEngine_InputSystem_Sensor_samplingFrequency)
Example:
`Gyroscope.current.samplingFrequency = 1.0f / updateInterval;`

__Notes__:
[`samplingFrequency`](../api/UnityEngine.InputSystem.Sensor.html#UnityEngine_InputSystem_Sensor_samplingFrequency) is in Hz, not in seconds as [`updateInterval`](https://docs.unity3d.com/ScriptReference/Gyroscope-updateInterval.html), so you need to divide 1 by the value.

The new Input System replaces `UnityEngine.Gyroscope` with multiple separate sensor devices. Substitute [`Gyroscope`](../api/UnityEngine.InputSystem.Gyroscope.html) with other sensors in the sample as needed. See the notes for `Input.gyro` above for details. -[`Input.gyro.userAcceleration`](https://docs.unity3d.com/ScriptReference/Gyroscope-userAcceleration.html)|[`LinearAccelerationSensor.current.acceleration.acceleration.ReadValue()`](../api/UnityEngine.InputSystem.LinearAccelerationSensor.html) [`Input.imeCompositionMode`](https://docs.unity3d.com/ScriptReference/Input-imeCompositionMode.html)|No corresponding API yet. [`Input.imeIsSelected`](https://docs.unity3d.com/ScriptReference/Input-imeIsSelected.html)|Get: `Keyboard.current.imeSelected`
Set: `Keyboard.current.SetIMEEnabled(true);` [`Input.inputString`](https://docs.unity3d.com/ScriptReference/Input-inputString.html)|Subscribe to the [`Keyboard.onTextInput`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_onTextInput) event:
`Keyboard.current.onTextInput += character => /* ... */;` -[`Input.location`](https://docs.unity3d.com/ScriptReference/Input-location.html)|No corresponding API yet. + +### Mouse +|Input Manager (Old)|Input System (New)| +|--|--| +[`Input.GetMouseButton`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButton.html)|Use [`ButtonControl.isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding mouse button.
Example: `Input.GetKey(KeyCode.Mouse0)` becomes: `InputSystem.Mouse.current.leftButton.isPressed` +[`Input.GetMouseButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButtonDown.html)|Use [`ButtonControl.wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding mouse button. +[`Input.GetMouseButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButtonUp.html)|Use [`ButtonControl.wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding mouse button. [`Input.mousePosition`](https://docs.unity3d.com/ScriptReference/Input-mousePosition.html)|[`Mouse.current.position.ReadValue()`](../api/UnityEngine.InputSystem.Mouse.html)
__Note__: Mouse simulation from touch isn't implemented yet. [`Input.mousePresent`](https://docs.unity3d.com/ScriptReference/Input-mousePresent.html)|[`Mouse.current != null`](../api/UnityEngine.InputSystem.Mouse.html#UnityEngine_InputSystem_Mouse_current). + + +### Touch and Pen + +|Input Manager (Old)|Input System (New)| +|--|--| +[`Input.GetTouch`](https://docs.unity3d.com/ScriptReference/Input.GetTouch.html)|Use [`EnhancedTouch.Touch.activeTouches[i]`](../api/UnityEngine.InputSystem.EnhancedTouch.Touch.html#UnityEngine_InputSystem_EnhancedTouch_Touch_activeTouches)
__Note__: Enable enhanced touch support first by calling [`EnhancedTouch.Enable()`](../api/UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.html#UnityEngine_InputSystem_EnhancedTouch_EnhancedTouchSupport_Enable). [`Input.multiTouchEnabled`](https://docs.unity3d.com/ScriptReference/Input-multiTouchEnabled.html)|No corresponding API yet. [`Input.simulateMouseWithTouches`](https://docs.unity3d.com/ScriptReference/Input-multiTouchEnabled.html)|No corresponding API yet. [`Input.stylusTouchSupported`](https://docs.unity3d.com/ScriptReference/Input-stylusTouchSupported.html)|No corresponding API yet. -[`Input.touchCount`](https://docs.unity3d.com/ScriptReference/Input-touchCount.html)|[`InputSystem.EnhancedTouch.Touch.activeTouches.Count`](../api/UnityEngine.InputSystem.EnhancedTouch.Touch.html#UnityEngine_InputSystem_EnhancedTouch_Touch_activeTouches)
__Note__: Enable enhanced touch support first by calling [`InputSystem.EnhancedTouchSupport.Enable()`](../api/UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.html#UnityEngine_InputSystem_EnhancedTouch_EnhancedTouchSupport_Enable) -[`Input.touches`](https://docs.unity3d.com/ScriptReference/Input-touches.html)|[`InputSystem.EnhancedTouch.Touch.activeTouches`](../api/UnityEngine.InputSystem.EnhancedTouch.Touch.html#UnityEngine_InputSystem_EnhancedTouch_Touch_activeTouches)
__Note__: Enable enhanced touch support first by calling [`InputSystem.EnhancedTouch.Enable()`](../api/UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.html#UnityEngine_InputSystem_EnhancedTouch_EnhancedTouchSupport_Enable) +[`Input.touchCount`](https://docs.unity3d.com/ScriptReference/Input-touchCount.html)|[`EnhancedTouch.Touch.activeTouches.Count`](../api/UnityEngine.InputSystem.EnhancedTouch.Touch.html#UnityEngine_InputSystem_EnhancedTouch_Touch_activeTouches)
__Note__: Enable enhanced touch support first by calling [`EnhancedTouchSupport.Enable()`](../api/UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.html#UnityEngine_InputSystem_EnhancedTouch_EnhancedTouchSupport_Enable) +[`Input.touches`](https://docs.unity3d.com/ScriptReference/Input-touches.html)|[`EnhancedTouch.Touch.activeTouches`](../api/UnityEngine.InputSystem.EnhancedTouch.Touch.html#UnityEngine_InputSystem_EnhancedTouch_Touch_activeTouches)
__Note__: Enable enhanced touch support first by calling [`EnhancedTouch.Enable()`](../api/UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.html#UnityEngine_InputSystem_EnhancedTouch_EnhancedTouchSupport_Enable) [`Input.touchPressureSupported`](https://docs.unity3d.com/ScriptReference/Input-touchPressureSupported.html)|No corresponding API yet. [`Input.touchSupported`](https://docs.unity3d.com/ScriptReference/Input-touchSupported.html)|[`Touchscreen.current != null`](../api/UnityEngine.InputSystem.Touchscreen.html#UnityEngine_InputSystem_Touchscreen_current) -[`Input.GetAccelerationEvent`](https://docs.unity3d.com/ScriptReference/Input.GetAccelerationEvent.html)|See notes for `Input.accelerationEvents` above. -[`Input.GetAxis`](https://docs.unity3d.com/ScriptReference/Input.GetAxis.html)|Set up an action as a 1D or 2D axis in the Actions Editor, then use [`InputAction.ReadValue`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_ReadValue__1) to read the value or 2D vector from the axis. There are some default built-in axis actions. See the [Quickstart Guide](QuickStartGuide.md) to get started quickly. -[`Input.GetAxisRaw`](https://docs.unity3d.com/ScriptReference/Input.GetAxisRaw.html)|Not directly applicable. You can use [`InputControl<>.ReadUnprocessedValue()`](../api/UnityEngine.InputSystem.InputControl-1.html#UnityEngine_InputSystem_InputControl_1_ReadUnprocessedValue) to read unprocessed values from any control. -[`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)|[`InputAction.IsPressed`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_IsPressed_) -|[`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)|[`InputAction.WasPressedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasPressedThisFrame_) -[`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)|[`InputAction.WasReleasedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasReleasedThisFrame_) -[`Input.GetJoystickNames`](https://docs.unity3d.com/ScriptReference/Input.GetJoystickNames.html)|There is no API that corresponds to this exactly, but there are examples of [how to read all connected devices here](Gamepad.html#discover-all-connected-devices). -[`Input.GetKey`](https://docs.unity3d.com/ScriptReference/Input.GetKey.html)|Use [`ButtonControl.isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding key. -[`Input.GetKeyDown`](https://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html)|Use [`ButtonControl.wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding key. -[`Input.GetKeyUp`](https://docs.unity3d.com/ScriptReference/Input.GetKeyUp.html)|Use [`ButtonControl.wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding key. - -``` -// Using KeyControl property directly. -Keyboard.current.spaceKey.wasReleasedThisFrame -Keyboard.current.aKey.wasReleasedThisFrame // etc. - -// Using Key enum. -Keyboard.current[Key.Space].wasReleasedThisFrame - -// Using key name. -((KeyControl)Keyboard.current["space"]).wasReleasedThisFrame -``` - ->__Note__: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use [`KeyControl.displayName`](../api/UnityEngine.InputSystem.InputControl.html#UnityEngine_InputSystem_InputControl_displayName). +[`UnityEngine.TouchScreenKeyboard`](https://docs.unity3d.com/ScriptReference/TouchScreenKeyboard.html)|No corresponding API yet. Use `TouchScreenKeyboard` for now. -|Input Manager (Old)|Input System (New)| -|--|--| -[`Input.GetMouseButton`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButton.html)|Use [`ButtonControl.isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding mouse button: -``` -Mouse.current.leftButton.isPressed -Mouse.current.rightButton.isPressed -Mouse.current.middleButton.isPressed - -// You can also go through all buttons on the mouse (does not allocate). -var controls = Mouse.current.allControls; -for (var i = 0; i < controls.Count; ++i) -{ - var button = controls[i] as ButtonControl; - if (button != null && button.isPressed) - /* ... */; -} - -// Or look up controls by name. -((ButtonControl)Mouse.current["leftButton"]).isPressed -``` +### Gamepad and Joystick |Input Manager (Old)|Input System (New)| |--|--| -[`Input.GetMouseButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButtonDown.html)|Use [`ButtonControl.wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding mouse button: +[`Input.GetAxis`](https://docs.unity3d.com/ScriptReference/Input.GetAxis.html)|Set up an action as a 1D or 2D axis in the Actions Editor, then use [`InputAction.ReadValue`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_ReadValue__1) to read the value or 2D vector from the axis. There are some default built-in axis actions. See the [Quickstart Guide](QuickStartGuide.md) to get started quickly. +[`Input.GetAxisRaw`](https://docs.unity3d.com/ScriptReference/Input.GetAxisRaw.html)|Not directly applicable. You can use [`InputControl<>.ReadUnprocessedValue()`](../api/UnityEngine.InputSystem.InputControl-1.html#UnityEngine_InputSystem_InputControl_1_ReadUnprocessedValue) to read unprocessed values from any control. +[`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)|Use [`InputAction.IsPressed`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_IsPressed_) on the corresponding Gamepad button.
Example: `Input.GetKey(KeyCode.JoystickButton0)` becomes: `InputSystem.GamePad.current.buttonNorth.isPressed`. +[`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)|Use [`InputAction.WasPressedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasPressedThisFrame_) on the corresponding Gamepad button. +[`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)|Use [`InputAction.WasReleasedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasReleasedThisFrame_) on the corresponding Gamepad button. +[`Input.GetJoystickNames`](https://docs.unity3d.com/ScriptReference/Input.GetJoystickNames.html)|There is no API that corresponds to this exactly, but there are examples of [how to read all connected devices here](Gamepad.html#discover-all-connected-devices). +[`Input.IsJoystickPreconfigured`](https://docs.unity3d.com/ScriptReference/Input.IsJoystickPreconfigured.html)|Not needed. Devices which derive from [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) always correctly implement the mapping of axes and buttons to the corresponding [`InputControl`](../api/UnityEngine.InputSystem.InputControl.html) members of the [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) class. [`Input.ResetInputAxes`](https://docs.unity3d.com/ScriptReference/Input.ResetInputAxes.html) -``` -Mouse.current.leftButton.wasPressedThisFrame -Mouse.current.rightButton.wasPressedThisFrame -Mouse.current.middleButton.wasPressedThisFrame -``` +### Sensors |Input Manager (Old)|Input System (New)| |--|--| -[`Input.GetMouseButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButtonUp.html)|Use [`ButtonControl.wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding mouse button: - -``` -Mouse.current.leftButton.wasReleasedThisFrame -Mouse.current.rightButton.wasReleasedThisFrame -Mouse.current.middleButton.wasReleasedThisFrame -``` +[`Input.acceleration`](https://docs.unity3d.com/ScriptReference/Input-acceleration.html)|[`Accelerometer.current.acceleration.ReadValue()`](../api/UnityEngine.InputSystem.Accelerometer.html). +[`Input.accelerationEventCount`](https://docs.unity3d.com/ScriptReference/Input-accelerationEventCount.html)
[`Input.accelerationEvents`](https://docs.unity3d.com/ScriptReference/Input-accelerationEvents.html)|Acceleration events aren't made available separately from other input events. See the [accelerometer code sample on the Sensors page](Sensors.html#accelerometer). +[`Input.compass`](https://docs.unity3d.com/ScriptReference/Input-compass.html)|No corresponding API yet. +[`Input.compensateSensors`](https://docs.unity3d.com/ScriptReference/Input-compensateSensors.html)|[`InputSettings.compensateForScreenOrientation`](../api/UnityEngine.InputSystem.InputSettings.html#UnityEngine_InputSystem_InputSettings_compensateForScreenOrientation). +[`Input.deviceOrientation`](https://docs.unity3d.com/ScriptReference/Input-deviceOrientation.html)|No corresponding API yet. +[`Input.gyro`](https://docs.unity3d.com/ScriptReference/Input-gyro.html)|The `UnityEngine.Gyroscope` class is replaced by multiple separate sensor Devices in the new Input System:
[`Gyroscope`](../api/UnityEngine.InputSystem.Gyroscope.html) to measure angular velocity.
[`GravitySensor`](../api/UnityEngine.InputSystem.GravitySensor.html) to measure the direction of gravity.
[`AttitudeSensor`](../api/UnityEngine.InputSystem.AttitudeSensor.html) to measure the orientation of the device.
[`Accelerometer`](../api/UnityEngine.InputSystem.Accelerometer.html) to measure the total acceleration applied to the device.
[`LinearAccelerationSensor`](../api/UnityEngine.InputSystem.LinearAccelerationSensor.html) to measure acceleration applied to the device, compensating for gravity. +[`Input.gyro.attitude`](https://docs.unity3d.com/ScriptReference/Gyroscope-attitude.html)|[`AttitudeSensor.current.orientation.ReadValue()`](../api/UnityEngine.InputSystem.AttitudeSensor.html). +[`Input.gyro.enabled`](https://docs.unity3d.com/ScriptReference/Gyroscope-enabled.html)|Get: `Gyroscope.current.enabled`
Set:
`EnableDevice(Gyroscope.current);`
`DisableDevice(Gyroscope.current);`

__Note__: The new Input System replaces `UnityEngine.Gyroscope` with multiple separate sensor devices. Substitute [`Gyroscope`](../api/UnityEngine.InputSystem.Gyroscope.html) with other sensors in the sample as needed. See the notes for `Input.gyro` above for details. +[`Input.gyro.gravity`](https://docs.unity3d.com/ScriptReference/Gyroscope-gravity.html)|[`GravitySensor.current.gravity.ReadValue()`](../api/UnityEngine.InputSystem.GravitySensor.html) +[`Input.gyro.rotationRate`](https://docs.unity3d.com/ScriptReference/Gyroscope-rotationRate.html)|[`Gyroscope.current.angularVelocity.ReadValue()`](../api/UnityEngine.InputSystem.Gyroscope.html). +[`Input.gyro.rotationRateUnbiased`](https://docs.unity3d.com/ScriptReference/Gyroscope-rotationRateUnbiased.html)|No corresponding API yet. +[`Input.gyro.updateInterval`](https://docs.unity3d.com/ScriptReference/Gyroscope-updateInterval.html)|[`Sensor.samplingFrequency`](../api/UnityEngine.InputSystem.Sensor.html#UnityEngine_InputSystem_Sensor_samplingFrequency)
Example:
`Gyroscope.current.samplingFrequency = 1.0f / updateInterval;`

__Notes__:
[`samplingFrequency`](../api/UnityEngine.InputSystem.Sensor.html#UnityEngine_InputSystem_Sensor_samplingFrequency) is in Hz, not in seconds as [`updateInterval`](https://docs.unity3d.com/ScriptReference/Gyroscope-updateInterval.html), so you need to divide 1 by the value.

The new Input System replaces `UnityEngine.Gyroscope` with multiple separate sensor devices. Substitute [`Gyroscope`](../api/UnityEngine.InputSystem.Gyroscope.html) with other sensors in the sample as needed. See the notes for `Input.gyro` above for details. +[`Input.gyro.userAcceleration`](https://docs.unity3d.com/ScriptReference/Gyroscope-userAcceleration.html)|[`LinearAccelerationSensor.current.acceleration.acceleration.ReadValue()`](../api/UnityEngine.InputSystem.LinearAccelerationSensor.html) +[`Input.location`](https://docs.unity3d.com/ScriptReference/Input-location.html)|No corresponding API yet. +[`Input.GetAccelerationEvent`](https://docs.unity3d.com/ScriptReference/Input.GetAccelerationEvent.html)|See notes for `Input.accelerationEvents` above. +### Actions |Input Manager (Old)|Input System (New)| |--|--| -[`Input.GetTouch`](https://docs.unity3d.com/ScriptReference/Input.GetTouch.html)|Use [`InputSystem.EnhancedTouch.Touch.activeTouches[i]`](../api/UnityEngine.InputSystem.EnhancedTouch.Touch.html#UnityEngine_InputSystem_EnhancedTouch_Touch_activeTouches)
__Note__: Enable enhanced touch support first by calling [`InputSystem.EnhancedTouch.Enable()`](../api/UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.html#UnityEngine_InputSystem_EnhancedTouch_EnhancedTouchSupport_Enable). -[`Input.IsJoystickPreconfigured`](https://docs.unity3d.com/ScriptReference/Input.IsJoystickPreconfigured.html)|Not needed. Devices which derive from [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) always correctly implement the mapping of axes and buttons to the corresponding [`InputControl`](../api/UnityEngine.InputSystem.InputControl.html) members of the [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) class. [`Input.ResetInputAxes`](https://docs.unity3d.com/ScriptReference/Input.ResetInputAxes.html) -[`UnityEngine.TouchScreenKeyboard`](https://docs.unity3d.com/ScriptReference/TouchScreenKeyboard.html)|No corresponding API yet. Use `TouchScreenKeyboard` for now. +[`Input.backButtonLeavesApp`](https://docs.unity3d.com/ScriptReference/Input-backButtonLeavesApp.html)|No corresponding API yet. diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs index 496bcc54f2..37655660fc 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs @@ -91,7 +91,7 @@ public ButtonControl() /// than its button press threshold (). /// /// - /// You can us this to read whether specific keys are currently pressed by using isPressed on keys, as shown in the following examples: + /// You can use this to read whether specific keys are currently pressed by using isPressed on keys, as shown in the following examples: /// /// /// // Using KeyControl property directly. @@ -107,6 +107,30 @@ public ButtonControl() /// /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . /// + /// You can also use this to read mouse buttons, as shown in the following examples: + /// + /// + /// + /// Mouse.current.leftButton.isPressed + /// Mouse.current.rightButton.isPressed + /// Mouse.current.middleButton.isPressed + /// + /// // You can also go through all buttons on the mouse (does not allocate). + /// var controls = Mouse.current.allControls; + /// for (var i = 0; i < controls.Count; ++i) + /// { + /// var button = controls[i] as ButtonControl; + /// if (button != null && button.isPressed) + /// { + /// // respond to mouse button press here... + /// } + /// } + /// + /// // Or look up controls by name. + /// ((ButtonControl)Mouse.current["leftButton"]).isPressed + /// + /// + /// /// /// /// @@ -136,9 +160,45 @@ public ButtonControl() /// /// /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . + /// + /// You can also use this property to read mouse buttons. For example: + /// + /// + /// + /// Mouse.current.leftButton.wasPressedThisFrame + /// Mouse.current.rightButton.wasPressedThisFrame + /// Mouse.current.middleButton.wasPressedThisFrame + /// + /// + /// + /// /// public bool wasPressedThisFrame => device.wasUpdatedThisFrame && IsValueConsideredPressed(value) && !IsValueConsideredPressed(ReadValueFromPreviousFrame()); + /// + /// Whether the press ended this frame. + /// + /// True if the current press of the button ended this frame. + /// + /// + /// + /// // An example showing the use of this property on a gamepad button and a keyboard key. + /// + /// using UnityEngine; + /// using UnityEngine.InputSystem; + /// + /// public class ExampleScript : MonoBehaviour + /// { + /// void Update() + /// { + /// bool buttonPressed = Gamepad.current.aButton.wasReleasedThisFrame; + /// bool spaceKeyPressed = Keyboard.current.spaceKey.wasReleasedThisFrame; + /// } + /// } + /// + /// + /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . + /// public bool wasReleasedThisFrame => device.wasUpdatedThisFrame && !IsValueConsideredPressed(value) && IsValueConsideredPressed(ReadValueFromPreviousFrame()); // We make the current global default button press point available as a static so that we don't have to From 0f891a0a957812f093fe5b1b3c53fc59bf14dbe8 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Tue, 21 May 2024 13:57:06 +0100 Subject: [PATCH 03/18] more WIP - migrating action-based input --- .../Images/InputManagerVsInputActions.png | Bin 0 -> 61519 bytes .../Documentation~/Migration.md | 44 +++++++++++------- 2 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 Packages/com.unity.inputsystem/Documentation~/Images/InputManagerVsInputActions.png diff --git a/Packages/com.unity.inputsystem/Documentation~/Images/InputManagerVsInputActions.png b/Packages/com.unity.inputsystem/Documentation~/Images/InputManagerVsInputActions.png new file mode 100644 index 0000000000000000000000000000000000000000..30b44d7f7879009f5b2a4e997d5538a6e350177b GIT binary patch literal 61519 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 literal 0 HcmV?d00001 diff --git a/Packages/com.unity.inputsystem/Documentation~/Migration.md b/Packages/com.unity.inputsystem/Documentation~/Migration.md index e2a0de21a7..ba2fefc11c 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Migration.md +++ b/Packages/com.unity.inputsystem/Documentation~/Migration.md @@ -6,12 +6,11 @@ uid: input-system-migration - [Read the introductory documentation first](#read-the-introductory-documentation-first) - [Which system is enabled?](#which-system-is-enabled) - [List of corresponding API in the old Input Manager new Input System package](#list-of-corresponding-api-in-the-old-input-manager-new-input-system-package) + - [Action-based input](#action-based-input) - [Keyboard](#keyboard) - [Mouse](#mouse) - [Touch and Pen](#touch-and-pen) - - [Gamepad and Joystick](#gamepad-and-joystick) - [Sensors](#sensors) - - [Actions](#actions) This page is provided to help you match input-related API from Unity's old, built-in input (known as the [Input Manager](https://docs.unity3d.com/Manual/class-InputManager.html)) to the corresponding API in the new Input System package. @@ -44,6 +43,30 @@ There are scripting symbols defined which allow you to use conditional compilati All of the new APIs listed below are in the `UnityEngine.InputSystem` namespace. The namespace is omitted here for brevity. `UnityEngine.InputSystem` is referenced in full for easy disambiguation. +### Action-based input + +Action-based input refers to reading pre-configured named axes, buttons, or other controls. + +- In the old Input Manager, these are defined in the **Axes** list, in the **Input Manager** section of the **Project Settings** window. +- In the new Input System, these are defined in the [Actions Editor](ActionsEditor.md), which can be found in the **Input System Package** section of the **Project Settings** window, or by opening an [Action Asset](ActionAssets.md). + +![](Images/InputManagerVsInputActions.png)
_On the left, the old Input Manager Axes Configuration window, in Project settings. On the right, the new Input System's [Actions Editor](ActionsEditor.md)._ + +__Note:__ In most cases for named axes and buttons, the new Input System requires slightly more code than the old Input Manager, but this results in better performance. This is because in the new Input System, the logic is separated into two parts: the first is to find and store a reference to the action (usually done once, for example in your `Start` method), and the second is to read the action (usually done every frame, for example in your `Update` method). In contrast, the old Input Manager used a string-based API to "find" and "read" the value at the same time, because it was not possible to store a reference to a button or axis. This results in worse performance, because the axis or button is looked up each time the value is read. + +|Input Manager (Old)|Input System (New)| +|--|--| +[`Input.GetAxis`](https://docs.unity3d.com/ScriptReference/Input.GetAxis.html)|Set up an action as a 1D or 2D axis in the Actions Editor, then use [`InputAction.ReadValue`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_ReadValue__1) to read the value or 2D vector from the axis. There are some default built-in axis actions. See the [Quickstart Guide](QuickStartGuide.md) to get started quickly.

Use [`FindAction`](../api/UnityEngine.InputSystem.InputActionAsset.html#UnityEngine_InputSystem_InputActionAsset_FindAction_System_String_System_Boolean_) to find and store a reference to the action.
For example: `InputAction moveAction = InputSystem.actions.FindAction("Move")`.

Use [`ReadValue`](../api/UnityEngine.InputSystem.InputBindingComposite-1.html#UnityEngine_InputSystem_InputBindingComposite_1_ReadValue_UnityEngine_InputSystem_InputBindingCompositeContext__) to read the current value of the axis.
For example: `Vector2 moveValue = moveAction.ReadValue()`. +[`Input.GetAxisRaw`](https://docs.unity3d.com/ScriptReference/Input.GetAxisRaw.html)|Not directly applicable. You can use [`InputControl<>.ReadUnprocessedValue()`](../api/UnityEngine.InputSystem.InputControl-1.html#UnityEngine_InputSystem_InputControl_1_ReadUnprocessedValue) to read unprocessed values from any control. +[`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)|Use [`InputAction.IsPressed`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_IsPressed_) on the corresponding Gamepad button.
Example: `Input.GetKey(KeyCode.JoystickButton0)` becomes: `InputSystem.GamePad.current.buttonNorth.isPressed`. +[`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)|Use [`InputAction.WasPressedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasPressedThisFrame_) on the corresponding Gamepad button. +[`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)|Use [`InputAction.WasReleasedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasReleasedThisFrame_) on the corresponding Gamepad button. +[`Input.GetJoystickNames`](https://docs.unity3d.com/ScriptReference/Input.GetJoystickNames.html)|There is no API that corresponds to this exactly, but there are examples of [how to read all connected devices here](Gamepad.html#discover-all-connected-devices). +[`Input.IsJoystickPreconfigured`](https://docs.unity3d.com/ScriptReference/Input.IsJoystickPreconfigured.html)|Not needed. Devices which derive from [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) always correctly implement the mapping of axes and buttons to the corresponding [`InputControl`](../api/UnityEngine.InputSystem.InputControl.html) members of the [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) class. [`Input.ResetInputAxes`](https://docs.unity3d.com/ScriptReference/Input.ResetInputAxes.html) + + + + ### Keyboard |Input Manager (Old)|Input System (New)| |--|--| @@ -81,19 +104,9 @@ All of the new APIs listed below are in the `UnityEngine.InputSystem` namespace. [`Input.touchPressureSupported`](https://docs.unity3d.com/ScriptReference/Input-touchPressureSupported.html)|No corresponding API yet. [`Input.touchSupported`](https://docs.unity3d.com/ScriptReference/Input-touchSupported.html)|[`Touchscreen.current != null`](../api/UnityEngine.InputSystem.Touchscreen.html#UnityEngine_InputSystem_Touchscreen_current) [`UnityEngine.TouchScreenKeyboard`](https://docs.unity3d.com/ScriptReference/TouchScreenKeyboard.html)|No corresponding API yet. Use `TouchScreenKeyboard` for now. +[`Input.backButtonLeavesApp`](https://docs.unity3d.com/ScriptReference/Input-backButtonLeavesApp.html)|No corresponding API yet. -### Gamepad and Joystick -|Input Manager (Old)|Input System (New)| -|--|--| -[`Input.GetAxis`](https://docs.unity3d.com/ScriptReference/Input.GetAxis.html)|Set up an action as a 1D or 2D axis in the Actions Editor, then use [`InputAction.ReadValue`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_ReadValue__1) to read the value or 2D vector from the axis. There are some default built-in axis actions. See the [Quickstart Guide](QuickStartGuide.md) to get started quickly. -[`Input.GetAxisRaw`](https://docs.unity3d.com/ScriptReference/Input.GetAxisRaw.html)|Not directly applicable. You can use [`InputControl<>.ReadUnprocessedValue()`](../api/UnityEngine.InputSystem.InputControl-1.html#UnityEngine_InputSystem_InputControl_1_ReadUnprocessedValue) to read unprocessed values from any control. -[`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)|Use [`InputAction.IsPressed`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_IsPressed_) on the corresponding Gamepad button.
Example: `Input.GetKey(KeyCode.JoystickButton0)` becomes: `InputSystem.GamePad.current.buttonNorth.isPressed`. -[`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)|Use [`InputAction.WasPressedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasPressedThisFrame_) on the corresponding Gamepad button. -[`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)|Use [`InputAction.WasReleasedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasReleasedThisFrame_) on the corresponding Gamepad button. -[`Input.GetJoystickNames`](https://docs.unity3d.com/ScriptReference/Input.GetJoystickNames.html)|There is no API that corresponds to this exactly, but there are examples of [how to read all connected devices here](Gamepad.html#discover-all-connected-devices). -[`Input.IsJoystickPreconfigured`](https://docs.unity3d.com/ScriptReference/Input.IsJoystickPreconfigured.html)|Not needed. Devices which derive from [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) always correctly implement the mapping of axes and buttons to the corresponding [`InputControl`](../api/UnityEngine.InputSystem.InputControl.html) members of the [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) class. [`Input.ResetInputAxes`](https://docs.unity3d.com/ScriptReference/Input.ResetInputAxes.html) - ### Sensors |Input Manager (Old)|Input System (New)| |--|--| @@ -112,8 +125,3 @@ All of the new APIs listed below are in the `UnityEngine.InputSystem` namespace. [`Input.gyro.userAcceleration`](https://docs.unity3d.com/ScriptReference/Gyroscope-userAcceleration.html)|[`LinearAccelerationSensor.current.acceleration.acceleration.ReadValue()`](../api/UnityEngine.InputSystem.LinearAccelerationSensor.html) [`Input.location`](https://docs.unity3d.com/ScriptReference/Input-location.html)|No corresponding API yet. [`Input.GetAccelerationEvent`](https://docs.unity3d.com/ScriptReference/Input.GetAccelerationEvent.html)|See notes for `Input.accelerationEvents` above. - -### Actions -|Input Manager (Old)|Input System (New)| -|--|--| -[`Input.backButtonLeavesApp`](https://docs.unity3d.com/ScriptReference/Input-backButtonLeavesApp.html)|No corresponding API yet. From d8f4464fcedc99c54f8d82e2f3769f0d68a047a3 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Tue, 21 May 2024 17:53:55 +0100 Subject: [PATCH 04/18] More WIP on Migration page --- .../Documentation~/Gamepad.md | 4 +-- .../Documentation~/Migration.md | 29 +++++++++++++++---- .../InputSystem/Controls/ButtonControl.cs | 18 +++++------- .../InputSystem/Devices/Keyboard.cs | 2 +- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/Packages/com.unity.inputsystem/Documentation~/Gamepad.md b/Packages/com.unity.inputsystem/Documentation~/Gamepad.md index b64757a79a..ad4acf19cf 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Gamepad.md +++ b/Packages/com.unity.inputsystem/Documentation~/Gamepad.md @@ -199,7 +199,7 @@ The Input System support Switch Pro controllers on desktop computers via the [`S To give gamepads and joysticks control over a hardware or software cursor, you can use the [`VirtualMouseInput`](../api/UnityEngine.InputSystem.UI.VirtualMouseInput.html) component. See [`VirtualMouseInput` component](UISupport.md#virtual-mouse-cursor-control) in the UI section of the manual. -## Discover all connected devices +## Discover all connected devices There are various ways to discover the currently connected devices, as shown in the code samples below. @@ -231,4 +231,4 @@ for (var i = 0; i < devices.Count; ++i) Debug.Log("Found " + device); } } -``` \ No newline at end of file +``` diff --git a/Packages/com.unity.inputsystem/Documentation~/Migration.md b/Packages/com.unity.inputsystem/Documentation~/Migration.md index ba2fefc11c..dd48b30773 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Migration.md +++ b/Packages/com.unity.inputsystem/Documentation~/Migration.md @@ -7,11 +7,12 @@ uid: input-system-migration - [Which system is enabled?](#which-system-is-enabled) - [List of corresponding API in the old Input Manager new Input System package](#list-of-corresponding-api-in-the-old-input-manager-new-input-system-package) - [Action-based input](#action-based-input) + - [Directly reading Gamepad and Joystick controls](#directly-reading-gamepad-and-joystick-controls) - [Keyboard](#keyboard) - [Mouse](#mouse) - [Touch and Pen](#touch-and-pen) - [Sensors](#sensors) - + This page is provided to help you match input-related API from Unity's old, built-in input (known as the [Input Manager](https://docs.unity3d.com/Manual/class-InputManager.html)) to the corresponding API in the new Input System package. ## Read the introductory documentation first @@ -45,7 +46,7 @@ All of the new APIs listed below are in the `UnityEngine.InputSystem` namespace. ### Action-based input -Action-based input refers to reading pre-configured named axes, buttons, or other controls. +Action-based input refers to reading pre-configured named axes, buttons, or other controls. ([Read more about Action-based input](./Workflow-Actions.md)) - In the old Input Manager, these are defined in the **Axes** list, in the **Input Manager** section of the **Project Settings** window. - In the new Input System, these are defined in the [Actions Editor](ActionsEditor.md), which can be found in the **Input System Package** section of the **Project Settings** window, or by opening an [Action Asset](ActionAssets.md). @@ -54,19 +55,37 @@ Action-based input refers to reading pre-configured named axes, buttons, or othe __Note:__ In most cases for named axes and buttons, the new Input System requires slightly more code than the old Input Manager, but this results in better performance. This is because in the new Input System, the logic is separated into two parts: the first is to find and store a reference to the action (usually done once, for example in your `Start` method), and the second is to read the action (usually done every frame, for example in your `Update` method). In contrast, the old Input Manager used a string-based API to "find" and "read" the value at the same time, because it was not possible to store a reference to a button or axis. This results in worse performance, because the axis or button is looked up each time the value is read. +To find and store references to actions, which can be axes or buttons use [`FindAction`](../api/UnityEngine.InputSystem.InputActionAsset.html#UnityEngine_InputSystem_InputActionAsset_FindAction_System_String_System_Boolean_). For example: +``` +InputAction moveAction = InputSystem.actions.FindAction("Move"); // A 2D axis +InputAction jumpAction = InputSystem.actions.FindAction("Jump"); // A button +``` + |Input Manager (Old)|Input System (New)| |--|--| -[`Input.GetAxis`](https://docs.unity3d.com/ScriptReference/Input.GetAxis.html)|Set up an action as a 1D or 2D axis in the Actions Editor, then use [`InputAction.ReadValue`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_ReadValue__1) to read the value or 2D vector from the axis. There are some default built-in axis actions. See the [Quickstart Guide](QuickStartGuide.md) to get started quickly.

Use [`FindAction`](../api/UnityEngine.InputSystem.InputActionAsset.html#UnityEngine_InputSystem_InputActionAsset_FindAction_System_String_System_Boolean_) to find and store a reference to the action.
For example: `InputAction moveAction = InputSystem.actions.FindAction("Move")`.

Use [`ReadValue`](../api/UnityEngine.InputSystem.InputBindingComposite-1.html#UnityEngine_InputSystem_InputBindingComposite_1_ReadValue_UnityEngine_InputSystem_InputBindingCompositeContext__) to read the current value of the axis.
For example: `Vector2 moveValue = moveAction.ReadValue()`. +[`Input.GetAxis`](https://docs.unity3d.com/ScriptReference/Input.GetAxis.html)

For example, to read the horizontal and vertical axes:
`float h = Input.GetAxis("Horizontal");`
`float v = Input.GetAxis("Vertical");`

| Use [`ReadValue`](../api/UnityEngine.InputSystem.InputBindingComposite-1.html#UnityEngine_InputSystem_InputBindingComposite_1_ReadValue_UnityEngine_InputSystem_InputBindingCompositeContext__) on the reference to the action to read the current value of the axis.
Example: `Vector2 moveVector = moveAction.ReadValue()`. +[`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)
Example: `bool jump = Input.GetButton("Jump");`|Use [`IsPressed`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_IsPressed_) on the reference to the action to read the button value.
Example: `bool jumpValue = jumpAction.IsPressed()`.

+[`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)
Example: `bool jump = Input.GetButtonDown("Jump");`

|Use [`WasPressedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasPressedThisFrame_) on the reference to the action to read if the button was pressed this frame.
Example: `bool jumpValue = jumpAction.WasPressedThisFrame()`.

+[`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)
Example: `bool jump = Input.GetButtonUp("Jump");`

|Use [`WasReleasedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasReleasedThisFrame_) on the reference to the action to read whether the button was released this frame.
Example: `bool jumpValue = jumpAction.WasReleasedThisFrame()`.

[`Input.GetAxisRaw`](https://docs.unity3d.com/ScriptReference/Input.GetAxisRaw.html)|Not directly applicable. You can use [`InputControl<>.ReadUnprocessedValue()`](../api/UnityEngine.InputSystem.InputControl-1.html#UnityEngine_InputSystem_InputControl_1_ReadUnprocessedValue) to read unprocessed values from any control. + + + +### Directly reading Gamepad and Joystick controls + +Directly reading hardware controls bypasses the new Input System's action-based workflow, which has some benefits and some drawbacks. ([Read more about directly reading devices](./Workflow-Direct.md)) + + +|Input Manager (Old)|Input System (New)| +|--|--| [`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)|Use [`InputAction.IsPressed`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_IsPressed_) on the corresponding Gamepad button.
Example: `Input.GetKey(KeyCode.JoystickButton0)` becomes: `InputSystem.GamePad.current.buttonNorth.isPressed`. [`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)|Use [`InputAction.WasPressedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasPressedThisFrame_) on the corresponding Gamepad button. [`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)|Use [`InputAction.WasReleasedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasReleasedThisFrame_) on the corresponding Gamepad button. -[`Input.GetJoystickNames`](https://docs.unity3d.com/ScriptReference/Input.GetJoystickNames.html)|There is no API that corresponds to this exactly, but there are examples of [how to read all connected devices here](Gamepad.html#discover-all-connected-devices). +[`Input.GetJoystickNames`](https://docs.unity3d.com/ScriptReference/Input.GetJoystickNames.html)|There is no API that corresponds to this exactly, but there are examples of [how to read all connected devices here](Gamepad.html#discover-all-connected-devices). [`Input.IsJoystickPreconfigured`](https://docs.unity3d.com/ScriptReference/Input.IsJoystickPreconfigured.html)|Not needed. Devices which derive from [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) always correctly implement the mapping of axes and buttons to the corresponding [`InputControl`](../api/UnityEngine.InputSystem.InputControl.html) members of the [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) class. [`Input.ResetInputAxes`](https://docs.unity3d.com/ScriptReference/Input.ResetInputAxes.html) - ### Keyboard |Input Manager (Old)|Input System (New)| |--|--| diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs index 37655660fc..76e9851e77 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs @@ -89,35 +89,31 @@ public ButtonControl() /// /// A button is considered pressed if its value is equal to or greater /// than its button press threshold (). - /// - /// /// You can use this to read whether specific keys are currently pressed by using isPressed on keys, as shown in the following examples: /// /// /// // Using KeyControl property directly. /// Keyboard.current.spaceKey.isPressed /// Keyboard.current.aKey.isPressed // etc. - /// + /// /// // Using Key enum. /// Keyboard.current[Key.Space].isPressed - /// + /// /// // Using key name. /// (KeyControl)Keyboard.current["space"]).isPressed /// /// /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . - /// /// You can also use this to read mouse buttons, as shown in the following examples: - /// /// /// /// Mouse.current.leftButton.isPressed /// Mouse.current.rightButton.isPressed /// Mouse.current.middleButton.isPressed - /// + /// /// // You can also go through all buttons on the mouse (does not allocate). /// var controls = Mouse.current.allControls; - /// for (var i = 0; i < controls.Count; ++i) + /// for (var i = 0; i < controls.Count; ++i) /// { /// var button = controls[i] as ButtonControl; /// if (button != null && button.isPressed) @@ -128,7 +124,7 @@ public ButtonControl() /// /// // Or look up controls by name. /// ((ButtonControl)Mouse.current["leftButton"]).isPressed - /// + /// /// /// /// @@ -160,9 +156,9 @@ public ButtonControl() /// /// /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . - /// + /// /// You can also use this property to read mouse buttons. For example: - /// + /// /// /// /// Mouse.current.leftButton.wasPressedThisFrame diff --git a/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs b/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs index 122d3485ef..86da29dcc6 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs @@ -980,7 +980,7 @@ public event Action onTextInput /// }; /// /// - /// + /// /// See for turning IME on/off /// public event Action onIMECompositionChange From 8908df2e3dade953d1b3808eb1a9474d6e2f3a97 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Wed, 22 May 2024 15:52:06 +0100 Subject: [PATCH 05/18] Migration page improvements WIP --- .../Documentation~/Migration.md | 49 ++++++++++--------- .../Documentation~/TableOfContents.md | 2 +- .../InputSystem/Controls/ButtonControl.cs | 36 +++++++++----- 3 files changed, 53 insertions(+), 34 deletions(-) diff --git a/Packages/com.unity.inputsystem/Documentation~/Migration.md b/Packages/com.unity.inputsystem/Documentation~/Migration.md index dd48b30773..82354150a2 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Migration.md +++ b/Packages/com.unity.inputsystem/Documentation~/Migration.md @@ -19,7 +19,7 @@ This page is provided to help you match input-related API from Unity's old, buil If you're new to the Input System package and have landed on this page looking for documentation, it's best to read the [QuickStart Guide](QuickStartGuide.md), and the [Concepts](Concepts.md) and [Workflows](Workflows.md) pages from the introduction section of the documentation, so that you can make sure you're choosing the best workflow for your project's input requirements. -This is because there are a number of different ways to read input using the Input System, and many of the directly corresponding API methods on this page might give you the quickest but least flexible solution, and may not be suitable for a project with more complex requirements. +This is because there are a number of different ways to read input using the Input System, and some of the directly corresponding API methods on this page might give you the quickest - but least flexible - solution, and may not be suitable for a project with more complex requirements. ## Which system is enabled? @@ -48,23 +48,28 @@ All of the new APIs listed below are in the `UnityEngine.InputSystem` namespace. Action-based input refers to reading pre-configured named axes, buttons, or other controls. ([Read more about Action-based input](./Workflow-Actions.md)) -- In the old Input Manager, these are defined in the **Axes** list, in the **Input Manager** section of the **Project Settings** window. -- In the new Input System, these are defined in the [Actions Editor](ActionsEditor.md), which can be found in the **Input System Package** section of the **Project Settings** window, or by opening an [Action Asset](ActionAssets.md). +- In the old Input Manager, these are defined in the **Axes** list, in the **Input Manager** section of the **Project Settings** window. _(Below, left)_ +- In the new Input System, these are defined in the [Actions Editor](ActionsEditor.md), which can be found in the **Input System Package** section of the **Project Settings** window, or by opening an [Action Asset](ActionAssets.md). _(Below, right)_ ![](Images/InputManagerVsInputActions.png)
_On the left, the old Input Manager Axes Configuration window, in Project settings. On the right, the new Input System's [Actions Editor](ActionsEditor.md)._ -__Note:__ In most cases for named axes and buttons, the new Input System requires slightly more code than the old Input Manager, but this results in better performance. This is because in the new Input System, the logic is separated into two parts: the first is to find and store a reference to the action (usually done once, for example in your `Start` method), and the second is to read the action (usually done every frame, for example in your `Update` method). In contrast, the old Input Manager used a string-based API to "find" and "read" the value at the same time, because it was not possible to store a reference to a button or axis. This results in worse performance, because the axis or button is looked up each time the value is read. +__Note:__ In some cases for named axes and buttons, the new Input System requires slightly more code than the old Input Manager, but this results in better performance. This is because in the new Input System, the logic is separated into two parts: the first is to find and store a reference to the action (usually done once, for example in your `Start` method), and the second is to read the action (usually done every frame, for example in your `Update` method). In contrast, the old Input Manager used a string-based API to "find" and "read" the value at the same time, because it was not possible to store a reference to a button or axis. This results in worse performance, because the axis or button is looked up each time the value is read. To find and store references to actions, which can be axes or buttons use [`FindAction`](../api/UnityEngine.InputSystem.InputActionAsset.html#UnityEngine_InputSystem_InputActionAsset_FindAction_System_String_System_Boolean_). For example: ``` -InputAction moveAction = InputSystem.actions.FindAction("Move"); // A 2D axis -InputAction jumpAction = InputSystem.actions.FindAction("Jump"); // A button + // A 2D axis action named "Move" +InputAction moveAction = InputSystem.actions.FindAction("Move"); + + // A button action named "Jump" +InputAction jumpAction = InputSystem.actions.FindAction("Jump"); ``` +Then, to read the action values, use the following: + |Input Manager (Old)|Input System (New)| |--|--| -[`Input.GetAxis`](https://docs.unity3d.com/ScriptReference/Input.GetAxis.html)

For example, to read the horizontal and vertical axes:
`float h = Input.GetAxis("Horizontal");`
`float v = Input.GetAxis("Vertical");`

| Use [`ReadValue`](../api/UnityEngine.InputSystem.InputBindingComposite-1.html#UnityEngine_InputSystem_InputBindingComposite_1_ReadValue_UnityEngine_InputSystem_InputBindingCompositeContext__) on the reference to the action to read the current value of the axis.
Example: `Vector2 moveVector = moveAction.ReadValue()`. -[`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)
Example: `bool jump = Input.GetButton("Jump");`|Use [`IsPressed`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_IsPressed_) on the reference to the action to read the button value.
Example: `bool jumpValue = jumpAction.IsPressed()`.

+[`Input.GetAxis`](https://docs.unity3d.com/ScriptReference/Input.GetAxis.html)
In the old Input Manager System, all axes are 1D and return float values. For example, to read the horizontal and vertical axes:
`float h = Input.GetAxis("Horizontal");`
`float v = Input.GetAxis("Vertical");`

| Use [`ReadValue`](../api/UnityEngine.InputSystem.InputBindingComposite-1.html#UnityEngine_InputSystem_InputBindingComposite_1_ReadValue_UnityEngine_InputSystem_InputBindingCompositeContext__) on the reference to the action to read the current value of the axis. In the new Input System, axes can be 1D, 2D or other value types. You must specify the correct value type that corresponds with how the action is set up. This example shows a 2D axis:
`Vector2 moveVector = moveAction.ReadValue()`.

+[`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)
Example:
`bool jumpValue = Input.GetButton("Jump");`

|Use [`IsPressed`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_IsPressed_) on the reference to the action to read the button value.
Example:
`bool jumpValue = jumpAction.IsPressed()`.

[`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)
Example: `bool jump = Input.GetButtonDown("Jump");`

|Use [`WasPressedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasPressedThisFrame_) on the reference to the action to read if the button was pressed this frame.
Example: `bool jumpValue = jumpAction.WasPressedThisFrame()`.

[`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)
Example: `bool jump = Input.GetButtonUp("Jump");`

|Use [`WasReleasedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasReleasedThisFrame_) on the reference to the action to read whether the button was released this frame.
Example: `bool jumpValue = jumpAction.WasReleasedThisFrame()`.

[`Input.GetAxisRaw`](https://docs.unity3d.com/ScriptReference/Input.GetAxisRaw.html)|Not directly applicable. You can use [`InputControl<>.ReadUnprocessedValue()`](../api/UnityEngine.InputSystem.InputControl-1.html#UnityEngine_InputSystem_InputControl_1_ReadUnprocessedValue) to read unprocessed values from any control. @@ -78,9 +83,9 @@ Directly reading hardware controls bypasses the new Input System's action-based |Input Manager (Old)|Input System (New)| |--|--| -[`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)|Use [`InputAction.IsPressed`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_IsPressed_) on the corresponding Gamepad button.
Example: `Input.GetKey(KeyCode.JoystickButton0)` becomes: `InputSystem.GamePad.current.buttonNorth.isPressed`. -[`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)|Use [`InputAction.WasPressedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasPressedThisFrame_) on the corresponding Gamepad button. -[`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)|Use [`InputAction.WasReleasedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasReleasedThisFrame_) on the corresponding Gamepad button. +[`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)
Example: `Input.GetKey(KeyCode.JoystickButton0)`

|Use [`isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding Gamepad button.
Example: `InputSystem.GamePad.current.buttonNorth.isPressed`.
+[`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)
Example: `Input.GetGetButtonDownKey(KeyCode.JoystickButton0)`

|Use [`wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding Gamepad button.
Example: `InputSystem.GamePad.current.buttonNorth.WasPressedThisFrame`.
+[`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)
Example: `Input.GetButtonUp(KeyCode.JoystickButton0)`

|Use [`wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding Gamepad button.
Example: `InputSystem.GamePad.current.buttonNorth.wasReleasedThisFrame`.
[`Input.GetJoystickNames`](https://docs.unity3d.com/ScriptReference/Input.GetJoystickNames.html)|There is no API that corresponds to this exactly, but there are examples of [how to read all connected devices here](Gamepad.html#discover-all-connected-devices). [`Input.IsJoystickPreconfigured`](https://docs.unity3d.com/ScriptReference/Input.IsJoystickPreconfigured.html)|Not needed. Devices which derive from [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) always correctly implement the mapping of axes and buttons to the corresponding [`InputControl`](../api/UnityEngine.InputSystem.InputControl.html) members of the [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) class. [`Input.ResetInputAxes`](https://docs.unity3d.com/ScriptReference/Input.ResetInputAxes.html) @@ -89,12 +94,12 @@ Directly reading hardware controls bypasses the new Input System's action-based ### Keyboard |Input Manager (Old)|Input System (New)| |--|--| -[`Input.GetKey`](https://docs.unity3d.com/ScriptReference/Input.GetKey.html)|Use [`ButtonControl.isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding key.
Example: `Input.GetKey(KeyCode.Space)` becomes: `InputSystem.Keyboard.current.spaceKey.isPressed` -[`Input.GetKeyDown`](https://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html)|Use [`ButtonControl.wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding key. -[`Input.GetKeyUp`](https://docs.unity3d.com/ScriptReference/Input.GetKeyUp.html)|Use [`ButtonControl.wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding key. -[`Input.anyKey`](https://docs.unity3d.com/ScriptReference/Input-anyKey.html)|[`onAnyButtonPress`](../api/UnityEngine.InputSystem.InputSystem.html#UnityEngine_InputSystem_InputSystem_onAnyButtonPress)
-[`Input.anyKeyDown`](https://docs.unity3d.com/ScriptReference/Input-anyKeyDown.html)|[`Keyboard.current.anyKey.wasUpdatedThisFrame`](../api/UnityEngine.InputSystem.Keyboard.html) -[`Input.compositionCursorPos`](https://docs.unity3d.com/ScriptReference/Input-compositionCursorPos.html)|[`Keyboard.current.SetIMECursorPosition(myPosition)`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_SetIMECursorPosition_UnityEngine_Vector2_) +[`Input.GetKey`](https://docs.unity3d.com/ScriptReference/Input.GetKey.html)
Example: `Input.GetKey(KeyCode.Space)`

|Use [`isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding key.
Example: `InputSystem.Keyboard.current.spaceKey.isPressed`

+[`Input.GetKeyDown`](https://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html)
Example: `Input.GetKeyDown(KeyCode.Space)`

|Use [`wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding key.
Example: `InputSystem.Keyboard.current.spaceKey.wasPressedThisFrame`

+[`Input.GetKeyUp`](https://docs.unity3d.com/ScriptReference/Input.GetKeyUp.html)
Example: `Input.GetKeyUp(KeyCode.Space)`

|Use [`wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding key.
Example: `InputSystem.Keyboard.current.spaceKey.wasReleasedThisFrame`

+[`Input.anyKey`](https://docs.unity3d.com/ScriptReference/Input-anyKey.html)|Use [`onAnyButtonPress`](../api/UnityEngine.InputSystem.InputSystem.html#UnityEngine_InputSystem_InputSystem_onAnyButtonPress).
This also includes controller buttons as well as keyboard keys. +[`Input.anyKeyDown`](https://docs.unity3d.com/ScriptReference/Input-anyKeyDown.html)|Use [`Keyboard.current.anyKey.wasUpdatedThisFrame`](../api/UnityEngine.InputSystem.Keyboard.html) +[`Input.compositionCursorPos`](https://docs.unity3d.com/ScriptReference/Input-compositionCursorPos.html)|Use [`Keyboard.current.SetIMECursorPosition(myPosition)`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_SetIMECursorPosition_UnityEngine_Vector2_) [`Input.compositionString`](https://docs.unity3d.com/ScriptReference/Input-compositionString.html)|Subscribe to the [`Keyboard.onIMECompositionChange`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_onIMECompositionChange). [`Input.imeCompositionMode`](https://docs.unity3d.com/ScriptReference/Input-imeCompositionMode.html)|No corresponding API yet. [`Input.imeIsSelected`](https://docs.unity3d.com/ScriptReference/Input-imeIsSelected.html)|Get: `Keyboard.current.imeSelected`
Set: `Keyboard.current.SetIMEEnabled(true);` @@ -103,11 +108,11 @@ Directly reading hardware controls bypasses the new Input System's action-based ### Mouse |Input Manager (Old)|Input System (New)| |--|--| -[`Input.GetMouseButton`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButton.html)|Use [`ButtonControl.isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding mouse button.
Example: `Input.GetKey(KeyCode.Mouse0)` becomes: `InputSystem.Mouse.current.leftButton.isPressed` -[`Input.GetMouseButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButtonDown.html)|Use [`ButtonControl.wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding mouse button. -[`Input.GetMouseButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButtonUp.html)|Use [`ButtonControl.wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding mouse button. -[`Input.mousePosition`](https://docs.unity3d.com/ScriptReference/Input-mousePosition.html)|[`Mouse.current.position.ReadValue()`](../api/UnityEngine.InputSystem.Mouse.html)
__Note__: Mouse simulation from touch isn't implemented yet. -[`Input.mousePresent`](https://docs.unity3d.com/ScriptReference/Input-mousePresent.html)|[`Mouse.current != null`](../api/UnityEngine.InputSystem.Mouse.html#UnityEngine_InputSystem_Mouse_current). +[`Input.GetMouseButton`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButton.html)
Example: `Input.GetMouseButton(0)`|Use [`isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding mouse button.
Example: `InputSystem.Mouse.current.leftButton.isPressed` +[`Input.GetMouseButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButtonDown.html)
Example: `Input.GetMouseButtonDown(0)`|Use [`wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding mouse button.
Example: `InputSystem.Mouse.current.leftButton.wasPressedThisFrame` +[`Input.GetMouseButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButtonUp.html)
Example: `Input.GetMouseButtonUp(0)`|Use [`wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding mouse button.
Example: `InputSystem.Mouse.current.leftButton.wasReleasedThisFrame` +[`Input.mousePosition`](https://docs.unity3d.com/ScriptReference/Input-mousePosition.html)|Use [`Mouse.current.position.ReadValue()`](../api/UnityEngine.InputSystem.Mouse.html)
__Note__: Mouse simulation from touch isn't implemented yet. +[`Input.mousePresent`](https://docs.unity3d.com/ScriptReference/Input-mousePresent.html)|Use [`Mouse.current != null`](../api/UnityEngine.InputSystem.Mouse.html#UnityEngine_InputSystem_Mouse_current). ### Touch and Pen diff --git a/Packages/com.unity.inputsystem/Documentation~/TableOfContents.md b/Packages/com.unity.inputsystem/Documentation~/TableOfContents.md index b292f2c1b0..305e0dfa9f 100644 --- a/Packages/com.unity.inputsystem/Documentation~/TableOfContents.md +++ b/Packages/com.unity.inputsystem/Documentation~/TableOfContents.md @@ -43,6 +43,6 @@ * [Input testing](Testing.md) * [How do I...?](HowDoI.md) * [Architecture](Architecture.md) -* [Migrating from the old input system](Migration.md) +* [Migrating from the old Input Manager](Migration.md) * [Contributing](Contributing.md) * [Known Limitations](KnownLimitations.md) diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs index 76e9851e77..c625669408 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs @@ -103,17 +103,25 @@ public ButtonControl() /// (KeyControl)Keyboard.current["space"]).isPressed /// /// - /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . + /// Note: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . + /// /// You can also use this to read mouse buttons, as shown in the following examples: /// /// - /// Mouse.current.leftButton.isPressed - /// Mouse.current.rightButton.isPressed - /// Mouse.current.middleButton.isPressed - /// - /// // You can also go through all buttons on the mouse (does not allocate). + /// + /// + /// + /// + /// You can also check through all numbered buttons on the mouse: (this example does not cause allocations) + /// + /// + /// + /// + /// + /// + /// Or you can look up controls by name, like this: + /// + /// + /// /// /// /// From 0d21a110c0064ed55c1c15ba875afb6e58ca5a86 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Wed, 29 May 2024 17:30:13 +0100 Subject: [PATCH 06/18] Amendments from PR review comments --- .../Documentation~/Migration.md | 28 +++++++++---------- .../InputSystem/Controls/ButtonControl.cs | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Packages/com.unity.inputsystem/Documentation~/Migration.md b/Packages/com.unity.inputsystem/Documentation~/Migration.md index 82354150a2..0eeb47cae1 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Migration.md +++ b/Packages/com.unity.inputsystem/Documentation~/Migration.md @@ -5,7 +5,7 @@ uid: input-system-migration - [Read the introductory documentation first](#read-the-introductory-documentation-first) - [Which system is enabled?](#which-system-is-enabled) -- [List of corresponding API in the old Input Manager new Input System package](#list-of-corresponding-api-in-the-old-input-manager-new-input-system-package) +- [Comparison of API in the old Input Manager and the new Input System package](#comparison-of-api-in-the-old-input-manager-and-the-new-input-system-package) - [Action-based input](#action-based-input) - [Directly reading Gamepad and Joystick controls](#directly-reading-gamepad-and-joystick-controls) - [Keyboard](#keyboard) @@ -39,10 +39,10 @@ There are scripting symbols defined which allow you to use conditional compilati > **Note:** It is possible to have both systems enabled at the same time, in which case both sets of code in the example above above will be active. -## List of corresponding API in the old Input Manager new Input System package - -All of the new APIs listed below are in the `UnityEngine.InputSystem` namespace. The namespace is omitted here for brevity. `UnityEngine.InputSystem` is referenced in full for easy disambiguation. +## Comparison of API in the old Input Manager and the new Input System package +Below is a list comparing the API from the old Input Manager with the corresponding API for the new Input System package. +All of the new Input System package APIs listed below are in the `UnityEngine.InputSystem` namespace. The namespace is omitted here for brevity. ### Action-based input @@ -68,11 +68,11 @@ Then, to read the action values, use the following: |Input Manager (Old)|Input System (New)| |--|--| -[`Input.GetAxis`](https://docs.unity3d.com/ScriptReference/Input.GetAxis.html)
In the old Input Manager System, all axes are 1D and return float values. For example, to read the horizontal and vertical axes:
`float h = Input.GetAxis("Horizontal");`
`float v = Input.GetAxis("Vertical");`

| Use [`ReadValue`](../api/UnityEngine.InputSystem.InputBindingComposite-1.html#UnityEngine_InputSystem_InputBindingComposite_1_ReadValue_UnityEngine_InputSystem_InputBindingCompositeContext__) on the reference to the action to read the current value of the axis. In the new Input System, axes can be 1D, 2D or other value types. You must specify the correct value type that corresponds with how the action is set up. This example shows a 2D axis:
`Vector2 moveVector = moveAction.ReadValue()`.

-[`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)
Example:
`bool jumpValue = Input.GetButton("Jump");`

|Use [`IsPressed`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_IsPressed_) on the reference to the action to read the button value.
Example:
`bool jumpValue = jumpAction.IsPressed()`.

-[`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)
Example: `bool jump = Input.GetButtonDown("Jump");`

|Use [`WasPressedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasPressedThisFrame_) on the reference to the action to read if the button was pressed this frame.
Example: `bool jumpValue = jumpAction.WasPressedThisFrame()`.

-[`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)
Example: `bool jump = Input.GetButtonUp("Jump");`

|Use [`WasReleasedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasReleasedThisFrame_) on the reference to the action to read whether the button was released this frame.
Example: `bool jumpValue = jumpAction.WasReleasedThisFrame()`.

-[`Input.GetAxisRaw`](https://docs.unity3d.com/ScriptReference/Input.GetAxisRaw.html)|Not directly applicable. You can use [`InputControl<>.ReadUnprocessedValue()`](../api/UnityEngine.InputSystem.InputControl-1.html#UnityEngine_InputSystem_InputControl_1_ReadUnprocessedValue) to read unprocessed values from any control. +[`Input.GetAxis`](https://docs.unity3d.com/ScriptReference/Input.GetAxis.html)
In the old Input Manager System, all axes are 1D and return float values. For example, to read the horizontal and vertical axes:
`float h = Input.GetAxis("Horizontal");`
`float v = Input.GetAxis("Vertical");`

| Use [`ReadValue`](../api/UnityEngine.InputSystem.InputBindingComposite-1.html#UnityEngine_InputSystem_InputBindingComposite_1_ReadValue_UnityEngine_InputSystem_InputBindingCompositeContext__) on the reference to the action to read the current value of the axis. In the new Input System, axes can be 1D, 2D or other value types. You must specify the correct value type that corresponds with how the action is set up. This example shows a 2D axis:
`Vector2 moveVector = moveAction.ReadValue();`.

+[`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)
Example:
`bool jumpValue = Input.GetButton("Jump");`

|Use [`IsPressed`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_IsPressed_) on the reference to the action to read the button value.
Example:
`bool jumpValue = jumpAction.IsPressed();`.

+[`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)
Example: `bool jump = Input.GetButtonDown("Jump");`

|Use [`WasPressedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasPressedThisFrame_) on the reference to the action to read if the button was pressed this frame.
Example: `bool jumpValue = jumpAction.WasPressedThisFrame();`.

+[`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)
Example: `bool jump = Input.GetButtonUp("Jump");`

|Use [`WasReleasedThisFrame`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_WasReleasedThisFrame_) on the reference to the action to read whether the button was released this frame.
Example: `bool jumpValue = jumpAction.WasReleasedThisFrame();`.

+[`Input.GetAxisRaw`](https://docs.unity3d.com/ScriptReference/Input.GetAxisRaw.html)
For example, to read the raw values of the horizontal and vertical axes:
`float h = Input.GetAxisRaw("Horizontal");`
`float v = Input.GetAxisRaw("Vertical");`

|No direct equivalent, but if there are [processors](Processors.md) associated with the action, you can use [`InputControl<>.ReadUnprocessedValue()`](../api/UnityEngine.InputSystem.InputControl-1.html#UnityEngine_InputSystem_InputControl_1_ReadUnprocessedValue) to read unprocessed values.
Example: `Vector2 moveVector = moveAction.ReadUnprocessedValue();`
Note: This returns the same value as ReadValue when there are no processors on the action. @@ -98,7 +98,7 @@ Directly reading hardware controls bypasses the new Input System's action-based [`Input.GetKeyDown`](https://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html)
Example: `Input.GetKeyDown(KeyCode.Space)`

|Use [`wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding key.
Example: `InputSystem.Keyboard.current.spaceKey.wasPressedThisFrame`

[`Input.GetKeyUp`](https://docs.unity3d.com/ScriptReference/Input.GetKeyUp.html)
Example: `Input.GetKeyUp(KeyCode.Space)`

|Use [`wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding key.
Example: `InputSystem.Keyboard.current.spaceKey.wasReleasedThisFrame`

[`Input.anyKey`](https://docs.unity3d.com/ScriptReference/Input-anyKey.html)|Use [`onAnyButtonPress`](../api/UnityEngine.InputSystem.InputSystem.html#UnityEngine_InputSystem_InputSystem_onAnyButtonPress).
This also includes controller buttons as well as keyboard keys. -[`Input.anyKeyDown`](https://docs.unity3d.com/ScriptReference/Input-anyKeyDown.html)|Use [`Keyboard.current.anyKey.wasUpdatedThisFrame`](../api/UnityEngine.InputSystem.Keyboard.html) +[`Input.anyKeyDown`](https://docs.unity3d.com/ScriptReference/Input-anyKeyDown.html)|Use [`Keyboard.current.anyKey.wasUpdatedThisFrame`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_anyKey) [`Input.compositionCursorPos`](https://docs.unity3d.com/ScriptReference/Input-compositionCursorPos.html)|Use [`Keyboard.current.SetIMECursorPosition(myPosition)`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_SetIMECursorPosition_UnityEngine_Vector2_) [`Input.compositionString`](https://docs.unity3d.com/ScriptReference/Input-compositionString.html)|Subscribe to the [`Keyboard.onIMECompositionChange`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_onIMECompositionChange). [`Input.imeCompositionMode`](https://docs.unity3d.com/ScriptReference/Input-imeCompositionMode.html)|No corresponding API yet. @@ -111,15 +111,15 @@ Directly reading hardware controls bypasses the new Input System's action-based [`Input.GetMouseButton`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButton.html)
Example: `Input.GetMouseButton(0)`|Use [`isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding mouse button.
Example: `InputSystem.Mouse.current.leftButton.isPressed` [`Input.GetMouseButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButtonDown.html)
Example: `Input.GetMouseButtonDown(0)`|Use [`wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding mouse button.
Example: `InputSystem.Mouse.current.leftButton.wasPressedThisFrame` [`Input.GetMouseButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButtonUp.html)
Example: `Input.GetMouseButtonUp(0)`|Use [`wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding mouse button.
Example: `InputSystem.Mouse.current.leftButton.wasReleasedThisFrame` -[`Input.mousePosition`](https://docs.unity3d.com/ScriptReference/Input-mousePosition.html)|Use [`Mouse.current.position.ReadValue()`](../api/UnityEngine.InputSystem.Mouse.html)
__Note__: Mouse simulation from touch isn't implemented yet. -[`Input.mousePresent`](https://docs.unity3d.com/ScriptReference/Input-mousePresent.html)|Use [`Mouse.current != null`](../api/UnityEngine.InputSystem.Mouse.html#UnityEngine_InputSystem_Mouse_current). +[`Input.mousePosition`](https://docs.unity3d.com/ScriptReference/Input-mousePosition.html)|Use [`Mouse.current.position.ReadValue()`](../api/UnityEngine.InputSystem.Mouse.html)
Example: `Vector2 position = Mouse.current.position.ReadValue();`
__Note__: Mouse simulation from touch isn't implemented yet. +[`Input.mousePresent`](https://docs.unity3d.com/ScriptReference/Input-mousePresent.html)|Check whether [`Mouse.current`](../api/UnityEngine.InputSystem.Mouse.html#UnityEngine_InputSystem_Mouse_current) is null.
Example: `bool isMousePresent = Mouse.current != null;` ### Touch and Pen |Input Manager (Old)|Input System (New)| |--|--| -[`Input.GetTouch`](https://docs.unity3d.com/ScriptReference/Input.GetTouch.html)|Use [`EnhancedTouch.Touch.activeTouches[i]`](../api/UnityEngine.InputSystem.EnhancedTouch.Touch.html#UnityEngine_InputSystem_EnhancedTouch_Touch_activeTouches)
__Note__: Enable enhanced touch support first by calling [`EnhancedTouch.Enable()`](../api/UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.html#UnityEngine_InputSystem_EnhancedTouch_EnhancedTouchSupport_Enable). +[`Input.GetTouch`](https://docs.unity3d.com/ScriptReference/Input.GetTouch.html)
For example:
`Touch touch = Input.GetTouch(0);`
`Vector2 touchPos = touch.position;`|Use [`EnhancedTouch.Touch.activeTouches[i]`](../api/UnityEngine.InputSystem.EnhancedTouch.Touch.html#UnityEngine_InputSystem_EnhancedTouch_Touch_activeTouches)
Example: `Vector2 touchPos = EnhancedTouch.Touch.activeTouches[0].position;`
__Note__: Enable enhanced touch support first by calling [`EnhancedTouch.Enable()`](../api/UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.html#UnityEngine_InputSystem_EnhancedTouch_EnhancedTouchSupport_Enable). [`Input.multiTouchEnabled`](https://docs.unity3d.com/ScriptReference/Input-multiTouchEnabled.html)|No corresponding API yet. [`Input.simulateMouseWithTouches`](https://docs.unity3d.com/ScriptReference/Input-multiTouchEnabled.html)|No corresponding API yet. [`Input.stylusTouchSupported`](https://docs.unity3d.com/ScriptReference/Input-stylusTouchSupported.html)|No corresponding API yet. @@ -127,9 +127,9 @@ Directly reading hardware controls bypasses the new Input System's action-based [`Input.touches`](https://docs.unity3d.com/ScriptReference/Input-touches.html)|[`EnhancedTouch.Touch.activeTouches`](../api/UnityEngine.InputSystem.EnhancedTouch.Touch.html#UnityEngine_InputSystem_EnhancedTouch_Touch_activeTouches)
__Note__: Enable enhanced touch support first by calling [`EnhancedTouch.Enable()`](../api/UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.html#UnityEngine_InputSystem_EnhancedTouch_EnhancedTouchSupport_Enable) [`Input.touchPressureSupported`](https://docs.unity3d.com/ScriptReference/Input-touchPressureSupported.html)|No corresponding API yet. [`Input.touchSupported`](https://docs.unity3d.com/ScriptReference/Input-touchSupported.html)|[`Touchscreen.current != null`](../api/UnityEngine.InputSystem.Touchscreen.html#UnityEngine_InputSystem_Touchscreen_current) -[`UnityEngine.TouchScreenKeyboard`](https://docs.unity3d.com/ScriptReference/TouchScreenKeyboard.html)|No corresponding API yet. Use `TouchScreenKeyboard` for now. [`Input.backButtonLeavesApp`](https://docs.unity3d.com/ScriptReference/Input-backButtonLeavesApp.html)|No corresponding API yet. +Note: [`UnityEngine.TouchScreenKeyboard`](https://docs.unity3d.com/ScriptReference/TouchScreenKeyboard.html) is not part of the old Input Manager, so you can continue to use it when migrating to the new Input System package. ### Sensors |Input Manager (Old)|Input System (New)| diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs index c625669408..2902084812 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs @@ -100,7 +100,7 @@ public ButtonControl() /// Keyboard.current[Key.Space].isPressed /// /// // Using key name. - /// (KeyControl)Keyboard.current["space"]).isPressed + /// ((KeyControl)Keyboard.current["space"]).isPressed /// /// /// Note: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . From c35ae06a7d1576a8a000feff2a42558e01b749c5 Mon Sep 17 00:00:00 2001 From: Lyndon Homewood <33493311+lyndon-unity@users.noreply.github.com> Date: Thu, 27 Jun 2024 09:47:08 +0100 Subject: [PATCH 07/18] Update Migration.md Corrected GetKey/GetButton mismatch in the joysticks section (GetButton is analogous to 'actions' and GetKey is analogous to direct device access) --- Packages/com.unity.inputsystem/Documentation~/Migration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.inputsystem/Documentation~/Migration.md b/Packages/com.unity.inputsystem/Documentation~/Migration.md index 0eeb47cae1..3a3ac1040a 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Migration.md +++ b/Packages/com.unity.inputsystem/Documentation~/Migration.md @@ -83,9 +83,9 @@ Directly reading hardware controls bypasses the new Input System's action-based |Input Manager (Old)|Input System (New)| |--|--| -[`Input.GetButton`](https://docs.unity3d.com/ScriptReference/Input.GetButton.html)
Example: `Input.GetKey(KeyCode.JoystickButton0)`

|Use [`isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding Gamepad button.
Example: `InputSystem.GamePad.current.buttonNorth.isPressed`.
-[`Input.GetButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetButtonDown.html)
Example: `Input.GetGetButtonDownKey(KeyCode.JoystickButton0)`

|Use [`wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding Gamepad button.
Example: `InputSystem.GamePad.current.buttonNorth.WasPressedThisFrame`.
-[`Input.GetButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetButtonUp.html)
Example: `Input.GetButtonUp(KeyCode.JoystickButton0)`

|Use [`wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding Gamepad button.
Example: `InputSystem.GamePad.current.buttonNorth.wasReleasedThisFrame`.
+[`Input.GetKey`](https://docs.unity3d.com/ScriptReference/Input.GetKey.html)
Example: `Input.GetKey(KeyCode.JoystickButton0)`

|Use [`isPressed`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_isPressed) on the corresponding Gamepad button.
Example: `InputSystem.GamePad.current.buttonNorth.isPressed`.
+[`Input.GetKeyDown`](https://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html)
Example: `Input.GetKeyDown(KeyCode.JoystickButton0)`

|Use [`wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding Gamepad button.
Example: `InputSystem.GamePad.current.buttonNorth.WasPressedThisFrame`.
+[`Input.GetKeyUp`](https://docs.unity3d.com/ScriptReference/Input.GetKeyUp.html)
Example: `Input.GetKeyUp(KeyCode.JoystickButton0)`

|Use [`wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding Gamepad button.
Example: `InputSystem.GamePad.current.buttonNorth.wasReleasedThisFrame`.
[`Input.GetJoystickNames`](https://docs.unity3d.com/ScriptReference/Input.GetJoystickNames.html)|There is no API that corresponds to this exactly, but there are examples of [how to read all connected devices here](Gamepad.html#discover-all-connected-devices). [`Input.IsJoystickPreconfigured`](https://docs.unity3d.com/ScriptReference/Input.IsJoystickPreconfigured.html)|Not needed. Devices which derive from [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) always correctly implement the mapping of axes and buttons to the corresponding [`InputControl`](../api/UnityEngine.InputSystem.InputControl.html) members of the [`Gamepad`](../api/UnityEngine.InputSystem.Gamepad.html) class. [`Input.ResetInputAxes`](https://docs.unity3d.com/ScriptReference/Input.ResetInputAxes.html) From d7acd693df99f5b56f9a3fac347185aa6426796b Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Fri, 28 Jun 2024 14:37:32 +0100 Subject: [PATCH 08/18] Fix broken api links for KeyControl.displayName --- .../InputSystem/Controls/ButtonControl.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs index 2902084812..93119cf9c4 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs @@ -103,7 +103,7 @@ public ButtonControl() /// ((KeyControl)Keyboard.current["space"]).isPressed /// /// - /// Note: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . + /// Note: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . /// /// You can also use this to read mouse buttons, as shown in the following examples: /// @@ -169,7 +169,7 @@ public ButtonControl() /// } /// /// - /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . + /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . /// /// You can also use this property to read mouse buttons. For example: /// @@ -207,7 +207,7 @@ public ButtonControl() /// } /// /// - /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . + /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . /// public bool wasReleasedThisFrame => device.wasUpdatedThisFrame && !IsValueConsideredPressed(value) && IsValueConsideredPressed(ReadValueFromPreviousFrame()); From 9bccbbcf8d74de3d33aa33a78d3c9abfa4bdc736 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Fri, 28 Jun 2024 15:36:42 +0100 Subject: [PATCH 09/18] Formatting fix --- Packages/com.unity.inputsystem/Documentation~/Migration.md | 2 +- .../InputSystem/Controls/ButtonControl.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Packages/com.unity.inputsystem/Documentation~/Migration.md b/Packages/com.unity.inputsystem/Documentation~/Migration.md index 3a3ac1040a..0c0e552198 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Migration.md +++ b/Packages/com.unity.inputsystem/Documentation~/Migration.md @@ -41,7 +41,7 @@ There are scripting symbols defined which allow you to use conditional compilati ## Comparison of API in the old Input Manager and the new Input System package -Below is a list comparing the API from the old Input Manager with the corresponding API for the new Input System package. +Below is a list comparing the API from the old Input Manager with the corresponding API for the new Input System package. All of the new Input System package APIs listed below are in the `UnityEngine.InputSystem` namespace. The namespace is omitted here for brevity. ### Action-based input diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs index 93119cf9c4..9580526465 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs @@ -115,7 +115,7 @@ public ButtonControl() /// ]]> /// /// - /// + /// /// You can also check through all numbered buttons on the mouse: (this example does not cause allocations) /// /// @@ -132,7 +132,7 @@ public ButtonControl() /// ]]> /// /// - /// + /// /// Or you can look up controls by name, like this: /// /// From 0e68c819435701b19d9dfba549b1a55bda457365 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Mon, 1 Jul 2024 10:15:01 +0100 Subject: [PATCH 10/18] Updates to migration guide for Pen events --- Packages/com.unity.inputsystem/Documentation~/Migration.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/Documentation~/Migration.md b/Packages/com.unity.inputsystem/Documentation~/Migration.md index 0c0e552198..a3d5abef51 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Migration.md +++ b/Packages/com.unity.inputsystem/Documentation~/Migration.md @@ -128,8 +128,12 @@ Directly reading hardware controls bypasses the new Input System's action-based [`Input.touchPressureSupported`](https://docs.unity3d.com/ScriptReference/Input-touchPressureSupported.html)|No corresponding API yet. [`Input.touchSupported`](https://docs.unity3d.com/ScriptReference/Input-touchSupported.html)|[`Touchscreen.current != null`](../api/UnityEngine.InputSystem.Touchscreen.html#UnityEngine_InputSystem_Touchscreen_current) [`Input.backButtonLeavesApp`](https://docs.unity3d.com/ScriptReference/Input-backButtonLeavesApp.html)|No corresponding API yet. +[`GetPenEvent`](https://docs.unity3d.com/ScriptReference/Input.GetPenEvent.html)
[`GetLastPenContactEvent`](https://docs.unity3d.com/ScriptReference/Input.GetLastPenContactEvent.html)
[`ResetPenEvents`](https://docs.unity3d.com/ScriptReference/Input.ResetPenEvents.html)
[`ClearLastPenContactEvent`](https://docs.unity3d.com/ScriptReference/Input.ClearLastPenContactEvent.html)|Use: [`Pen.current`](../api/UnityEngine.InputSystem.Pen.html#UnityEngine_InputSystem_Pen_current)
See the [Pen, tablet and stylus support](Pen.md) docs for more information. +
-Note: [`UnityEngine.TouchScreenKeyboard`](https://docs.unity3d.com/ScriptReference/TouchScreenKeyboard.html) is not part of the old Input Manager, so you can continue to use it when migrating to the new Input System package. + + +Note: [`UnityEngine.TouchScreenKeyboard`](https://docs.unity3d.com/ScriptReference/TouchScreenKeyboard.html) is not part of the old Input Manager API, so you can continue to use it when migrating to the new Input System package. ### Sensors |Input Manager (Old)|Input System (New)| From 3c58f515a2a63b7581ea2206419bb6d490379551 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Mon, 1 Jul 2024 10:34:24 +0100 Subject: [PATCH 11/18] Updates to migration guide for Keyboard IME text composition --- Packages/com.unity.inputsystem/Documentation~/Migration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Packages/com.unity.inputsystem/Documentation~/Migration.md b/Packages/com.unity.inputsystem/Documentation~/Migration.md index a3d5abef51..67bac9426b 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Migration.md +++ b/Packages/com.unity.inputsystem/Documentation~/Migration.md @@ -101,8 +101,8 @@ Directly reading hardware controls bypasses the new Input System's action-based [`Input.anyKeyDown`](https://docs.unity3d.com/ScriptReference/Input-anyKeyDown.html)|Use [`Keyboard.current.anyKey.wasUpdatedThisFrame`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_anyKey) [`Input.compositionCursorPos`](https://docs.unity3d.com/ScriptReference/Input-compositionCursorPos.html)|Use [`Keyboard.current.SetIMECursorPosition(myPosition)`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_SetIMECursorPosition_UnityEngine_Vector2_) [`Input.compositionString`](https://docs.unity3d.com/ScriptReference/Input-compositionString.html)|Subscribe to the [`Keyboard.onIMECompositionChange`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_onIMECompositionChange). -[`Input.imeCompositionMode`](https://docs.unity3d.com/ScriptReference/Input-imeCompositionMode.html)|No corresponding API yet. -[`Input.imeIsSelected`](https://docs.unity3d.com/ScriptReference/Input-imeIsSelected.html)|Get: `Keyboard.current.imeSelected`
Set: `Keyboard.current.SetIMEEnabled(true);` +[`Input.imeCompositionMode`](https://docs.unity3d.com/ScriptReference/Input-imeCompositionMode.html)|Use: [`Keyboard.current.SetIMEEnabled(true)`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_SetIMEEnabled_System_Boolean_)
Also see: [Keyboard text input documentation](Keyboard.html#ime). +[`Input.imeIsSelected`](https://docs.unity3d.com/ScriptReference/Input-imeIsSelected.html)|Use: [`Keyboard.current.imeSelected`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_imeSelected) [`Input.inputString`](https://docs.unity3d.com/ScriptReference/Input-inputString.html)|Subscribe to the [`Keyboard.onTextInput`](../api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_onTextInput) event:
`Keyboard.current.onTextInput += character => /* ... */;` ### Mouse From c6e39ff77c0f44d3a55613b56192715ad18ff074 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Wed, 3 Jul 2024 15:03:38 +0100 Subject: [PATCH 12/18] Removed migration info for Input.mousePresent --- Packages/com.unity.inputsystem/Documentation~/Migration.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Packages/com.unity.inputsystem/Documentation~/Migration.md b/Packages/com.unity.inputsystem/Documentation~/Migration.md index 67bac9426b..8f313acd08 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Migration.md +++ b/Packages/com.unity.inputsystem/Documentation~/Migration.md @@ -112,8 +112,7 @@ Directly reading hardware controls bypasses the new Input System's action-based [`Input.GetMouseButtonDown`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButtonDown.html)
Example: `Input.GetMouseButtonDown(0)`|Use [`wasPressedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasPressedThisFrame) on the corresponding mouse button.
Example: `InputSystem.Mouse.current.leftButton.wasPressedThisFrame` [`Input.GetMouseButtonUp`](https://docs.unity3d.com/ScriptReference/Input.GetMouseButtonUp.html)
Example: `Input.GetMouseButtonUp(0)`|Use [`wasReleasedThisFrame`](../api/UnityEngine.InputSystem.Controls.ButtonControl.html#UnityEngine_InputSystem_Controls_ButtonControl_wasReleasedThisFrame) on the corresponding mouse button.
Example: `InputSystem.Mouse.current.leftButton.wasReleasedThisFrame` [`Input.mousePosition`](https://docs.unity3d.com/ScriptReference/Input-mousePosition.html)|Use [`Mouse.current.position.ReadValue()`](../api/UnityEngine.InputSystem.Mouse.html)
Example: `Vector2 position = Mouse.current.position.ReadValue();`
__Note__: Mouse simulation from touch isn't implemented yet. -[`Input.mousePresent`](https://docs.unity3d.com/ScriptReference/Input-mousePresent.html)|Check whether [`Mouse.current`](../api/UnityEngine.InputSystem.Mouse.html#UnityEngine_InputSystem_Mouse_current) is null.
Example: `bool isMousePresent = Mouse.current != null;` - +[`Input.mousePresent`](https://docs.unity3d.com/ScriptReference/Input-mousePresent.html)|No corresponding API yet. ### Touch and Pen From 104ae35e82776d99c81e35c5a4c79f9f7bf68806 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Tue, 9 Jul 2024 15:23:40 +0100 Subject: [PATCH 13/18] Formatting fix --- .../com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs index c3fa95b14a..dc14b5f52f 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs @@ -341,6 +341,7 @@ internal void UpdateWasPressedEditor() m_LastUpdateWasPressEditor = isNowPressed; } } + #endif // UNITY_EDITOR // We make the current global default button press point available as a static so that we don't have to From 00155acdef098b9facc88d7370aae4c449f01941 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Tue, 30 Jul 2024 18:23:15 +0100 Subject: [PATCH 14/18] fix xml for ButtonControl --- .../InputSystem/Controls/ButtonControl.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs index dc14b5f52f..5660f5309e 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs @@ -103,6 +103,7 @@ public ButtonControl() /// A button is considered pressed if its value is equal to or greater /// than its button press threshold (). /// You can use this to read whether specific keys are currently pressed by using isPressed on keys, as shown in the following examples: + /// /// /// /// // Using KeyControl property directly. @@ -116,9 +117,11 @@ public ButtonControl() /// ((KeyControl)Keyboard.current["space"]).isPressed /// /// + /// /// Note: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . /// /// You can also use this to read mouse buttons, as shown in the following examples: + /// /// /// /// /// /// + /// /// /// You can also check through all numbered buttons on the mouse: (this example does not cause allocations) + /// /// /// /// /// /// + /// /// /// Or you can look up controls by name, like this: + /// /// /// /// /// /// - /// /// /// /// From 127549c88354359a2713876003665c2cc2cb93e9 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Wed, 31 Jul 2024 10:16:49 +0100 Subject: [PATCH 15/18] xml fix --- .../InputSystem/Controls/ButtonControl.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs index 5660f5309e..dc14b5f52f 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs @@ -103,7 +103,6 @@ public ButtonControl() /// A button is considered pressed if its value is equal to or greater /// than its button press threshold (). /// You can use this to read whether specific keys are currently pressed by using isPressed on keys, as shown in the following examples: - /// /// /// /// // Using KeyControl property directly. @@ -117,11 +116,9 @@ public ButtonControl() /// ((KeyControl)Keyboard.current["space"]).isPressed /// /// - /// /// Note: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . /// /// You can also use this to read mouse buttons, as shown in the following examples: - /// /// /// /// /// /// - /// /// /// You can also check through all numbered buttons on the mouse: (this example does not cause allocations) - /// /// /// /// /// /// - /// /// /// Or you can look up controls by name, like this: - /// /// /// /// /// /// + /// /// /// /// From a375f3f090a66f48fc988cd7fcf9744de7407a6f Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Wed, 31 Jul 2024 13:43:18 +0100 Subject: [PATCH 16/18] xml doc fix --- .../InputSystem/Controls/ButtonControl.cs | 19 +++++++------------ .../InputSystem/Devices/Keyboard.cs | 9 ++++----- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs index dc14b5f52f..df7bce1bb7 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs @@ -102,9 +102,11 @@ public ButtonControl() /// /// A button is considered pressed if its value is equal to or greater /// than its button press threshold (). - /// You can use this to read whether specific keys are currently pressed by using isPressed on keys, as shown in the following examples: + /// /// + /// You can use this to read whether specific keys are currently pressed by using isPressed on keys, as shown in the following examples: /// + /// /// - /// /// Note: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . /// /// You can also use this to read mouse buttons, as shown in the following examples: - /// /// /// /// - /// /// /// You can also check through all numbered buttons on the mouse: (this example does not cause allocations) - /// /// /// /// - /// /// /// Or you can look up controls by name, like this: - /// /// /// /// /// - /// /// /// /// @@ -270,10 +266,11 @@ public bool wasPressedThisFrame /// /// True if the current press of the button ended this frame. /// + /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . + /// /// + /// An example showing the use of this property on a gamepad button and a keyboard key: /// - /// // An example showing the use of this property on a gamepad button and a keyboard key. - /// /// using UnityEngine; /// using UnityEngine.InputSystem; /// @@ -287,8 +284,6 @@ public bool wasPressedThisFrame /// } /// /// - /// _Note_: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . - /// public bool wasReleasedThisFrame { get diff --git a/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs b/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs index 86da29dcc6..84d7f25e2b 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs @@ -969,9 +969,11 @@ public event Action onTextInput /// /// Many IMEs cause this event to fire with a blank string when the composition is submitted or reset, however it is best /// not to rely on this behaviour since it is IME dependent. - /// - /// To subscribe to the onIMECompositionChange event, use the following sample code: + /// + /// See for turning IME on/off + /// /// + /// To subscribe to the onIMECompositionChange event, use the following sample code: /// /// var compositionString = ""; /// Keyboard.current.onIMECompositionChange += composition => @@ -980,9 +982,6 @@ public event Action onTextInput /// }; /// /// - /// - /// See for turning IME on/off - /// public event Action onIMECompositionChange { add From 63b55f1e139913b3465191a3f04e940f0ffc4a67 Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Wed, 31 Jul 2024 13:47:20 +0100 Subject: [PATCH 17/18] whitespace format fix --- Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs b/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs index 84d7f25e2b..6699c726bb 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs @@ -969,7 +969,7 @@ public event Action onTextInput /// /// Many IMEs cause this event to fire with a blank string when the composition is submitted or reset, however it is best /// not to rely on this behaviour since it is IME dependent. - /// + /// /// See for turning IME on/off /// /// From 7a67b470b3420576abcb3d9e6c6bd2639f92fb1a Mon Sep 17 00:00:00 2001 From: Ben Pitt Date: Wed, 31 Jul 2024 14:12:06 +0100 Subject: [PATCH 18/18] added para tags for example plain text --- .../InputSystem/Controls/ButtonControl.cs | 14 ++++++-------- .../InputSystem/Devices/Keyboard.cs | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs index df7bce1bb7..fe28ffe352 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/ButtonControl.cs @@ -104,7 +104,7 @@ public ButtonControl() /// than its button press threshold (). /// /// - /// You can use this to read whether specific keys are currently pressed by using isPressed on keys, as shown in the following examples: + /// You can use this to read whether specific keys are currently pressed by using isPressed on keys, as shown in the following examples: /// /// /// - /// Note: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . + /// Note: The Input System identifies keys by physical layout, not according to the current language mapping of the keyboard. To query the name of the key according to the language mapping, use . /// - /// You can also use this to read mouse buttons, as shown in the following examples: + /// You can also use this to read mouse buttons, as shown in the following examples: /// /// /// - /// - /// You can also check through all numbered buttons on the mouse: (this example does not cause allocations) + /// You can also check through all numbered buttons on the mouse: (this example does not cause allocations) /// /// /// - /// - /// Or you can look up controls by name, like this: + /// Or you can look up controls by name, like this: /// /// . /// /// - /// An example showing the use of this property on a gamepad button and a keyboard key: + /// An example showing the use of this property on a gamepad button and a keyboard key: /// /// using UnityEngine; /// using UnityEngine.InputSystem; diff --git a/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs b/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs index 6699c726bb..20b8e0ecb3 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Devices/Keyboard.cs @@ -973,7 +973,7 @@ public event Action onTextInput /// See for turning IME on/off /// /// - /// To subscribe to the onIMECompositionChange event, use the following sample code: + /// To subscribe to the onIMECompositionChange event, use the following sample code: /// /// var compositionString = ""; /// Keyboard.current.onIMECompositionChange += composition =>