diff --git a/Packages/com.unity.inputsystem/Documentation~/ActionAssets.md b/Packages/com.unity.inputsystem/Documentation~/ActionAssets.md deleted file mode 100644 index 1910b06a65..0000000000 --- a/Packages/com.unity.inputsystem/Documentation~/ActionAssets.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -uid: input-system-action-assets ---- -# Input action assets - -An input action asset is an asset which contains a set of [input action](xref:input-system-actions) definitions and their associated [Bindings](xref:input-system-action-bindings) and [control schemes](xref:input-system-action-bindings#control-schemes). These assets have the `.inputactions` file extension and are stored in a plain JSON format. - -The input system creates an action asset when you set up the [default project-wide actions](xref:project-wide-actions), but you can also create new action assets directly in the Project window. - -For most common scenarios, you do not need to use more than one input action asset. It is usually simpler to configure your project-wide action definition in the Project Settings window. - - -## Creating input action assets - -To create an asset that contains [input actions](xref:input-system-actions) in Unity, right-click in the __Project__ window or go to __Assets > Create > Input Actions__ from Unity's main menu. - -## Editing input action assets - -To open the Input Actions Editor, double-click an `.inputactions` asset in the Project Browser, or select the __Edit Asset__ button in the Inspector for that asset. You can have more than one editor window open at the same time, but not for the same asset. - -This Input Actions Editor is identical to the one that opens in the [Project Settings window](xref:input-system-configuring-input). - - -## Using input action assets - - -## Type-safe C# API generation - -Input action assets allow you to **generate a C# class** from your action definitions, so you can refer to your actions in a type-safe manner from code. This means you can avoid looking up your actions by string. - -### Auto-generating script code for actions - -One of the most convenient ways to work with `.inputactions` assets in scripts is to automatically generate a C# wrapper class for them. This provides an easier way to set up callbacks and avoid manually looking up actions and action maps by name. - -To enable this option, enable the __Generate C# Class__ property in the input action asset's Inspector, then select __Apply__. - -![The input action asset's Inspector window displays the enabled Generate C# Class property with default values for the C# class's file, name, and namespace settings.](Images/FireActionInputAssetInspector.png) - -You can optionally choose a path name, class name, and namespace for the generated script, or keep the default values. - -This generates a C# script that simplifies working with the asset. - -```CSharp -using UnityEngine; -using UnityEngine.InputSystem; - -// IGameplayActions is an interface generated from the newly added "gameplay" -// action map, triggered by the "Generate Interfaces" checkbox. Note that if -// you change the default values for the action map, the name of the interface -// will be different. -public class MyPlayerScript : MonoBehaviour, IGameplayActions -{ - // MyPlayerControls is the C# class that Unity generated. - // It encapsulates the data from the .inputactions asset we created - // and automatically looks up all the maps and actions for us. - MyPlayerControls controls; - - public void OnEnable() - { - if (controls == null) - { - controls = new MyPlayerControls(); - // Tell the "gameplay" action map that we want to be - // notified when actions get triggered. - controls.gameplay.SetCallbacks(this); - } - controls.gameplay.Enable(); - } - - public void OnDisable() - { - controls.gameplay.Disable(); - } - - public void OnUse(InputAction.CallbackContext context) - { - // 'Use' code here. - } - - public void OnMove(InputAction.CallbackContext context) - { - // 'Move' code here. - } - -} -``` - -> [!NOTE] -> To regenerate the .cs file, right-click the .inputactions asset in the Project window and choose "Reimport". - -### Using action assets with `PlayerInput` - -The [Player Input](xref:input-system-player-input) component provides a convenient way to handle input for one or multiple players. You can assign your action asset to the Player Input component so that it can then automatically handle activating action maps and selecting control schemes for you. - -![The PlayerInput component appears with Player set as the Default Map and the Behavior set to Invoke Unity Events.](Images/PlayerInput.png) - -### Modifying input action assets at runtime - -There are several ways to modify an input action asset at runtime. Any modifications that you make during Play mode to an input action asset do not persist in the asset after you exit Play mode. This means you can test your application in a realistic way in the Editor without having to worry about inadvertently modifying the asset. For examples on how to modify an input action asset, refer to [Create actions in code](xref:input-system-actions#create-actions-in-code) and [Change Bindings](xref:input-system-action-bindings#change-bindings). - - -### The default actions asset - -> [!NOTE] -> The default actions asset is entirely separate from the [default project-wide actions](xref:project-wide-actions). It is a legacy asset that is included in the package for backwards compatibility. - -The Input System package provides an asset called `DefaultInputActions.inputactions` which you can reference directly in your projects like any other Unity asset. The asset is also available in code form through the [`DefaultInputActions`](xref:UnityEngine.InputSystem.DefaultInputActions) class. - -```CSharp -void Start() -{ - // Create an instance of the default actions. - var actions = new DefaultInputActions(); - actions.Player.Look.performed += OnLook; - actions.Player.Move.performed += OnMove; - actions.Enable(); -} -``` diff --git a/Packages/com.unity.inputsystem/Documentation~/ActionBindings.md b/Packages/com.unity.inputsystem/Documentation~/ActionBindings.md deleted file mode 100644 index 134b5839ac..0000000000 --- a/Packages/com.unity.inputsystem/Documentation~/ActionBindings.md +++ /dev/null @@ -1,955 +0,0 @@ ---- -uid: input-system-action-bindings ---- -# Input bindings - -An [`InputBinding`](xref:UnityEngine.InputSystem.InputBinding) represents a connection between an [action](xref:input-system-actions) and one or more [controls](xref:input-system-controls) identified by a [control path](xref:input-system-controls#control-paths). For example, the right trigger of a gamepad (a control) might be bound to an an action named "accelerate", so that pulling the right trigger causes a car to accelerate in your game. - -You can add multiple bindings to an action, which is generally useful for supporting multiple types of input device. For example, in the default set of actions, the "Move" action has a binding to the left gamepad stick and the WASD keys, which means input through any of these bindings will perform the action. - -You can also bind multiple controls from the same device to an action. For example, both the left and right trigger of a gamepad could be mapped to the same action, so that pulling either trigger has the same result in your game. - -You can also set up [Composite](#composite-bindings) bindings, which don't bind to the controls themselves, but receive their input from **Part Bindings** and then return a value representing a composition of those inputs. For example, the right trigger on the gamepad can act as a strength multiplier on the value of the left stick. - -## InputBinding API access - -Each `InputBinding` has the following properties: - -|Property|Description| -|--------|-----------| -|[`path`](xref:UnityEngine.InputSystem.InputBinding.path)|[Control path](xref:input-system-controls#control-paths) that identifies the control(s) from which the action should receive input.

Example: `"/leftStick"`| -|[`overridePath`](xref:UnityEngine.InputSystem.InputBinding.overridePath)|[Control path](xref:input-system-controls#control-paths) that overrides `path`. Unlike `path`, `overridePath` is not persistent, so you can use it to non-destructively override the path on a binding. If it is set to something other than null, it takes effect and overrides `path`. To get the path which is currently in effect (that is, either `path` or `overridePath`), you can query the [`effectivePath`](xref:UnityEngine.InputSystem.InputBinding.effectivePath) property.| -|[`action`](xref:UnityEngine.InputSystem.InputBinding.action)|The name or ID of the action that the binding should trigger. Note that this can be null or empty (for instance, for [composites](#composite-bindings)). Not case-sensitive.

Example: `"fire"`| -|[`groups`](xref:UnityEngine.InputSystem.InputBinding.groups)|A semicolon-separated list of binding groups that the binding belongs to. Can be null or empty. Binding groups can be anything, but are mostly used for [control schemes](#control-schemes). Not case-sensitive.

Example: `"Keyboard&Mouse;Gamepad"`| -|[`interactions`](xref:UnityEngine.InputSystem.InputBinding.interactions)|A semicolon-separated list of [Interactions](xref:input-system-interactions) to apply to input on this binding. Note that Unity appends Interactions applied to the [action](xref:input-system-actions) itself (if any) to this list. Not case-sensitive.

Example: `"slowTap;hold(duration=0.75)"`| -|[`processors`](xref:UnityEngine.InputSystem.InputBinding.processors)|A semicolon-separated list of [Processors](UsingProcessors.md) to apply to input on this binding. Note that Unity appends Processors applied to the [action](xref:input-system-actions) itself (if any) to this list. Not case-sensitive.

Processors on bindings apply in addition to Processors on controls that are providing values. For example, if you put a `stickDeadzone` Processor on a binding and then bind it to `/leftStick`, you get deadzones applied twice: once from the deadzone Processor sitting on the `leftStick` control, and once from the binding.

Example: `"invert;axisDeadzone(min=0.1,max=0.95)"`| -|[`id`](xref:UnityEngine.InputSystem.InputBinding.id)|Unique ID of the binding. You can use it to identify the binding when storing binding overrides in user settings, for example.| -|[`name`](xref:UnityEngine.InputSystem.InputBinding.name)|Optional name of the binding. Identifies part names inside [Composites](#composite-bindings).

Example: `"Positive"`| -|[`isComposite`](xref:UnityEngine.InputSystem.InputBinding.isComposite)|Whether the binding acts as a [Composite](#composite-bindings).| -|[`isPartOfComposite`](xref:UnityEngine.InputSystem.InputBinding.isPartOfComposite)|Whether the binding is part of a [Composite](#composite-bindings).| - -To query the bindings for a specific action, use [`InputAction.bindings`](xref:UnityEngine.InputSystem.InputAction.bindings). - -To query a flat list of bindings for all actions in an action map, use [`InputActionMap.bindings`](xref:UnityEngine.InputSystem.InputActionMap.bindings). - -## Composite bindings - -You might want to have several controls act in unison to mimic a different type of control. The most common example of this is using the W, A, S, and D keys on the keyboard to form a 2D vector control equivalent to mouse deltas or gamepad sticks. Another example is to use two keys to form a 1D axis equivalent to a mouse scroll axis. - -This is difficult to implement with normal bindings. You can bind a [`ButtonControl`](xref:UnityEngine.InputSystem.Controls.ButtonControl) to an action expecting a `Vector2`, but doing so results in an exception at runtime when the Input System tries to read a `Vector2` from a control that can deliver only a `float`. - -Composite bindings (that is, bindings that are made up of other bindings) solve this problem. Composites themselves don't bind directly to controls; instead, they source values from other bindings that do, and then synthesize input on the fly from those values. - -To see how to create Composites in the editor UI, refer to [Editing Composite Bindings](xref:input-system-configuring-input#edit-composite-bindings). - -To create composites in code, use the [`AddCompositeBinding`](xref:UnityEngine.InputSystem.InputActionSetupExtensions.AddCompositeBinding(UnityEngine.InputSystem.InputAction,System.String,System.String,System.String)) method: - -```CSharp -myAction.AddCompositeBinding("Axis") - .With("Positive", "/rightTrigger") - .With("Negative", "/leftTrigger"); -``` - -Each Composite consists of one binding that has [`InputBinding.isComposite`](xref:UnityEngine.InputSystem.InputBinding.isComposite) set to true, followed by one or more bindings that have [`InputBinding.isPartOfComposite`](xref:UnityEngine.InputSystem.InputBinding.isPartOfComposite) set to true. In other words, several consecutive entries in [`InputActionMap.bindings`](xref:UnityEngine.InputSystem.InputActionMap.bindings) or [`InputAction.bindings`](xref:UnityEngine.InputSystem.InputAction.bindings) together form a Composite. - -Note that each composite part can be bound arbitrary many times. - -```CSharp -// Make both shoulders and triggers pull on the axis. -myAction.AddCompositeBinding("Axis") - .With("Positive", "/rightTrigger") - .With("Positive", "/rightShoulder") - .With("Negative", "/leftTrigger"); - .With("Negative", "/leftShoulder"); -``` - -Composites can have parameters, just like [Interactions](xref:input-system-interactions) and [Processors](UsingProcessors.md). - -```CSharp -myAction.AddCompositeBinding("Axis(whichSideWins=1)"); -``` - -There are currently five Composite types that come with the system out of the box: - -- [1D-Axis](#1d-axis): two buttons that pull a 1D axis in the negative and positive direction. -- [2D-Vector](#2d-vector): represents a 4-way button setup where each button represents a cardinal direction, for example a WASD keyboard input (up-down-left-right controls). -- [3D-Vector](#3d-vector): represents a 6-way button where two combinations each control one axis of a 3D Vector. -- [One Modifier](#one-modifier): requires the user to hold down a "modifier" button in addition to another control, for example, "SHIFT+1". -- [Two Modifiers](#two-modifiers): requires the user to hold down two "modifier" buttons in addition to another control, for example, "SHIFT+CTRL+1". - -You can also [add your own](#writing-custom-composites) types of Composites. - -### 1D Axis - -![The Add Positive/Negative binding property is selected for the "fire" action on the Actions panel.](Images/Add1DAxisComposite.png){width="486" height="133"} - -![The 1D Axis Composite binding appears under the "fire" action on the Actions panel.](Images/1DAxisComposite.png){width="486" height="142"} - - -The 1D Axis Composite is made of two buttons: one that pulls a 1D axis in its negative direction, and another that pulls it in its positive direction, using the [`AxisComposite`](xref:UnityEngine.InputSystem.Composites.AxisComposite) class to compute a `float`. - -```CSharp -myAction.AddCompositeBinding("1DAxis") // Or just "Axis" - .With("Positive", "/rightTrigger") - .With("Negative", "/leftTrigger"); -``` - -The axis Composite has two Part Bindings: - -|Part Binding|Type|Description| -|----|----|-----------| -|[`positive`](xref:UnityEngine.InputSystem.Composites.AxisComposite.positive)|`Button`|Controls pulling in the positive direction (towards [`maxValue`](xref:UnityEngine.InputSystem.Composites.AxisComposite.maxValue)).| -|[`negative`](xref:UnityEngine.InputSystem.Composites.AxisComposite.negative)|`Button`|Controls pulling in the negative direction, (towards [`minValue`](xref:UnityEngine.InputSystem.Composites.AxisComposite.minValue)).| - -You can set the following parameters on an axis Composite: - -|Parameter|Description| -|---------|-----------| -|[`whichSideWins`](xref:UnityEngine.InputSystem.Composites.AxisComposite.whichSideWins)|What happens if both [`positive`](xref:UnityEngine.InputSystem.Composites.AxisComposite.positive) and [`negative`](xref:UnityEngine.InputSystem.Composites.AxisComposite.negative) are actuated. See table below.| -|[`minValue`](xref:UnityEngine.InputSystem.Composites.AxisComposite.minValue)|The value returned if the [`negative`](xref:UnityEngine.InputSystem.Composites.AxisComposite.negative) side is actuated. Default is -1.| -|[`maxValue`](xref:UnityEngine.InputSystem.Composites.AxisComposite.maxValue)|The value returned if the [`positive`](xref:UnityEngine.InputSystem.Composites.AxisComposite.positive) side is actuated. Default is 1.| - -If controls from both the `positive` and the `negative` side are actuated, then the resulting value of the axis Composite depends on the `whichSideWin` parameter setting. - -| [`WhichSideWins`](xref:UnityEngine.InputSystem.Composites.AxisComposite.WhichSideWins) | Description | -| ------------------------------------------------------------ | ------------------------------------------------------------ | -| (0) `Neither` | Neither side has precedence. The Composite returns the [`midpoint`](xref:UnityEngine.InputSystem.Composites.AxisComposite.midPoint) between `minValue` and `maxValue` as a result. At their default settings, this is 0.

This is the default value for this setting. | -| (1) `Positive` | The positive side has precedence and the Composite returns `maxValue`. | -| (2) `Negative` | The negative side has precedence and the Composite returns `minValue`. | - -> [!NOTE] -> There is no support yet for interpolating between the positive and negative over time. - -### 2D Vector - -![The Add Up/Down/Left/Right Composite binding is selected for the "Move" action on the Actions panel.](Images/Add2DVectorComposite.png){width="486" height="199"} - -![The WASD part bindings appear under the "Move" action on the Actions panel.](Images/2DVectorComposite.png){width="486" height="178"} - -A 2D Vector Composite represents a 4-way button setup like the D-pad on gamepads, where each button represents a cardinal direction. This type of Composite binding uses the [`Vector2Composite`](xref:UnityEngine.InputSystem.Composites.Vector2Composite) class to compute a `Vector2`. - -This is very useful for representing up-down-left-right controls, such as WASD keyboard input. - -```CSharp -myAction.AddCompositeBinding("2DVector") // Or "Dpad" - .With("Up", "/w") - .With("Down", "/s") - .With("Left", "/a") - .With("Right", "/d"); - -// To set mode (2=analog, 1=digital, 0=digitalNormalized): -myAction.AddCompositeBinding("2DVector(mode=2)") - .With("Up", "/leftStick/up") - .With("Down", "/leftStick/down") - .With("Left", "/leftStick/left") - .With("Right", "/leftStick/right"); -``` - -The 2D Vector Composite has four Part Bindings. - -|Part Binding|Type|Description| -|----|----|-----------| -|[`up`](xref:UnityEngine.InputSystem.Composites.Vector2Composite.up)|`Button`|Controls representing `(0,1)` (+Y).| -|[`down`](xref:UnityEngine.InputSystem.Composites.Vector2Composite.down)|`Button`|Controls representing `(0,-1)` (-Y).| -|[`left`](xref:UnityEngine.InputSystem.Composites.Vector2Composite.left)|`Button`|Controls representing `(-1,0)` (-X).| -|[`right`](xref:UnityEngine.InputSystem.Composites.Vector2Composite.right)|`Button`|Controls representing `(1,0)` (+X).| - -In addition, you can set this parameter on a 2D Vector Composite: - -|Parameter|Description| -|---------|-----------| -|[`mode`](xref:UnityEngine.InputSystem.Composites.Vector2Composite.mode)|Whether to treat the inputs as digital or as analog controls.

If this is set to [`Mode.DigitalNormalized`](xref:UnityEngine.InputSystem.Composites.Vector2Composite.Mode.DigitalNormalized), inputs are treated as buttons (off if below [`defaultButtonPressPoint`](xref:UnityEngine.InputSystem.InputSettings.defaultButtonPressPoint) and on if equal to or greater). Each input is 0 or 1 depending on whether the button is pressed or not. The vector resulting from the up/down/left/right parts is normalized. The result is a diamond-shaped 2D input range.

If this is set to [`Mode.Digital`](xref:UnityEngine.InputSystem.Composites.Vector2Composite.Mode.Digital), the behavior is essentially the same as [`Mode.DigitalNormalized`](xref:UnityEngine.InputSystem.Composites.Vector2Composite.Mode.DigitalNormalized) except that the resulting vector is not normalized.

Finally, if this is set to [`Mode.Analog`](xref:UnityEngine.InputSystem.Composites.Vector2Composite.Mode.Analog), inputs are treated as analog (i.e. full floating-point values) and, other than [`down`](xref:UnityEngine.InputSystem.Composites.Vector2Composite.down) and [`left`](xref:UnityEngine.InputSystem.Composites.Vector2Composite.left) being inverted, values will be passed through as is.

The default is [`Mode.DigitalNormalized`](xref:UnityEngine.InputSystem.Composites.Vector2Composite.Mode.DigitalNormalized).| - -> [!NOTE] -> There is no support yet for interpolating between the up/down/left/right over time. - -### 3D Vector - - -![The Add Up/Down/Left/Right/Forward/Backward Composite binding is selected for the "position" action on the Actions panel.](Images/Add3DVectorComposite.png){width="486" height="150"} - -![The 3D Vector part bindings appear under the "position" action on the Actions panel.](Images/3DVectorComposite.png){width="486" height="259" -} - -A 3D Vector Composite that represents a 6-way button where two combinations each control one axis of a 3D Vector. This type of Composite binding uses the the [`Vector3Composite`](xref:UnityEngine.InputSystem.Composites.Vector3Composite) class to compute a `Vector3`. - -```CSharp -myAction.AddCompositeBinding("3DVector") - .With("Up", "/w") - .With("Down", "/s") - .With("Left", "/a") - .With("Right", "/d"); - -// To set mode (2=analog, 1=digital, 0=digitalNormalized): -myAction.AddCompositeBinding("3DVector(mode=2)") - .With("Up", "/leftStick/up") - .With("Down", "/leftStick/down") - .With("Left", "/leftStick/left") - .With("Right", "/leftStick/right"); -``` - -The 3D Vector Composite has four Part Bindings. - -|Part Binding|Type|Description| -|----|----|-----------| -|[`up`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.up)|`Button`|Controls representing `(0,1,0)` (+Y).| -|[`down`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.down)|`Button`|Controls representing `(0,-1,0)` (-Y).| -|[`left`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.left)|`Button`|Controls representing `(-1,0,0)` (-X).| -|[`right`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.right)|`Button`|Controls representing `(1,0,0)` (+X).| -|[`forward`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.forward)|`Button`|Controls representing `(0,0,1)` (+Z).| -|[`backward`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.backward)|`Button`|Controls representing `(0,0,-1)` (-Z).| - -In addition, you can set the following parameters on a 3D vector Composite: - -|Parameter|Description| -|---------|-----------| -|[`mode`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.mode)|Whether to treat the inputs as digital or as analog controls.

If this is set to [`Mode.DigitalNormalized`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.Mode.DigitalNormalized), inputs are treated as buttons (off if below [`defaultButtonPressPoint`](xref:UnityEngine.InputSystem.InputSettings.defaultButtonPressPoint) and on if equal to or greater). Each input is 0 or 1 depending on whether the button is pressed or not. The vector resulting from the up/down/left/right/forward/backward parts is normalized.

If this is set to [`Mode.Digital`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.Mode.Digital), the behavior is essentially the same as [`Mode.DigitalNormalized`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.Mode.DigitalNormalized) except that the resulting vector is not normalized.

Finally, if this is set to [`Mode.Analog`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.Mode.Analog), inputs are treated as analog (that is, full floating-point values) and, other than [`down`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.down), [`left`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.left), and [`backward`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.backward) being inverted, values will be passed through as they are.

The default is [`Analog`](xref:UnityEngine.InputSystem.Composites.Vector3Composite.Mode.Analog).| - -### One Modifier - - -![The Add Binding With One Modifier Composite binding is selected for the "fire" action on the Actions panel.](Images/AddBindingWithOneModifier.png){width="486" height="129"} - -![The One Modifier part bindings appear under the "fire" action on the Actions panel.](Images/OneModifierComposite.png){width="486" height="147"} - -A One Modifier Composite requires the user to hold down a "modifier" button in addition to another control from which the actual value of the binding is determined. This can be used, for example, for bindings such as "SHIFT+1". This type of Composite binding uses the [`OneModifierComposite`](xref:UnityEngine.InputSystem.Composites.OneModifierComposite) class. The buttons can be on any device, and can be toggle buttons or full-range buttons such as gamepad triggers. - -The result is a value of the same type as the controls bound to the [`binding`](xref:UnityEngine.InputSystem.Composites.OneModifierComposite.binding) part. - -```CSharp -// Add binding for "CTRL+1". -myAction.AddCompositeBinding("OneModifier") - .With("Binding", "/1") - .With("Modifier", "/ctrl") - -// Add binding to mouse delta such that it only takes effect -// while the ALT key is down. -myAction.AddCompositeBinding("OneModifier") - .With("Binding", "/delta") - .With("Modifier", "/alt"); -``` - -The button with One Modifier Composite has two Part Bindings. - -|Part|Type|Description| -|----|----|-----------| -|[`modifier`](xref:UnityEngine.InputSystem.Composites.OneModifierComposite.modifier)|`Button`|Modifier that has to be held for `binding` to come through. If the user holds any of the buttons bound to the `modifier` at the same time as the button that triggers the action, the Composite assumes the value of the `modifier` binding. If the user does not press any button bound to the `modifier`, the Composite remains at default value.| -|[`binding`](xref:UnityEngine.InputSystem.Composites.OneModifierComposite.binding)|Any|The control(s) whose value the Composite assumes while the user holds down the `modifier` button.| - -This Composite has no parameters. - -### Two Modifiers - - -![The bindings With Two Modifiers Composite binding is selected for the "fire" action on the Actions panel.](Images/AddBindingWithTwoModifiers.png){width="486" height="119"} - -![The Two Modifiers part bindings appear under the "fire" action on the Actions panel.](Images/TwoModifiersComposite.png){width="486" height="149"} - -A Two Modifiers Composite requires the user to hold down two "modifier" buttons in addition to another control from which the actual value of the binding is determined. This can be used, for example, for bindings such as "SHIFT+CTRL+1". This type of Composite binding uses the [`TwoModifiersComposite`](xref:UnityEngine.InputSystem.Composites.TwoModifiersComposite) class. The buttons can be on any device, and can be toggle buttons or full-range buttons such as gamepad triggers. - -The result is a value of the same type as the controls bound to the [`binding`](xref:UnityEngine.InputSystem.Composites.TwoModifiersComposite.binding) part. - -```CSharp -myAction.AddCompositeBinding("TwoModifiers") - .With("Button", "/1") - .With("Modifier1", "/leftCtrl") - .With("Modifier1", "/rightCtrl") - .With("Modifier2", "/leftShift") - .With("Modifier2", "/rightShift"); -``` - -The button with Two Modifiers Composite has three Part Bindings. - -|Part|Type|Description| -|----|----|-----------| -|[`modifier1`](xref:UnityEngine.InputSystem.Composites.TwoModifiersComposite.modifier1)|`Button`|The first modifier the user must hold alongside `modifier2`, for `binding` to come through. If the user does not press any button bound to the `modifier1`, the Composite remains at default value.| -|[`modifier2`](xref:UnityEngine.InputSystem.Composites.TwoModifiersComposite.modifier2)|`Button`|The second modifier the user must hold alongside `modifier1`, for `binding` to come through. If the user does not press any button bound to the `modifier2`, the Composite remains at default value.| -|[`binding`](xref:UnityEngine.InputSystem.Composites.TwoModifiersComposite.binding)|Any|The control(s) whose value the Composite assumes while the user presses both `modifier1` and `modifier2` at the same time.| - -This Composite has no parameters. - -### Writing custom Composites - -You can define new types of Composites, and register them with the API. Unity treats these the same as predefined types, which the Input System internally defines and registers in the same way. - -To define a new type of Composite, create a class based on [`InputBindingComposite`](xref:UnityEngine.InputSystem.InputBindingComposite`1). - -> [!IMPORTANT] -> Composites must be __stateless__. This means that you cannot store local state that changes depending on the input being processed. For __stateful__ processing on bindings, see [interactions](xref:input-system-interactions#writing-custom-interactions). - -```CSharp -// Use InputBindingComposite as a base class for a composite that returns -// values of type TValue. -// NOTE: It is possible to define a composite that returns different kinds of values -// but doing so requires deriving directly from InputBindingComposite. -#if UNITY_EDITOR -[InitializeOnLoad] // Automatically register in editor. -#endif -// Determine how GetBindingDisplayString() formats the composite by applying -// the DisplayStringFormat attribute. -[DisplayStringFormat("{firstPart}+{secondPart}")] -public class CustomComposite : InputBindingComposite -{ - // Each part binding is represented as a field of type int and annotated with - // InputControlAttribute. Setting "layout" restricts the controls that - // are made available for picking in the UI. - // - // On creation, the int value is set to an integer identifier for the binding - // part. This identifier can read values from InputBindingCompositeContext. - // See ReadValue() below. - [InputControl(layout = "Button")] - public int firstPart; - - [InputControl(layout = "Button")] - public int secondPart; - - // Any public field that is not annotated with InputControlAttribute is considered - // a parameter of the composite. This can be set graphically in the UI and also - // in the data (e.g. "custom(floatParameter=2.0)"). - public float floatParameter; - public bool boolParameter; - - // This method computes the resulting input value of the composite based - // on the input from its part bindings. - public override float ReadValue(ref InputBindingCompositeContext context) - { - var firstPartValue = context.ReadValue(firstPart); - var secondPartValue = context.ReadValue(secondPart); - - //... do some processing and return value - } - - // This method computes the current actuation of the binding as a whole. - public override float EvaluateMagnitude(ref InputBindingCompositeContext context) - { - // Compute normalized [0..1] magnitude value for current actuation level. - } - - static CustomComposite() - { - // Can give custom name or use default (type name with "Composite" clipped off). - // Same composite can be registered multiple times with different names to introduce - // aliases. - // - // NOTE: Registering from the static constructor using InitializeOnLoad and - // RuntimeInitializeOnLoadMethod is only one way. You can register the - // composite from wherever it works best for you. Note, however, that - // the registration has to take place before the composite is first used - // in a binding. Also, for the composite to show in the editor, it has - // to be registered from code that runs in edit mode. - InputSystem.RegisterBindingComposite(); - } - - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] - static void Init() {} // Trigger static constructor. -} -``` - -The Composite should now appear in the editor UI when you add a binding, and you can now use it in scripts. - -```CSharp - myAction.AddCompositeBinding("custom(floatParameter=2.0)") - .With("firstpart", "/buttonSouth") - .With("secondpart", "/buttonNorth"); -``` - -To define a custom parameter editor for the Composite, you can derive from [`InputParameterEditor`](xref:UnityEngine.InputSystem.Editor.InputParameterEditor`1). - -```CSharp -#if UNITY_EDITOR -public class CustomParameterEditor : InputParameterEditor -{ - public override void OnGUI() - { - EditorGUILayout.Label("Custom stuff"); - target.floatParameter = EditorGUILayout.FloatField("Some Parameter", target.floatParameter); - } -} -#endif -``` - -## Working with bindings - -### Look up bindings - -You can retrieve the bindings of an action using its [`InputAction.bindings`](xref:UnityEngine.InputSystem.InputAction.bindings) property which returns a read-only array of [`InputBinding`](xref:UnityEngine.InputSystem.InputBinding) structs. - -```CSharp - // Get bindings of "fire" action. - var fireBindings = playerInput.actions["fire"].bindings; -``` - -Also, all the bindings for all actions in an [`InputActionMap`](xref:UnityEngine.InputSystem.InputActionMap) are made available through the [`InputActionMap.bindings`](xref:UnityEngine.InputSystem.InputActionMap.bindings) property. The bindings are associated with actions through an [action ID](xref:UnityEngine.InputSystem.InputAction.id) or [action name](xref:UnityEngine.InputSystem.InputAction.name) stored in the [`InputBinding.action`](xref:UnityEngine.InputSystem.InputBinding.action) property. - -```CSharp - // Get all bindings in "gameplay" action map. - var gameplayBindings = playerInput.actions.FindActionMap("gameplay").bindings; -``` - -You can also look up specific the indices of specific bindings in [`InputAction.bindings`](xref:UnityEngine.InputSystem.InputAction.bindings) using the [`InputActionRebindingExtensions.GetBindingIndex`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.GetBindingIndex(UnityEngine.InputSystem.InputAction,UnityEngine.InputSystem.InputBinding)) method. - -```CSharp - // Find the binding in the "Keyboard" control scheme. - playerInput.actions["fire"].GetBindingIndex(group: "Keyboard"); - - // Find the first binding to the space key in the "gameplay" action map. - playerInput.FindActionMap("gameplay").GetBindingIndex( - new InputBinding { path = "/space" }); -``` - -Finally, you can look up the binding that corresponds to a specific control through [`GetBindingIndexForControl`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.GetBindingIndexForControl*). This way, you can, for example, map a control found in the [`controls`](xref:UnityEngine.InputSystem.InputAction.controls) array of an [`InputAction`](xref:UnityEngine.InputSystem.InputAction) back to an [`InputBinding`](xref:UnityEngine.InputSystem.InputBinding). - -```CSharp - // Find the binding that binds LMB to "fire". If there is no such binding, - // bindingIndex will be -1. - var fireAction = playerInput.actions["fire"]; - var bindingIndex = fireAction.GetBindingIndexForControl(Mouse.current.leftButton); - if (binding == -1) - Debug.Log("Fire is not bound to LMB of the current mouse."); -``` - -### Change bindings - -In general, you can change existing bindings via the [`InputActionSetupExtensions.ChangeBinding`](xref:UnityEngine.InputSystem.InputActionSetupExtensions.ChangeBinding(UnityEngine.InputSystem.InputAction,System.Int32)) method. This returns an accessor that can be used to modify the properties of the targeted [`InputBinding`](xref:UnityEngine.InputSystem.InputBinding). Note that most of the write operations of the accessor are destructive. For non-destructive changes to bindings, refer to [Apply overrides](#apply-overrides). - -```CSharp -// Get write access to the second binding of the 'fire' action. -var accessor = playerInput.actions['fire'].ChangeBinding(1); - -// You can also gain access through the InputActionMap. Each -// map contains an array of all its bindings (see InputActionMap.bindings). -// Here we gain access to the third binding in the map. -accessor = playerInput.actions.FindActionMap("gameplay").ChangeBinding(2); -``` - -You can use the resulting accessor to modify properties through methods such as [`WithPath`](xref:UnityEngine.InputSystem.InputActionSetupExtensions.BindingSyntax.WithPath*) or [`WithProcessors`](xref:UnityEngine.InputSystem.InputActionSetupExtensions.BindingSyntax.WithProcessors*). - -```CSharp -playerInput.actions["fire"].ChangeBinding(1) - // Change path to space key. - .WithPath("/space"); -``` - -You can also use the accessor to iterate through bindings using [`PreviousBinding`](xref:UnityEngine.InputSystem.InputActionSetupExtensions.BindingSyntax.PreviousBinding*) and [`NextBinding`](xref:UnityEngine.InputSystem.InputActionSetupExtensions.BindingSyntax.NextBinding*). - -```CSharp -// Move accessor to previous binding. -accessor = accessor.PreviousBinding(); - -// Move accessor to next binding. -accessor = accessor.NextBinding(); -``` - -If the given binding is a [composite](xref:UnityEngine.InputSystem.InputBinding.isComposite), you can address it by its name rather than by index. - -```CSharp -// Change the 2DVector composite of the "move" action. -playerInput.actions["move"].ChangeCompositeBinding("2DVector") - - -// -playerInput.actions["move"].ChangeBinding("WASD") -``` - -#### Apply overrides - -You can override aspects of any binding at run-time non-destructively. Specific properties of [`InputBinding`](xref:UnityEngine.InputSystem.InputBinding) have an `override` variant that, if set, will take precedent over the property that they shadow. All `override` properties are of type `String`. - -|Property|Override|Description| -|--------|--------|-----------| -|[`path`](xref:UnityEngine.InputSystem.InputBinding.path)|[`overridePath`](xref:UnityEngine.InputSystem.InputBinding.overridePath)|Replaces the [control path](xref:input-system-controls#control-paths) that determines which control(s) are referenced in the binding. If [`overridePath`](xref:UnityEngine.InputSystem.InputBinding.overridePath) is set to an empty string, the binding is effectively disabled.

Example: `"/leftStick"`| -|[`processors`](xref:UnityEngine.InputSystem.InputBinding.processors)|[`overrideProcessors`](xref:UnityEngine.InputSystem.InputBinding.overrideProcessors)|Replaces the [processors](./UsingProcessors.md) applied to the binding.

Example: `"invert,normalize(min=0,max=10)"`| -|[`interactions`](xref:UnityEngine.InputSystem.InputBinding.interactions)|[`overrideInteractions`](xref:UnityEngine.InputSystem.InputBinding.overrideInteractions)|Replaces the [interactions](xref:input-system-interactions) applied to the binding.

Example: `"tap(duration=0.5)"`| - -> [!NOTE] -> The `override` property values are not saved with the actions, for example, when calling [`InputActionAsset.ToJson()`](xref:UnityEngine.InputSystem.InputActionAsset.ToJson)). Refer to [Saving and loading rebinds](#save-and-load-rebinds) for details about how to persist user rebinds. - -To set the various `override` properties, you can use the [`ApplyBindingOverride`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.ApplyBindingOverride(UnityEngine.InputSystem.InputAction,UnityEngine.InputSystem.InputBinding)) APIs. - -```CSharp -// Rebind the "fire" action to the left trigger on the gamepad. -playerInput.actions["fire"].ApplyBindingOverride("/leftTrigger"); -``` - -In most cases, it is best to locate specific bindings using APIs such as [`GetBindingIndexForControl`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.GetBindingIndexForControl*) and to then apply the override to that specific binding. - -```CSharp -// Find the "Jump" binding for the space key. -var jumpAction = playerInput.actions["Jump"]; -var bindingIndex = jumpAction.GetBindingIndexForControl(Keyboard.current.spaceKey); - -// And change it to the enter key. -jumpAction.ApplyBindingOverride(bindingIndex, "/enter"); -``` - -#### Erase bindings - -You can erase a binding by calling [`Erase`](xref:UnityEngine.InputSystem.InputActionSetupExtensions.BindingSyntax.Erase*) on the [binding accessor](xref:UnityEngine.InputSystem.InputActionSetupExtensions.BindingSyntax). - -```CSharp -// Erase first binding on "fire" action. -playerInput.actions["fire"].ChangeBinding(0).Erase(); - -// Erase "2DVector" composite. This will also erase the part -// bindings of the composite. -playerInput.actions["move"].ChangeCompositeBinding("2DVector").Erase(); - -// Can also do this by using the name given to the composite binding. -playerInput.actions["move"].ChangeCompositeBinding("WASD").Erase(); - -// Erase first binding in "gameplay" action map. -playerInput.actions.FindActionMap("gameplay").ChangeBinding(0).Erase(); -``` - -#### Add bindings - -New bindings can be added to an action using [`AddBinding`](xref:UnityEngine.InputSystem.InputActionSetupExtensions.AddBinding(UnityEngine.InputSystem.InputAction,System.String,System.String,System.String,System.String)) or [`AddCompositeBinding`](xref:UnityEngine.InputSystem.InputActionSetupExtensions.AddCompositeBinding(UnityEngine.InputSystem.InputAction,System.String,System.String,System.String)). - -```CSharp -// Add a binding for the left mouse button to the "fire" action. -playerInput.actions["fire"].AddBinding("/leftButton"); - -// Add a WASD composite binding to the "move" action. -playerInput.actions["move"] - .AddCompositeBinding("2DVector") - .With("Up", "/w") - .With("Left", "/a") - .With("Down", "/s") - .With("Right", "/d"); -``` - -#### Set parameters - -A binding may, either through itself or through its associated action, lead to [processor](UsingProcessors.md), [interaction](xref:input-system-interactions), and/or [composite](#composite-bindings) objects being created. These objects can have parameters you can configure through in the [Binding properties view](xref:input-system-configuring-input#bindings) of the [Input Actions Editor](xref:input-system-configuring-input) or through the API. This configuration will give parameters their default value. - -```CSharp -// Create an action with a "Hold" interaction on it. -// Set the "duration" parameter to 4 seconds. -var action = new InputAction(interactions: "hold(duration=4)"); -``` - -You can query the current value of any such parameter using the [`GetParameterValue`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.GetParameterValue(UnityEngine.InputSystem.InputAction,System.String,UnityEngine.InputSystem.InputBinding)) API. - -```CSharp -// This returns a PrimitiveValue?. It will be null if the -// parameter is not found. Otherwise, it is a PrimitiveValue -// which can be converted to a number or boolean. -var p = action.GetParameterValue("duration"); -Debug.Log("'duration' is set to: " + p.Value); -``` - -The above looks for the parameter on any object found on any of the bindings on the action. You can restrict either or both to a more narrow set. - -```CSharp -// Retrieve the value of the "duration" parameter specifically of a -// "Hold" interaction and only look on bindings in the "Gamepad" group. -action.GetParameterValue("hold:duration", InputBinding.MaskByGroup("Gamepad")); -``` - -Alternatively, you can use an expression parameter to encapsulate both the type and the name of the parameter you want to get the value of. This has the advantage of not needing a string parameter but rather references both the type and the name of the parameter in a typesafe way. - -```CSharp -// Retrieve the value of the "duration" parameter of TapInteraction. -// This version returns a float? instead of a PrimitiveValue? as it -// sees the type of "duration" at compile-time. -action.GetParameterValue((TapInteraction x) => x.duration); -``` - -To alter the current value of a parameter, you can use what is referred to as a "parameter override". You can apply these at the level of an individual [`InputAction`](xref:UnityEngine.InputSystem.InputAction), or at the level of an entire [`InputActionMap`](xref:UnityEngine.InputSystem.InputActionMap), or even at the level of an entire [`InputActionAsset`](xref:UnityEngine.InputSystem.InputActionAsset). Such overrides are stored internally and applied automatically even on bindings added later. - -To add an override, use the [`ApplyParameterOverride`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.ApplyParameterOverride(UnityEngine.InputSystem.InputAction,System.String,UnityEngine.InputSystem.Utilities.PrimitiveValue,UnityEngine.InputSystem.InputBinding)) API or any of its overloads. - -```CSharp -// Set the "duration" parameter on all bindings of the action to 4. -action.ApplyParameterOverride("duration", 4f); - -// Set the "duration" parameter specifically for "tap" interactions only. -action.ApplyParameterOverride("tap:duration", 0.5f); - -// Set the "duration" parameter on tap interactions but only for bindings -// in the "Gamepad" group. -action.ApplyParameterOverride("tap:duration", 0.5f, InputBinding.MaskByGroup("Gamepad"); - -// Set tap duration for all bindings in an action map. -map.ApplyParameterOverride("tap:duration", 0.5f); - -// Set tap duration for all bindings in an entire asset. -asset.ApplyParameterOverride("tap:duration", 0.5f); - -// Like for GetParameterValue, overloads are available that take -// an expression instead. -action.ApplyParameterOverride((TapInteraction x) => x.duration, 0.4f); -map.ApplyParameterOverride((TapInteraction x) => x.duration, 0.4f); -asset.ApplyParameterOverride((TapInteraction x) => x.duration, 0.4f); -``` - -The new value will be applied immediately and affect all composites, processors, and interactions already in use and targeted by the override. - -Note that if multiple parameter overrides are applied – especially when applying some directly to actions and some to maps or assets –, there may be conflicts between which override to apply. In this case, an attempt is made to chose the "most specific" override to apply. - -```CSharp -// Let's say you have an InputAction `action` that is part of an InputActionAsset asset. -var map = action.actionMap; -var asset = map.asset; - -// And you apply a "tap:duration" override to the action. -action.ApplyParameterOverride("tap:duration", 0.6f); - -// But also apply a "tap:duration" override to the action specifically -// for bindings in the "Gamepad" group. -action.ApplyParameterOverride("tap:duration", 1f, InputBinding.MaskByGroup("Gamepad")); - -// And finally also apply a "tap:duration" override to the entire asset. -asset.ApplyParameterOverride("tap:duration", 0.3f); - -// Now, bindings on `action` in the "Gamepad" group will use a value of 1 for tap durations, -// other bindings on `action` will use 0.6, and every other binding in the asset will use 0.3. -``` - -You can use parameter overrides, for example, to scale mouse delta values on a "Look" action. - -```CSharp -// Set up an example "Look" action. -var look = new InputAction("look", type: InputActionType.Value); -look.AddBinding("/delta", groups: "KeyboardMouse", processors: "scaleVector2"); -look.AddBinding("/rightStick", groups: "Gamepad", processors: "scaleVector2"); - -// Now you can adjust stick sensitivity separately from mouse sensitivity. -look.ApplyParameterOverride("scaleVector2:x", 0.5f, InputBinding.MaskByGroup("KeyboardMouse")); -look.ApplyParameterOverride("scaleVector2:y", 0.5f, InputBinding.MaskByGroup("KeyboardMouse")); - -look.ApplyParameterOverride("scaleVector2:x", 2f, InputBinding.MaskByGroup("Gamepad")); -look.ApplyParameterOverride("scaleVector2:y", 2f, InputBinding.MaskByGroup("Gamepad")); - -// Alternative to using groups, you can also apply overrides directly to specific binding paths. -look.ApplyParameterOverride("scaleVector2:x", 0.5f, new InputBinding("/delta")); -look.ApplyParameterOverride("scaleVector2:y", 0.5f, new InputBinding("/delta")); -``` - -> [!NOTE] -> Parameter overrides are *not* persisted along with an asset. - -### Interactive rebinding - -> [!NOTE] -> To download a sample project which demonstrates how to set up a rebinding user interface with Input System APIs, open the Package Manager, select the Input System Package, and choose the sample project "Rebinding UI" to download. - -Runtime rebinding allows users of your application to set their own bindings. - -To allow users to choose their own bindings interactively, use the [`InputActionRebindingExtensions.RebindingOperation`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.RebindingOperation) class. Call the [`PerformInteractiveRebinding()`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.PerformInteractiveRebinding(UnityEngine.InputSystem.InputAction,System.Int32)) method on an action to create a rebinding operation. This operation waits for the Input System to register any input from any device which matches the action's expected control type, then uses [`InputBinding.overridePath`](xref:UnityEngine.InputSystem.InputBinding.overridePath) to assign the control path for that control to the action's bindings. If the user actuates multiple controls, the rebinding operation chooses the control with the highest [magnitude](xref:input-system-controls#control-actuation). - -> [!IMPORTANT] -> You must dispose of [`InputActionRebindingExtensions.RebindingOperation`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.RebindingOperation) instances via `Dispose()`, so that they don't leak memory on the unmanaged memory heap. - -```C# - void RemapButtonClicked(InputAction actionToRebind) - { - var rebindOperation = actionToRebind - .PerformInteractiveRebinding().Start(); - } -``` - -The [`InputActionRebindingExtensions.RebindingOperation`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.RebindingOperation) API is highly configurable to match your needs. For example, you can: - -* Choose expected control types ([`WithExpectedControlType()`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.RebindingOperation.WithExpectedControlType(System.Type))). - -* Exclude certain controls ([`WithControlsExcluding()`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.RebindingOperation.WithControlsExcluding(System.String))). - -* Set a control to cancel the operation ([`WithCancelingThrough()`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.RebindingOperation.WithCancelingThrough(UnityEngine.InputSystem.InputControl))). - -* Choose which bindings to apply the operation on if the action has multiple bindings ([`WithTargetBinding()`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.RebindingOperation.WithTargetBinding(System.Int32)), [`WithBindingGroup()`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.RebindingOperation.WithBindingGroup(System.String)), [`WithBindingMask()`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.RebindingOperation.WithBindingMask(System.Nullable{UnityEngine.InputSystem.InputBinding}))). - -Refer to the scripting API reference for [`InputActionRebindingExtensions.RebindingOperation`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.RebindingOperation) for a full overview. - -Note that [`PerformInteractiveRebinding()`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.PerformInteractiveRebinding(UnityEngine.InputSystem.InputAction,System.Int32)) automatically applies a set of default configurations based on the given action and targeted binding. - -### Save and load rebinds - -You can serialize override properties of [bindings](xref:UnityEngine.InputSystem.InputBinding) by serializing them as JSON strings and restoring them from these. Use [`SaveBindingOverridesAsJson`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.SaveBindingOverridesAsJson(UnityEngine.InputSystem.IInputActionCollection2)) to create these strings and [`LoadBindingOverridesFromJson`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.LoadBindingOverridesFromJson(UnityEngine.InputSystem.IInputActionCollection2,System.String,System.Boolean)) to restore overrides from them. - -```CSharp -// Store player rebinds in PlayerPrefs. -var rebinds = playerInput.actions.SaveBindingOverridesAsJson(); -PlayerPrefs.SetString("rebinds", rebinds); - -// Restore player rebinds from PlayerPrefs (removes all existing -// overrides on the actions; pass `false` for second argument -// in case you want to prevent that). -var rebinds = PlayerPrefs.GetString("rebinds"); -playerInput.actions.LoadBindingOverridesFromJson(rebinds); -``` - -#### Restore original bindings - -You can remove binding overrides and thus restore defaults by using [`RemoveBindingOverride`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.RemoveBindingOverride(UnityEngine.InputSystem.InputAction,System.Int32)) or [`RemoveAllBindingOverrides`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.RemoveAllBindingOverrides(UnityEngine.InputSystem.IInputActionCollection2)). - -```CSharp -// Remove binding overrides from the first binding of the "fire" action. -playerInput.actions["fire"].RemoveBindingOverride(0); - -// Remove all binding overrides from the "fire" action. -playerInput.actions["fire"].RemoveAllBindingOverrides(); - -// Remove all binding overrides from a player's actions. -playerInput.actions.RemoveAllBindingOverrides(); -``` - -#### Display bindings - -It can be useful for the user to know what an action is currently bound to (taking any potentially active rebindings into account) while rebinding UIs, and for on-screen hints while the app is running. You can use [`InputBinding.effectivePath`](xref:UnityEngine.InputSystem.InputBinding.effectivePath) to get the currently active path for a binding (which returns [`overridePath`](xref:UnityEngine.InputSystem.InputBinding.overridePath) if set, or otherwise returns [`path`](xref:UnityEngine.InputSystem.InputBinding.path)). - -The easiest way to retrieve a display string for an action is to call [`InputActionRebindingExtensions.GetBindingDisplayString`](xref:UnityEngine.InputSystem.InputActionRebindingExtensions.GetBindingDisplayString*) which is an extension method for [`InputAction`](xref:UnityEngine.InputSystem.InputAction). - -```CSharp - // Get a binding string for the action as a whole. This takes into account which - // bindings are currently active and the actual controls bound to the action. - m_RebindButton.GetComponentInChildren().text = action.GetBindingDisplayString(); - - // Get a binding string for a specific binding on an action by index. - m_RebindButton.GetComponentInChildren().text = action.GetBindingDisplayString(1); - - // Look up binding indices with GetBindingIndex. - var bindingIndex = action.GetBindingIndex(InputBinding.MaskByGroup("Gamepad")); - m_RebindButton.GetComponentInChildren().text = - action.GetBindingDisplayString(bindingIndex); -``` - -You can also use this method to replace the text string with images. - -```CSharp - // Call GetBindingDisplayString() such that it also returns information about the - // name of the device layout and path of the control on the device. This information - // is useful for reliably associating imagery with individual controls. - // NOTE: The first argument is the index of the binding within InputAction.bindings. - var bindingString = action.GetBindingDisplayString(0, out deviceLayout, out controlPath); - - // If it's a gamepad, look up an icon for the control. - Sprite icon = null; - if (!string.IsNullOrEmpty(deviceLayout) - && !string.IsNullOrEmpty(controlPath) - && InputSystem.IsFirstLayoutBasedOnSecond(deviceLayout, "Gamepad")) - { - switch (controlPath) - { - case "buttonSouth": icon = aButtonIcon; break; - case "dpad/up": icon = dpadUpIcon; break; - //... - } - } - - // If you have an icon, display it instead of the text. - var text = m_RebindButton.GetComponentInChildren(); - var image = m_RebindButton.GetComponentInChildren(); - if (icon != null) - { - // Display icon. - text.gameObject.SetActive(false); - image.gameObject.SetActive(true); - image.sprite = icon; - } - else - { - // Display text. - text.gameObject.SetActive(true); - image.gameObject.SetActive(false); - text.text = bindingString; - } -``` - -Additionally, each binding has a [`ToDisplayString`](xref:UnityEngine.InputSystem.InputBinding.ToDisplayString(UnityEngine.InputSystem.InputBinding.DisplayStringOptions,UnityEngine.InputSystem.InputControl)) method, which you can use to turn individual bindings into display strings. There is also a generic formatting method for control paths, [`InputControlPath.ToHumanReadableString`](xref:UnityEngine.InputSystem.InputControlPath.ToHumanReadableString(System.String,UnityEngine.InputSystem.InputControlPath.HumanReadableStringOptions,UnityEngine.InputSystem.InputControl)), which you can use with arbitrary control path strings. - -Note that the controls a binding resolves to can change at any time, and the display strings for controls might change dynamically. For example, if the user switches the currently active keyboard layout, the display string for each individual key on the [`Keyboard`](xref:UnityEngine.InputSystem.Keyboard) might change. - -## Control schemes - -A binding can belong to any number of binding groups. Unity stores these on the [`InputBinding`](xref:UnityEngine.InputSystem.InputBinding) class as a semicolon-separated string in the [`InputBinding.groups`](xref:UnityEngine.InputSystem.InputBinding.groups) property, and you can use them for any arbitrary grouping of bindings. To enable different sets of binding groups for an [`InputActionMap`](xref:UnityEngine.InputSystem.InputActionMap) or [`InputActionAsset`](xref:UnityEngine.InputSystem.InputActionAsset), you can use the [`InputActionMap.bindingMask`](xref:UnityEngine.InputSystem.InputActionMap.bindingMask)/[`InputActionAsset.bindingMask`](xref:UnityEngine.InputSystem.InputActionAsset.bindingMask) property. The Input System uses this to implement the concept of grouping bindings into different [`InputControlSchemes`](xref:UnityEngine.InputSystem.InputControlScheme). - -Control Schemes use binding groups to map bindings in an [`InputActionMap`](xref:UnityEngine.InputSystem.InputActionMap) or [`InputActionAsset`](xref:UnityEngine.InputSystem.InputActionAsset) to different types of devices. The [`PlayerInput`](xref:input-system-player-input) class uses these to enable a matching control scheme for a new [user](xref:input-system-user-management) joining the game, based on the device they are playing on. - -## Details - -### Binding resolution - -When the Input System accesses the [controls](xref:input-system-controls) bound to an action for the first time, the action resolves its bindings to match them to existing controls on existing devices. In this process, the action calls [`InputSystem.FindControls<>()`](xref:UnityEngine.InputSystem.InputSystem.FindControls``1(System.String,UnityEngine.InputSystem.InputControlList{``0}@)) (filtering for devices assigned to the InputActionMap, if there are any) for the binding path of each of the action's bindings. This creates a list of resolved controls that are now bound to the action. - -Note that a single [binding path](xref:input-system-controls#control-paths) can match multiple controls: - -* A specific device path such as `/buttonEast` matches the "Circle" button on a [PlayStation controller](xref:input-system-gamepad#playstation-controllers). If you have multiple PlayStation controllers connected, it resolves to the "Circle" button on each of these controllers. - -* An abstract device path such as `/buttonEast` matches the right action button on any connected gamepad. If you have a PlayStation controller and an [Xbox controller](xref:input-system-gamepad#xbox-controllers) connected, it resolves to the "Circle" button on the PlayStation controller, and to the "B" button on the Xbox controller. - -* A binding path can also contain wildcards, such as `/button*`. This matches any control on any gamepad with a name starting with "button", which matches all the four action buttons on any connected gamepad. A different example: `*/{Submit}` matches any control tagged with the "Submit" [usage](xref:input-system-controls#control-usages) on any device. - -If there are multiple bindings on the same action that all reference the same control(s), the control will effectively feed into the action multiple times. This is to allow, for example, a single control to produce different input on the same action by virtue of being bound in a different fashion (composites, processors, interactions, etc). However, regardless of how many times a control is bound on any given action, it will only be mentioned once in the action's [array of `controls`](xref:UnityEngine.InputSystem.InputAction.controls). - -To query the controls that an action resolves to, you can use [`InputAction.controls`](xref:UnityEngine.InputSystem.InputAction.controls). You can also run this query if the action is disabled. - -To be notified when binding resolution happens, you can listen to [`InputSystem.onActionChange`](xref:UnityEngine.InputSystem.InputSystem.onActionChange) which triggers [`InputActionChange.BoundControlsAboutToChange`](xref:UnityEngine.InputSystem.InputActionChange.BoundControlsAboutToChange) before modifying control lists and triggers [`InputActionChange.BoundControlsChanged`](xref:UnityEngine.InputSystem.InputActionChange.BoundControlsChanged) after having updated them. - -#### Binding resolution while actions are enabled - -In certain situations, the [controls](xref:UnityEngine.InputSystem.InputAction.controls) bound to an action have to be updated more than once. For example, if a new [device](xref:input-system-devices) becomes usable with an action, the action may now pick up input from additional controls. Also, if bindings are added, removed, or modified, control lists will need to be updated. - -This updating of controls usually happens transparently in the background. However, when an action is [enabled](xref:UnityEngine.InputSystem.InputAction.enabled) and especially when it is [in progress](xref:UnityEngine.InputSystem.InputAction.IsInProgress*), there may be a noticeable effect on the action. - -Adding or removing a device – either [globally](xref:UnityEngine.InputSystem.InputSystem.devices) or to/from the [device list](xref:UnityEngine.InputSystem.InputActionAsset.devices) of an action – will remain transparent __except__ if an action is in progress and it is the device of its [active control](xref:UnityEngine.InputSystem.InputAction.activeControl) that is being removed. In this case, the action will automatically be [cancelled](xref:UnityEngine.InputSystem.InputAction.canceled). - -Modifying the [binding mask](xref:UnityEngine.InputSystem.InputActionAsset.bindingMask) or modifying any of the bindings (such as through [rebinding](#interactive-rebinding) or by adding or removing bindings) will, however, lead to all enabled actions being temporarily disabled and then re-enabled and resumed. - -#### Choose which devices to use - -> [!NOTE] -> [`InputUser`](xref:input-system-user-management) and [`PlayerInput`](xref:input-system-player-input) make use of this facility automatically. They set [`InputActionMap.devices`](xref:UnityEngine.InputSystem.InputActionMap.devices) automatically based on the devices that are paired to the user. - -By default, actions resolve their bindings against all devices present in the Input System (that is, [`InputSystem.devices`](xref:UnityEngine.InputSystem.InputSystem.devices)). For example, if there are two gamepads present in the system, a binding to `/buttonSouth` picks up both gamepads and allows the action to be used from either. - -You can override this behavior by restricting [`InputActionAssets`](xref:UnityEngine.InputSystem.InputActionAsset) or individual [`InputActionMaps`](xref:UnityEngine.InputSystem.InputActionMap) to a specific set of devices. If you do this, binding resolution only takes the controls of the given devices into account. - -``` - var actionMap = new InputActionMap(); - - // Restrict the action map to just the first gamepad. - actionMap.devices = new[] { Gamepad.all[0] }; -``` - -### Conflicting inputs - -There are two situations where a given input may lead to ambiguity: - -1. Several controls are bound to the same action and more than one is feeding input into the action at the same time. Example: an action that is bound to both the left and right trigger on a Gamepad and both triggers are pressed. -2. The input is part of a sequence of inputs and there are several possible such sequences. Example: one action is bound to the `B` key and another action is bound to `Shift-B`. - -#### Multiple, concurrently used controls - -> [!NOTE] -> This section does not apply to [`PassThrough`](xref:input-system-responding#pass-through) actions as they are by design meant to allow multiple concurrent inputs. - -For a [`Button`](xref:input-system-responding#button) or [`Value`](xref:input-system-responding#value) action, there can only be one control at any time that is "driving" the action. This control is considered the [`activeControl`](xref:UnityEngine.InputSystem.InputAction.activeControl). - -When an action is bound to multiple controls, the [`activeControl`](xref:UnityEngine.InputSystem.InputAction.activeControl) at any point is the one with the greatest level of ["actuation"](xref:input-system-controls#control-actuation), that is, the largest value returned from [`EvaluateMagnitude`](xref:UnityEngine.InputSystem.InputControl.EvaluateMagnitude*). If a control exceeds the actuation level of the current [`activeControl`](xref:UnityEngine.InputSystem.InputAction.activeControl), it will itself become the active control. - -The following example demonstrates this mechanism with a [`Button`](xref:input-system-responding#button) action and also demonstrates the difference to a [`PassThrough`](xref:input-system-responding#pass-through) action. - -```CSharp -// Create a button and a pass-through action and bind each of them -// to both triggers on the gamepad. -var buttonAction = new InputAction(type: InputActionType.Button, - binding: "/*Trigger"); -var passThroughAction = new InputAction(type: InputActionType.PassThrough, - binding: "/*Trigger"); - -buttonAction.performed += c => Debug.Log("${c.control.name} pressed (Button)"); -passThroughAction.performed += c => Debug.Log("${c.control.name} changed (Pass-Through)"); - -buttonAction.Enable(); -passThroughAction.Enable(); - -// Press the left trigger all the way down. -// This will trigger both buttonAction and passThroughAction. Both will -// see leftTrigger becoming the activeControl. -Set(gamepad.leftTrigger, 1f); - -// Will log -// "leftTrigger pressed (Button)" and -// "leftTrigger changed (Pass-Through)" - -// Press the right trigger halfway down. -// This will *not* trigger or otherwise change buttonAction as the right trigger -// is actuated *less* than the left one that is already driving action. -// However, passThrough action is not performing such tracking and will thus respond -// directly to the value change. It will perform and make rightTrigger its activeControl. -Set(gamepad.rightTrigger, 0.5f); - -// Will log -// "rightTrigger changed (Pass-Through)" - -// Release the left trigger. -// For buttonAction, this will mean that now all controls feeding into the action have -// been released and thus the button releases. activeControl will go back to null. -// For passThrough action, this is just another value change. So, the action performs -// and its active control changes to leftTrigger. -Set(gamepad.leftTrigger, 0f); - -// Will log -// "leftTrigger changed (Pass-Through)" -``` - -For [composite bindings](#composite-bindings), magnitudes of the composite as a whole rather than for individual controls are tracked. However, [`activeControl`](xref:UnityEngine.InputSystem.InputAction.activeControl) will stick track individual controls from the composite. - -##### Disable conflict resolution - -Conflict resolution is always applied to [Button](xref:input-system-responding#button) and [Value](xref:input-system-responding#value) type actions. However, it can be undesirable in situations when an action is simply used to gather any and all inputs from bound controls. For example, the following action would monitor the A button of all available gamepads: - -```CSharp -var action = new InputAction(type: InputActionType.PassThrough, binding: "/buttonSouth"); -action.Enable(); -``` - -By using the [Pass-Through](xref:input-system-responding#pass-through) action type, conflict resolution is bypassed and thus, pressing the A button on one gamepad will not result in a press on a different gamepad being ignored. - -#### Multiple input sequences (such as keyboard shortcuts) - -> [!NOTE] -> The mechanism described here only applies to actions that are part of the same [`InputActionMap`](xref:UnityEngine.InputSystem.InputActionMap) or [`InputActionAsset`](xref:UnityEngine.InputSystem.InputActionAsset). - -> [!NOTE] -> To use automatic composite complexity as described below, in **Project Settings** > **Input System Package**, enable __Complexity-Based Shortcut Resolution__ ([`InputSettings.shortcutKeysConsumeInput`](xref:UnityEngine.InputSystem.InputSettings.shortcutKeysConsumeInput)) and leave __Action Priority Shortcut Resolution__ ([`InputSettings.shortcutKeysUseActionPriority`](xref:UnityEngine.InputSystem.InputSettings.shortcutKeysUseActionPriority)) disabled. If __Action Priority Shortcut Resolution__ is enabled, overlaps are resolved using each action's [`InputAction.Priority`](xref:UnityEngine.InputSystem.InputAction.Priority) instead. Refer to [Input settings](xref:input-system-settings#improved-shortcut-support) for details. - -Inputs that are used in combinations with other inputs may also lead to ambiguities. If, for example, the `b` key on the Keyboard is bound both on its own as well as in combination with the `shift` key, then if you first press `shift` and then `b`, the latter key press would be a valid input for either of the actions. - -The way this is handled is that bindings will be processed in the order of decreasing "complexity". This metric is derived automatically from the binding: - -* A binding that is *not* part of a [composite](#composite-bindings) is assigned a complexity of 1. -* A binding that *is* part of a [composite](#composite-bindings) is assigned a complexity equal to the number of part bindings in the composite. - -In our example, this means that a [`OneModifier`](#one-modifier) composite binding to `Shift+B` has a higher "complexity" than a binding to `B` and thus is processed first. - -Additionally, the first binding that results in the action changing [phase](xref:input-system-responding#action-callbacks) will "consume" the input. This consuming will result in other bindings to the same input not being processed. So in our example, when `Shift+B` "consumes" the `B` input, the binding to `B` will be skipped. - -The following example illustrates how this works at the API level. - -```CSharp -// Create two actions in the same map. -var map = new InputActionMap(); -var bAction = map.AddAction("B"); -var shiftbAction = map.AddAction("ShiftB"); - -// Bind one of the actions to 'B' and the other to 'SHIFT+B'. -bAction.AddBinding("/b"); -shiftbAction.AddCompositeBinding("OneModifier") - .With("Modifier", "/shift") - .With("Binding", "/b"); - -// Print something to the console when the actions are triggered. -bAction.performed += _ => Debug.Log("B action performed"); -shiftbAction.performed += _ => Debug.Log("SHIFT+B action performed"); - -// Start listening to input. -map.Enable(); - -// Now, let's assume the left shift key on the keyboard is pressed (here, we manually -// press it with the InputTestFixture API). -Press(Keyboard.current.leftShiftKey); - -// And then the B is pressed. This is a valid input for both -// bAction as well as shiftbAction. -// -// What will happen now is that shiftbAction will do its processing first. In response, -// it will *perform* the action (i.e. we see the `performed` callback being invoked) and -// thus "consume" the input. bAction will stay silent as it will in turn be skipped over. -Press(keyboard.bKey); -``` - -### Initial state check - -After an action is [enabled](xref:UnityEngine.InputSystem.InputAction.enabled), it will start reacting to input as it comes in. However, at the time the action is enabled, one or more of the controls that are [bound](xref:UnityEngine.InputSystem.InputAction.controls) to an action may already have a non-default state at that point. - -Using what is referred to as an "initial state check", an action can be made to respond to such a non-default state as if the state change happened *after* the action was enabled. The way this works is that in the first input [update](xref:UnityEngine.InputSystem.InputSystem.Update*) after the action was enabled, all its bound controls are checked in turn. If any of them has a non-default state, the action responds right away. - -This check is implicitly enabled for [Value](xref:input-system-responding#value) actions. If, for example, you have a `Move` action bound to the left stick on the gamepad and the stick is already pushed in a direction when `Move` is enabled, the character will immediately start walking. - -By default, [Button](xref:input-system-responding#button) and [Pass-Through](xref:input-system-responding#pass-through) type actions, do not perform this check. A button that is pressed when its respective action is enabled first needs to be released and then pressed again for it to trigger the action. - -However, you can manually enable initial state checks on these types of actions using the checkbox in the Editor: - -![The Initial State Check setting appears with a checkmark under the Pass Through action on the Actions panel.](./Images/InitialStateCheck.png){width="486" height="116"} diff --git a/Packages/com.unity.inputsystem/Documentation~/Actions.md b/Packages/com.unity.inputsystem/Documentation~/Actions.md index 50b0d35821..1fd881d419 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Actions.md +++ b/Packages/com.unity.inputsystem/Documentation~/Actions.md @@ -3,178 +3,21 @@ uid: input-system-actions --- # Actions -**Actions** are an important concept in the Input System. They allow you to separate the purpose of an input from the device controls which perform that input. For example, the purpose of an input in a game might be to make the player's character move around. The device control associated with that action might be the motion of the left gamepad stick. +**Actions** allow you to separate the purpose of an input from the device controls which perform that input, and associate the purpose and device controls together in a flexible way. -To associate an action with one or more device controls, you set up [input bindings](xref:input-system-action-bindings) in the [Input Actions Editor](xref:input-system-configuring-input). Then you can refer to those actions in your code, instead of the specific devices. The input bindings define which device's controls are used to perform the action. For example this screenshot shows the "Move" action's bindings to the left gamepad stick and the keyboard's arrow keys. +For example, the purpose of an input in a game might be to make the player's character move. The device control associated with that action might be the left gamepad stick. -![](Images/ActionsBinding.png)
-*The Actions panel of the Input Actions Project Settings window* +To associate an action with one or more device controls, you set up input bindings in the [Input Actions Editor](actions-editor.md). Then you can refer to those actions in your code, instead of the specific devices. The input bindings define which device's controls are used to perform the action. For example this screenshot shows the "Move" action's bindings to the left gamepad stick and the keyboard's arrow keys. -When you get a reference to an action in your code, you can use it to check its value, or attach a callback method to be notified when it is performed. For a simple example script demonstrating this, refer to [Workflow Overview - Actions](xref:input-system-workflow-project-wide-actions). +![The Actions panel of the Input Actions Editor in Project Settings](Images/ActionsBinding.png)
+*The Actions panel of the Input Actions Editor in Project Settings* -Actions also make it simpler to create a system that lets your players [customize their bindings at runtime](xref:input-system-action-bindings#interactive-rebinding), which is a common requirement for games. +When you get a reference to an action in your code, you can use it to check its value, or attach a callback method to be notified when it is performed. For a simple example script demonstrating this, refer to [Workflow Overview - Actions](using-actions-workflow.md). + +Actions also make it simpler to create a system that lets your players [customize their bindings at runtime](rebind-action-runtime.md), which is a common requirement for games. > [!NOTE] -> - Actions are a runtime-only feature. You can't use them in [Editor window code](https://docs.unity3d.com/ScriptReference/EditorWindow.html). +> - Actions are a runtime only feature. You can't use them in [Editor window code](https://docs.unity3d.com/ScriptReference/EditorWindow.html). > -> - You can read input without using actions and bindings by directly reading specific device controls. This is less flexible, but can be quicker to implement for certain situations. For more information, refer to [Workflow Overview - Directly Reading Device States](xref:input-system-workflow-direct). +> - You can read input without using actions and bindings by directly reading specific device controls. This is less flexible, but can be quicker to implement for certain situations. Read more about [directly reading devices from script](using-direct-workflow.md). > -> - Although you can reorder actions in this window, the ordering is for visual convenience only, and does not affect the order in which the actions are triggered in your code. If multiple actions are performed in the same frame, the order in which they are reported by the Input System is undefined. To avoid problems, you should not write code that assumes they will be reported in a particular order. - - - -## Scripting access - -Here are several important APIs you can use to script with actions in the Input System: - -|API name|Description| -|-----|-----------| -|[`InputSystem.actions`](xref:UnityEngine.InputSystem.InputSystem)|A reference to the set of actions assigned as [project-wide actions](xref:project-wide-actions).| -|[`InputActionMap`](xref:UnityEngine.InputSystem.InputActionMap)|A named collection of input actions, treated as a group. This is the API equivalent to an entry in the "Action Maps" panel of the [Input Actions Editor](xref:input-system-configuring-input).| -|[`InputAction`](xref:UnityEngine.InputSystem.InputAction)|A named action that can return the current value of the controls that it is bound to, or can trigger callbacks in response to input. This is the API equivalent to an entry in the "Actions" panel of the [Input Actions Editor](xref:input-system-configuring-input).| -|[`InputBinding`](xref:UnityEngine.InputSystem.InputBinding)|The relationship between an action and the specific device controls for which it receives input. For more information about Bindings and how to use them, refer to [Input Bindings](xref:input-system-action-bindings).| - -Each action has a name ([`InputAction.name`](xref:UnityEngine.InputSystem.InputAction.name)), which must be unique within the action map that the action belongs to, if any (see [`InputAction.actionMap`](xref:UnityEngine.InputSystem.InputAction.actionMap)). Each action also has a unique ID ([`InputAction.id`](xref:UnityEngine.InputSystem.InputAction.id)), which you can use to reference the action. The ID remains the same even if you rename the action. - -Each action map has a name ([`InputActionMap.name`](xref:UnityEngine.InputSystem.InputActionMap.name)), which must also be unique with respect to the other action maps present, if any. Each action map also has a unique ID ([`InputActionMap.id`](xref:UnityEngine.InputSystem.InputActionMap.id)), which you can use to reference the action map. The ID remains the same even if you rename the action map. - -## Create actions - -Use the [Input Actions Editor](xref:input-system-configuring-input) in the Project Settings window to create actions. This is the recommended workflow if you want to organize all your input actions and bindings in one place, to apply across the whole project. This workflow works for most types of game or app. - -![Action Editor Window](Images/ProjectSettingsInputActionsSimpleShot.png) -*The Input Actions Editor in the Project Settings window* - -The Input System package API is open and flexible, which provides a lot of flexibility to suit less common scenarios. So if you want to customize your project beyond the standard workflow, you can use these alternative techniques to create actions: - -- [Declare actions in MonoBehaviour components](#declare-actions-in-monobehaviours) -- [Load actions from JSON data](#load-actions-from-json) -- [Create actions entirely in code](#create-actions-in-code) - - -### Declare actions in MonoBehaviours - -You can declare individual [`InputAction`](xref:UnityEngine.InputSystem.InputAction) and [`InputActionMap`](xref:UnityEngine.InputSystem.InputActionMap) objects as fields directly inside `MonoBehaviour` components. - -```CSharp -using UnityEngine; -using UnityEngine.InputSystem; - -public class ExampleScript : MonoBehaviour -{ - public InputAction move; - public InputAction jump; -} -``` - -The result is similar to using an action defined in the Input Actions Editor, except that you define the actions in the GameObject's properties and save them as scene or prefab data, instead of in a dedicated asset. - -When you define serialized `InputAction` fields in a `MonoBehaviour` component to embed actions, the GameObject's Inspector window displays a script component similar to the "Actions" panel of the [Input Actions Editor](xref:input-system-configuring-input): - -![The Move and Jump actions appear under the ExampleScript component with icons for editing, adding, and removing each action.](Images/Workflow-EmbeddedActionsInspector.png)
- - -This interface allows you to set up the bindings for those actions. For example: - -* To add or remove actions or bindings, select the Add (+) or Remove (-) icon on the action. -* To edit actions, select the gear icon on individual action properties. -* To edit bindings, double-click them. -* To open the context menu, right-click an entry. -* To duplicate an entry, hold the Alt key while dragging it. - -Unlike the project-wide actions in the Project Settings window, you must manually enable and disable actions and action maps that are embedded in MonoBehaviour components. - -When you use this workflow, the serialized action configurations are stored with the parent GameObject as part of the scene, instead of being serialized with an action asset. This can be useful if you want to bundle the control bindings and behavior together in a single MonoBehaviour or prefab, so it can be distributed together. However, this can also make it harder to organize your full set of control bindings if they are distributed across multiple prefabs or scenes. - -### Load actions from JSON - -You can load actions as JSON in the form of a set of action maps or as a full [`InputActionAsset`](xref:UnityEngine.InputSystem.InputActionAsset). This also works at runtime in the Player. - -```CSharp -// Load a set of action maps from JSON. -var maps = InputActionMap.FromJson(json); - -// Load an entire InputActionAsset from JSON. -var asset = InputActionAsset.FromJson(json); -``` - -### Create actions in code - -You can manually create and configure actions entirely in code, including assigning the bindings. This also works at runtime in the Player. For example: - -```CSharp -// Create free-standing actions. -var lookAction = new InputAction("look", binding: "/leftStick"); -var moveAction = new InputAction("move", binding: "/rightStick"); - -lookAction.AddBinding("/delta"); -moveAction.AddCompositeBinding("Dpad") - .With("Up", "/w") - .With("Down", "/s") - .With("Left", "/a") - .With("Right", "/d"); - -// Create an action map with actions. -var map = new InputActionMap("Gameplay"); -var lookAction = map.AddAction("look"); -lookAction.AddBinding("/leftStick"); - -// Create an action asset. -var asset = ScriptableObject.CreateInstance(); -var gameplayMap = new InputActionMap("gameplay"); -asset.AddActionMap(gameplayMap); -var lookAction = gameplayMap.AddAction("look", "/leftStick"); -``` - -Any action that you create in this way during Play mode doesn't persist in the input action asset after you exit Play mode. This means you can test your application in a realistic manner in the Editor without having to worry about inadvertently modifying the asset. - - -## Enable actions - -Actions have an **enabled** state, meaning you can enable or disable them to suit different situations. - -If you have an action asset assigned as [project-wide](xref:project-wide-actions), the actions it contains are enabled by default and ready to use. - -For actions defined elsewhere, such as in an action asset not assigned as project-wide, or defined your own code, they begin in a disabled state, and you must enable them before they will respond to input. - -You can enable actions individually, or as a group by enabling the action map which contains them. - -```CSharp -// Enable a single action. -lookAction.Enable(); - -// Enable an en entire action map. -gameplayActions.Enable(); -``` - -When you enable an action, the Input System resolves its bindings, unless it has done so already, or if the set of devices that the action can use has not changed. For more details about this process, refer to the documentation on [binding resolution](xref:input-system-action-bindings#binding-resolution). - -You can't change certain aspects of the configuration, such as action bindings, while an action is enabled. To stop actions or action maps from responding to input, call [`Disable`](xref:UnityEngine.InputSystem.InputAction.Disable). - -While enabled, an action actively monitors the [controls](xref:input-system-controls) it's bound to. If a bound control changes state, the action processes the change. If the control's change represents an [interaction](xref:input-system-interactions) change, the action creates a response. All of this happens during the Input System update logic. Depending on the [update mode](xref:input-system-settings#update-mode) selected in the input settings, this happens once every frame, once every fixed update, or manually if updates are set to manual. - -## Overlapping bindings and action priority - -When several enabled actions share the same physical control (for example a plain **B** key action and a **Shift**+**B** composite), the Input System can resolve which action should respond first using either complexity-based or priority-based resolution. Both modes are configured in **Project Settings** > **Input System Package** under [Improved Shortcut Support](xref:input-system-settings#improved-shortcut-support). - -Each action has a [`Priority`](xref:UnityEngine.InputSystem.InputAction.Priority) property. The range is from 0 to 65535, and is clamped when set. A higher value means a higher priority, notified first. - -The `Priority` value applies to all bindings on that action. Serialized priority is always stored on the asset; at runtime it's used only when **Action Priority Shortcut Resolution** is enabled. In that case, the **Priority** field is also shown in the [Input Actions Editor](xref:input-system-configuring-input). - -When action priority resolution is active: - -- Higher priority actions are notified before lower-priority actions on the same control. -- When an action reaches the Performed phase, priority `0 doesn't mark the input event as handled, so lower-priority actions in the same overlap group can still respond on that event. -- Any priority **greater than zero** can mark the event handled and suppress strictly lower-priority actions in the same group for that event. -- Actions with the **same** priority are not suppressed relative to each other; both can perform in the same update if their bindings fire. - -Set priority in code: - -```CSharp -fireAction.Priority = 10; -reloadAction.Priority = 5; -``` - -You can also edit the **Priority** field on an action in the Input Actions Editor when **Action Priority Shortcut Resolution** is enabled. - -For information about composite shortcuts and complexity ordering, refer to [Multiple input sequences (such as keyboard shortcuts)](xref:input-system-action-bindings#multiple-input-sequences-such-as-keyboard-shortcuts). diff --git a/Packages/com.unity.inputsystem/Documentation~/ActionsEditor.md b/Packages/com.unity.inputsystem/Documentation~/ActionsEditor.md deleted file mode 100644 index 07f34b4266..0000000000 --- a/Packages/com.unity.inputsystem/Documentation~/ActionsEditor.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -uid: input-system-configuring-input ---- -# Configuring input - -The **Input Actions Editor** allows you to edit [action assets](xref:input-system-action-assets), which contain a saved configuration of [input actions](xref:input-system-actions) and their associated [bindings](xref:input-system-action-bindings). - -It allows you to group collections of actions into [action maps](ActionsEditor.html#configure-action-maps), which represent different input scenarios in your project (such as UI navigation, gameplay, etc.) - -It also allows you to define [control schemes](xref:input-system-action-bindings#control-schemes) which are a way to enable or disable a set of devices, or respond to which type of device is being used. This is often useful if you want to customize your UI based on whether your users are using a mouse, keyboard, or gamepad as their chosen input. - -## Action assets and project-wide actions - -The typical workflow for most projects is to have a single action asset, which is assigned as the **project-wide actions**. Refer to [Project-Wide Actions](xref:project-wide-actions) to create and assign an actions asset as your project-wide action if you haven't already done this. - -## The Input Actions Editor window and panels - -The **Input Actions Editor** appears when you double-click an action asset to open it. - -It also appears in the Project Settings window under **Edit** > **Project Settings** > **Input System Package** if you have an action asset assigned as project-wide. - -![The Input Actions Editor displays the three panels and the default actions](./Images/ActionsEditorCallout.png) - -The Input Actions Editor is divided into three panels (marked A, B & C in the image above). - -|Panel name|Description| -|-|-| -|**(A) Action Maps**|Displays the list of currently defined action maps. Each action map is a collection of actions that you can enable or disable together as a group.| -|**(B) Actions**|Displays all the actions defined in the currently selected action map, and the bindings associated with each action.| -|**(C) Properties**|Displays the properties of the currently selected action or binding from the Actions panel. The title of this panel changes depending on whether you have an action or a binding selected in the Actions panel.| - -## Configure action maps - -* To add a new action map, select the Add (+) icon in the header of the __Action Maps__ panel. -* To rename an existing action map, either long-click the name, or right-click the action map and select __Rename__ from the context menu. Note that action map names can't contain slashes (`/`). -* To delete an existing action map, right-click it and select __Delete__ from the context menu. -* To duplicate an existing action map, right-click it and select __Duplicate__ from the context menu. - -## Configure actions - -* To add a new action, select the Add (+) icon in the header of the __Action__ column. -* To rename an existing action, either long-click the name, or right-click the action map and select __Rename__ from the context menu. -* To delete an existing action, either right-click it and select __Delete__ from the context menu. -* To duplicate an existing action, either right-click it and select __Duplicate__ from the context menu. - -## Edit action properties - -If you select an action, you can edit its properties in the __Action Properties__ panel on the right: - -![The Action Properties panel of the Input Actions Editor displays the Action, Interactions, and Processors groups expanded.](Images/ActionProperties.png) - -### Action Type - -Use the __Action Type__ setting to select **Button**, **Value** or **PassThrough**. - -These options relate to whether this action should represent a discrete on/off button-style interaction or a value that can change over time while the control is being used. - -For device controls such as keyboard keys, mouse clicks, or gamepad buttons, select **Button**. For device controls such as mouse movement, a joystick or gamepad stick, or device orientation that provide continuously changing input over a period of time, select **Value**. - -The Button and Value types of action also provides data about the action such as whether it has started and stopped, and conflict resolution in situations where multiple bindings are mapped to the same action. - -The third option, **PassThrough**, is also a value type, and as such is suitable for the same types of device controls as value. The difference is that actions set to PassThrough only provide basic information about the values incoming from the device controls bound to it, and does not provide the extra data relating to the phase of the action, nor does it perform conflict resolution in the case of multiple controls mapped to the same action. - -For details about how these types work, refer to [Action types](xref:input-system-responding#action-types) and [Default Interaction](xref:input-system-interactions#default-interaction). - -### Control Type - -The __Control Type__ setting allows you to select the type of control expected by the action. This limits the controls shown when setting up bindings in the UI and also limits which contols can be bound interactively to the action. - -For example, if you select **2D axis**, only those controls that can supply a 2D vector as value are available as options for the binding control path. - -There are more specific control types available which further filter the available bindings, such as "Stick", "Dpad" or "Touch". If you select one of these control types, the list of available controls is further limited to only those controls of those specific types when you select a binding for your action (see directly below). - -## Bindings - -* To add a new binding, select the Add (+) icon on the action you want to add it to, and select the binding type from the menu that appears. -* To delete an existing binding, either right-click it and select __Delete__ from the context menu. -* To duplicate an existing binding, either right-click it and select __Duplicate__ from the context menu. - -You can add multiple bindings to an action, which is generally useful for supporting multiple types of input device. For example, in the default set of actions, the "Move" action has a binding to the left gamepad stick and the WSAD keys, which means input through any of these bindings will perform the action. - -![](./Images/ActionWithMultipleBindings.png)
-_The default Move action in the Input Actions Editor, displaying the multiple bindings associated with it._ - -If you select a binding, you can edit its properties in the __Binding Properties__ panel on the right: - -![The Binding Properties panel displays the Path value as Left Stick [Gamepad].](Images/BindingProperties.png) - -### Set control paths - -The most important property of any binding is the [control path](xref:input-system-controls#control-paths) it's bound to. To edit it, open the __Path__ dropdown menu. This displays a control picker window. - -![The Binding Properties panel displays the control picker window available from the Path dropdown menu.](Images/InputControlPicker.png) - -In the control picker window, you can explore a tree of input devices and controls that the Input System recognizes, and bind to these controls. Unity filters this list by the action's [`expectedControlType`](xref:UnityEngine.InputSystem.InputAction.expectedControlType) property. For example, if the control type is `Vector2`, you can only select a control that generates two-dimensional values, like a stick. - -The device and control tree is organized hierarchically from generic to specific. For example, the __Gamepad__ control path `/buttonSouth` matches the lower action button on any gamepad. Alternatively, if you navigate to __Gamepad__ > __More Specific Gamepads__ and select __PS4 Controller__, and then choose the control path `/buttonSouth`, this only matches the "Cross" button on PlayStation gamepads, and doesn't match any other gamepads. - -Instead of browsing the tree to find the control you want, it's easier to let the Input System listen for input. To do that, select the __Listen__ button. At first, the list of Controls is empty. Once you start pressing buttons or actuating Controls on the Devices you want to bind to, the control picker window starts listing any bindings that match the controls you pressed. Select any of these bindings to view them. - -Finally, you can choose to manually edit the binding path, instead of using the control picker. To do that, select the __T__ button next to the control path popup. This changes the popup to a text field, where you can enter any binding string. This also allows you to use wildcard (`*`) characters in your bindings. For example, you can use a binding path such as `/touch*/press` to bind to any finger being pressed on the touchscreen, instead of manually binding to `/touch0/press`, `/touch1/press` and so on. - -### Edit composite bindings - -Composite bindings are bindings consisting of multiple parts, which form a control together. For instance, a [2D Vector Composite](xref:input-system-action-bindings#2d-vector) uses four buttons (left, right, up, down) to simulate a 2D stick input. Refer to [Composite bindings](xref:input-system-action-bindings#composite-bindings) to learn more. - -![The WASD setting appears under the Move property on the Actions panel.](Images/2DVectorComposite.png){width="486" height="178"} - - -To create a composite binding, in the Input Actions Editor, select the Add (+) icon on the action you want to add it to, and select the composite binding type from the popup menu. - -![The Add Up/Down/Left/Right Composite binding is selected for the Move property on the Actions panel.](Images/Add2DVectorComposite.png){width="486" height="199"} - -This creates multiple binding entries for the action: one for the Composite as a whole, and then, one level below that, one for each Composite part. The Composite itself doesn't have a binding path property, but its individual parts do, and you can edit these parts like any other binding. Once you bind all the Composite's parts, the Composite can work together as if you bound a single control to the action. - -> [!NOTE] -> The set of Composites displayed in the menu is depends on the value type of the action. This means that, for example, if the action is set to type "Button", then only Composites able to return values of type `float` will be shown. - -To change the type of a Composite retroactively, select the Composite, then select the new type from the **Composite Type** drop-down in the **Properties** pane. - -![The Composite Type binding is set to 2D Vector binding on the Actions panel.](./Images/CompositeType.png){width="486" height="184"} - -To change the part of the Composite to which a particular binding is assigned, use the **Composite Part** drop-down in the binding's properties. - -![The Composite Part binding is set to Up under the Path binding property.](./Images/CompositePart.png){width="486" height="161"} - -You can assign multiple bindings to the same part. You can also duplicate individual part bindings: right-click the binding, then select **Duplicate** to create new part bindings for the Composite. This can be used, for example, to create a single Composite for both "WASD" style controls and arrow keys. - -![The Keyboard setting under Move on the Actions panel displays duplicated part bindings.](./Images/DuplicatedPartBindings.png){width="486" height="214"} - -## Edit control schemes - -Input action assets can have multiple [control schemes](xref:input-system-action-bindings#control-schemes), which let you enable or disable different sets of bindings for your actions for different types of Devices. - -![Gamepad appears as the Scheme Name value on the Add Control Scheme window.](Images/ControlSchemeProperties.png) - -To see the control schemes in the Input Actions Editor, open the control scheme drop-down list in the top left of the window. This menu lets you add or remove control schemes to your actions asset. If the actions asset contains any control schemes, you can select a control scheme, and then the window only shows bindings that are associated with that scheme. If you select a binding, you can pick the control schemes for which this binding is active in the __Properties__ panel on the left. - -When you add a new control scheme, or select an existing control scheme, and then select __Edit Control Scheme__, you can edit the name of the control scheme and which devices the scheme should be active for. When you add a new control scheme, the "Device Type" list is empty by default (as shown above). You must add at least one type of device to this list for the control scheme to be functional. diff --git a/Packages/com.unity.inputsystem/Documentation~/Architecture.md b/Packages/com.unity.inputsystem/Documentation~/Architecture.md index bbd82ab672..a4530721a6 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Architecture.md +++ b/Packages/com.unity.inputsystem/Documentation~/Architecture.md @@ -9,9 +9,9 @@ The Input System has a layered architecture that consists of a low-level layer a The foundation of the Input System is the native backend code. This is platform-specific code which collects information about available Devices and input data from Devices. This code is not part of the Input System package, but is included with Unity itself. It has implementations for each runtime platform supported by Unity. This is why some platform-specific input bugs can only be fixed by an update to Unity, rather than a new version of the Input System package. -The Input System interfaces with the native backend using [events](xref:input-system-events) that the native backend sends. These events notify the system of the creation and removal of [Input Devices](xref:input-system-devices), as well as any updates to the Device states. For efficiency and to avoid creating any garbage, the native backend reports these events as a simple buffer of raw, unmanaged memory containing a stream of events. +The Input System interfaces with the native backend using [events](input-events.md) that the native backend sends. These events notify the system of the creation and removal of [Input Devices](devices.md), as well as any updates to the Device states. For efficiency and to avoid creating any garbage, the native backend reports these events as a simple buffer of raw, unmanaged memory containing a stream of events. -The Input System can also send data back to the native backend in the form of [commands](xref:input-system-devices#device-commands) sent to Devices, which are also buffers of memory that the native backend interprets. These commands can have different meanings for different Device types and platforms. +The Input System can also send data back to the native backend in the form of [commands](device-commands.md) sent to Devices, which are also buffers of memory that the native backend interprets. These commands can have different meanings for different Device types and platforms. # Input System (low-level) @@ -19,7 +19,7 @@ The Input System can also send data back to the native backend in the form of [c The low-level Input System code processes and interprets the memory from the event stream that the native backend provides, and dispatches individual events. -The Input System creates Device representations for any newly discovered Device in the event stream. The low-level code sees a Device as a block of raw, unmanaged memory. If it receives a state event for a Device, it writes the data from the state event into the Device's [state representation](xref:input-system-controls#control-state) in memory, so that the state always contains an up-to-date representation of the Device and all its Controls. +The Input System creates Device representations for any newly discovered Device in the event stream. The low-level code sees a Device as a block of raw, unmanaged memory. If it receives a state event for a Device, it writes the data from the state event into the Device's [state representation](control-state.md) in memory, so that the state always contains an up-to-date representation of the Device and all its Controls. The low-level system code also contains structs which describe the data layout of commonly known Devices. @@ -27,8 +27,8 @@ The low-level system code also contains structs which describe the data layout o ![High-Level Architecture](Images/InputArchitectureHighLevel.png) -The high-level Input System code interprets the data in a Device's state buffers by using [layouts](xref:input-system-layouts), which describe the data layout of a Device and its Controls in memory. The Input System creates layouts from either the pre-defined structs of commonly known Devices supplied by the low level system, or dynamically at runtime, as in the case of [generic HIDs](xref:input-system-hid#auto-generated-layouts). +The high-level Input System code interprets the data in a Device's state buffers by using [layouts](layouts.md), which describe the data layout of a Device and its Controls in memory. The Input System creates layouts from either the pre-defined structs of commonly known Devices supplied by the low level system, or dynamically at runtime, as in the case of [generic HIDs](hid-specification.md). -Based on the information in the layouts, the Input System then creates [Control](xref:input-system-controls) representations for each of the Device's controls, which let you read the state of each individual Control in a Device. +Based on the information in the layouts, the Input System then creates [Control](controls.md) representations for each of the Device's controls, which let you read the state of each individual Control in a Device. -As part of the high-level system, you can also build another abstraction layer to map Input Controls to your application mechanics. Use [Actions](xref:input-system-actions) to [bind](xref:input-system-action-bindings) one or more Controls to an input in your application. The Input System then monitors these Controls for state changes, and notifies your game logic using [callbacks](xref:input-system-responding#responding-to-actions-using-callbacks). You can also specify more complex behaviors for your Actions using [Processors](UsingProcessors.md) (which perform processing on the input data before sending it to you) and [Interactions](xref:input-system-interactions) (which let you specify patterns of input on a Control to listen to, such as multi-taps). +As part of the high-level system, you can also build another abstraction layer to map Input Controls to your application mechanics. Use [Actions](actions.md) to [bind](bindings.md) one or more Controls to an input in your application. The Input System then monitors these Controls for state changes, and notifies your game logic using [callbacks](set-callbacks-on-actions.md). You can also specify more complex behaviors for your Actions using [Processors](processors.md) (which perform processing on the input data before sending it to you) and [Interactions](Interactions.md) (which let you specify patterns of input on a Control to listen to, such as multi-taps). diff --git a/Packages/com.unity.inputsystem/Documentation~/Concepts.md b/Packages/com.unity.inputsystem/Documentation~/Concepts.md deleted file mode 100644 index e9bb07c058..0000000000 --- a/Packages/com.unity.inputsystem/Documentation~/Concepts.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -uid: basic-concepts ---- -# Basic Concepts - -This page introduces the basic concepts that relate to working with the Input System. They relate to the steps in the sequence of events that occur when a user sends input to your game or app. The Input System provides features which implement these steps, or you can choose to implement some of them yourself. - -![A flowchart showing the general workflow of the Input System, with icons representing the different concepts. It starts with the User icon, which then leads into the Input Device and its Controls icon. This then leads into the Action Map and Actions concept. The Input Device and Action Map and Actions icons are collectively grouped under the Binding header. This leads into the final icon representing your action code.](Images/ConceptsOverview.png) - -|Concept|Description| -|-------|-----------| -|[**User**](UserManagement.html)| The person playing your game or using your app, by holding or touching the input device and providing input.| -|[**Input Device**](SupportedDevices.html)| Often referred to just as a "**device**" within the context of input. A physical piece of hardware, such as a keyboard, gamepad, mouse, or touchscreen which allows the user to send input into Unity.| -|[**Control**](Controls.html)|The separate individual parts of an input device which each send input values into Unity. For example, a gamepad’s **controls** comprise multiple buttons, sticks and triggers, and a mouse’s controls include the two X and Y sensors on the underside, and the various buttons and scroll wheels on the top side.| -|[**Action**](Actions.html)| Actions are a high-level concept that describe individual things that a user might want to do in your game or app, such as "Jump" within a game, or "Select" in an on-screen UI. They are things a user can do in your game or app as a result of input, regardless of what device or control they use to perform it. Actions generally have conceptual names that you choose to suit your project, and should usually be verbs. For example "Run", "Jump" "Crouch", "Use", "Start", "Quit".| -|[**Action Map**](ActionsEditor.html#configure-action-maps) | Action Maps allow you to organize Actions into groups which represent specific situations where a set of actions make sense together. You can simultaneously enable or disable all Actions in an action map, so it is useful to group Actions in Action Maps by the context in which they are relevant. For example, you might have one action map for controlling a player, and another for interacting with your game's UI.| -|[**Binding**](ActionBindings.html)| A connection defined between an **Action** and specific device controls. There are two main types of bindings:
  • **Normal** bindings directly bind to control(s) by means of a [control path](xref:input-system-controls#control-paths). At runtime, any path that matches one or multiple controls will feed input into the binding.
  • **Composite** bindings don't bind to controls themselves. Instead, they receive their input from their **Part** bindings and then return a value representing a composition of those inputs. For example, the right trigger on the gamepad can act as a strength multiplier on the value of the left stick.
| -|[**Your Action Code**](xref:input-system-responding)| The part of your script which is executed based on the actions you have configured. In your code, you can use references to actions to either read the current value or state of the action (also known as "polling"), or set up a callback to call your own method when actions are performed.| -|[**Action Asset**](xref:input-system-action-assets) | An asset type which contains a saved configuration of Action Maps, Actions and Bindings. You can specify one Action Asset in your project as the [project-wide actions](xref:project-wide-actions), which allows you to easily reference those actions in code by using [`InputSystem.actions`](xref:UnityEngine.InputSystem.InputSystem). | diff --git a/Packages/com.unity.inputsystem/Documentation~/Contributing.md b/Packages/com.unity.inputsystem/Documentation~/Contributing.md index 6696dba1a1..434fc3bec0 100644 --- a/Packages/com.unity.inputsystem/Documentation~/Contributing.md +++ b/Packages/com.unity.inputsystem/Documentation~/Contributing.md @@ -1,7 +1,7 @@ --- uid: input-system-contributing --- -# Contributing +# Contribute to the Input System source code The [full source code](https://github.com/Unity-Technologies/InputSystem) for the Input System is available on GitHub. This is also where most of the Input System's development happens. diff --git a/Packages/com.unity.inputsystem/Documentation~/Controls.md b/Packages/com.unity.inputsystem/Documentation~/Controls.md deleted file mode 100644 index 806adfb003..0000000000 --- a/Packages/com.unity.inputsystem/Documentation~/Controls.md +++ /dev/null @@ -1,312 +0,0 @@ ---- -uid: input-system-controls ---- -# Controls - -An input control represents a source of values. These values can be of any structured or primitive type. The only requirement is that the type is [blittable](https://docs.microsoft.com/en-us/dotnet/framework/interop/blittable-and-non-blittable-types). - -> [!NOTE] -> Controls are for input only. Output and configuration items on input devices are not represented as controls. - -## Identification - -Each control is identified by its [name](xref:UnityEngine.InputSystem.InputControl.name). Optionally, it can also have a different [display name](xref:UnityEngine.InputSystem.InputControl.displayName). For example, the right-hand face button closest to the touchpad on a PlayStation DualShock 4 controller has the control name "buttonWest" and the display name "Square". - -Additionally, a control might have one or more aliases which provide alternative names for the control. You can access the aliases for a specific control through its [`aliases`](xref:UnityEngine.InputSystem.InputControl.aliases) property. - -Finally, a control might also have a short display name which can be accessed through the [`shortDisplayName`](xref:UnityEngine.InputSystem.InputControl.shortDisplayName) property. For example, the short display name for the left mouse button is "LMB". - -## Control hierarchies - -Controls can form hierarchies. The root of a control hierarchy is always a [device](xref:input-system-devices). - -The setup of hierarchies is exclusively controlled through [layouts](xref:input-system-layouts). - -You can access the parent of a control using its [`parent`](xref:UnityEngine.InputSystem.InputControl.parent) property, and its children using [`children`](xref:UnityEngine.InputSystem.InputControl.children). To access the flattened hierarchy of all controls on a device, use [`allControls`](xref:UnityEngine.InputSystem.InputDevice.allControls). - -## Control types - -All controls are based on the [`InputControl`](xref:UnityEngine.InputSystem.InputControl) base class. Most concrete implementations are based on [InputControl](xref:UnityEngine.InputSystem.InputControl`1). - -The Input System provides the following types of controls out of the box: - -|Control Type|Description|Example| -|------------|-----------|-------| -|[`AxisControl`](xref:UnityEngine.InputSystem.Controls.AxisControl)|A 1D floating-point axis.|[`Gamepad.leftStick.x`](xref:UnityEngine.InputSystem.Controls.Vector2Control.x)| -|[`ButtonControl`](xref:UnityEngine.InputSystem.Controls.ButtonControl)|A button expressed as a floating-point value. Whether the button can have a value other than 0 or 1 depends on the underlying representation. For example, gamepad trigger buttons can have values other than 0 and 1, but gamepad face buttons generally can't.|[`Mouse.leftButton`](xref:UnityEngine.InputSystem.Mouse.leftButton)| -|[`KeyControl`](xref:UnityEngine.InputSystem.Controls.KeyControl)|A specialized button that represents a key on a [`Keyboard`](xref:UnityEngine.InputSystem.Keyboard). Keys have an associated [`keyCode`](xref:UnityEngine.InputSystem.Controls.KeyControl.keyCode) and, unlike other types of controls, change their display name in accordance to the currently active system-wide keyboard layout. See the [Keyboard](xref:input-system-keyboard) documentation for details.|[`Keyboard.aKey`](xref:UnityEngine.InputSystem.Keyboard.aKey)| -|[`Vector2Control`](xref:UnityEngine.InputSystem.Controls.Vector2Control)|A 2D floating-point vector.|[`Pointer.position`](xref:UnityEngine.InputSystem.Pointer.position)| -|[`Vector3Control`](xref:UnityEngine.InputSystem.Controls.Vector3Control)|A 3D floating-point vector.|[`Accelerometer.acceleration`](xref:UnityEngine.InputSystem.Accelerometer.acceleration)| -|[`QuaternionControl`](xref:UnityEngine.InputSystem.Controls.QuaternionControl)|A 3D rotation.|[`AttitudeSensor.attitude`](xref:UnityEngine.InputSystem.AttitudeSensor.attitude)| -|[`IntegerControl`](xref:UnityEngine.InputSystem.Controls.IntegerControl)|An integer value.|[`Touchscreen.primaryTouch.touchId`](xref:UnityEngine.InputSystem.Controls.TouchControl.touchId)| -|[`StickControl`](xref:UnityEngine.InputSystem.Controls.StickControl)|A 2D stick control like the thumbsticks on gamepads or the stick control of a joystick.|[`Gamepad.rightStick`](xref:UnityEngine.InputSystem.Gamepad.rightStick)| -|[`DpadControl`](xref:UnityEngine.InputSystem.Controls.DpadControl)|A 4-way button control like the D-pad on gamepads or hatswitches on joysticks.|[`Gamepad.dpad`](xref:UnityEngine.InputSystem.Gamepad.dpad)| -|[`TouchControl`](xref:UnityEngine.InputSystem.Controls.TouchControl)|A control that represents all the properties of a touch on a [touch screen](xref:input-system-touch).|[`Touchscreen.primaryTouch`](xref:UnityEngine.InputSystem.Touchscreen.primaryTouch)| - -You can browse the set of all registered control layouts in the [input debugger](xref:input-system-debugging#debugging-layouts). - -## Control usages - -A control can have one or more associated usages. A usage is a string that denotes the control's intended use. An example of a control usage is `Submit`, which labels a control that is commonly used to confirm a selection in the UI. On a gamepad, this usage is commonly found on the `buttonSouth` control. - -You can access a control's usages using the [`InputControl.usages`](xref:UnityEngine.InputSystem.InputControl.usages) property. - -Usages can be arbitrary strings. However, a certain set of usages is very commonly used and comes predefined in the API in the [`CommonUsages`](xref:UnityEngine.InputSystem.CommonUsages) static class. - -## Control paths - -The Input System can look up controls using textual paths. [Bindings](xref:input-system-action-bindings) on Input Actions rely on this feature to identify the control(s) they read input from. For example, `/leftStick/x` means "X control on left stick of gamepad". However, you can also use them for lookup directly on controls and devices, or to let the Input System search for controls among all devices using [`InputSystem.FindControls`](xref:UnityEngine.InputSystem.InputSystem.FindControls(System.String)): - -```CSharp -var gamepad = Gamepad.all[0]; -var leftStickX = gamepad["leftStick/x"]; -var submitButton = gamepad["{Submit}"]; -var allSubmitButtons = InputSystem.FindControls("*/{Submit}"); -``` - -Control paths resemble file system paths: they contain components separated by a forward slash (`/`): - - component/component... - -Each component itself contains a set of [fields](#component-fields) with its own syntax. Each field is individually optional, provided that at least one of the fields is present as either a name or a wildcard: - -```structured text -{usageName}#(displayName)controlName -``` - -You can access the literal path of a given control via its [`InputControl.path`](xref:UnityEngine.InputSystem.InputControl.path) property. If you need to, you can manually parse a control path into its components using the [`InputControlPath.Parse(path)`](xref:UnityEngine.InputSystem.InputControlPath.Parse(System.String)) API: - -```CSharp -var parsed = InputControlPath.Parse("{LeftHand}/trigger").ToArray(); - -Debug.Log(parsed.Length); // Prints 2. -Debug.Log(parsed[0].layout); // Prints "XRController". -Debug.Log(parsed[0].name); // Prints an empty string. -Debug.Log(parsed[0].usages.First()); // Prints "LeftHand". -Debug.Log(parsed[1].layout); // Prints null. -Debug.Log(parsed[1].name); // Prints "trigger". -``` - -### Component fields - -All fields are case-insensitive. - -The following table explains the use of each field: - -|Field|Description|Related links| -|-----|-----|------------------| -|`layoutName`|The name of the layout that the control must be based on. The actual layout of the control may be the same or a layout *based* on the given layout. For example, ``.|The [Layouts](xref:input-system-layouts) user manual topic

The [InputControlLayout](xref:UnityEngine.InputSystem.Layouts.InputControlLayout) class| -|`usageName`|Works differently for controls and devices:
  • When used on a device (the first component of a path), it requires the device to have the given usage. For example, `{LeftHand}/trigger`.
  • For looking up a control, the usage field is currently restricted to the path component immediately following the device (the second component in the path). It finds the control on the device that has the given usage. The control can be anywhere in the control hierarchy of the device. For example, `/{Submit}`.
|The [Device usages](xref:input-system-devices#device-usages) user manual topic

The [Control usages](#control-usages) topic on this page<

The [InputControl.usages](xref:UnityEngine.InputSystem.Layouts.InputControlLayout) property| -|`displayName`|Requires the control at the current level to have the given display name. The display name may contain whitespace and symbols. For example:
  • `/#(a)` matches the key that generates the "a" character, if any, according to the current keyboard layout.
  • `/#(Cross)` matches the button named "Cross" on the Gamepad.
|The [Identification](#identification) topic on this page

The [InputControl.displayName](xref:UnityEngine.InputSystem.InputControl.displayName) property| -|`controlName`|Requires the control at the current level to have the given name. Takes both "proper" names such as `MyGamepad/buttonSouth`, and aliases such as `MyGamepad/South` into account.

This field can also be a wildcard (`*`) to match any name. For example, `*/{PrimaryAction}` matches any `PrimaryAction` usage on devices with any name.|The [Identification](#identification) topic on this page

The [InputControl.name](xref:UnityEngine.InputSystem.InputControl.name) property for "proper" names

The [InputControl.aliases](xref:UnityEngine.InputSystem.InputControl.aliases) property for aliases| - -Here are several examples of control paths: - -```csharp -// Matches all gamepads (also gamepads *based* on the Gamepad layout): -"" -// Matches the "Submit" control on all devices: -"*/" -// Matches the key that prints the "a" character on the current keyboard layout: -"/#(a)" -// Matches the X axis of the left stick on a gamepad. -"/leftStick/x" -// Matches the orientation control of the right-hand XR controller: -"/orientation" -// Matches all buttons on a gamepad. -"/