|
1 | 1 |
|
2 | | -## Binding conflict resolution |
| 2 | +# Binding conflicts |
3 | 3 |
|
4 | | -For Value type actions, the Input System continuously monitors all the Controls which are bound to the Action, and then chooses the one which is the most actuated to be the Control driving the Action, and report the values from that Control in callbacks, triggered whenever the value changes. If a different bound Control actuated more, then that Control becomes the Control driving the Action, and the Action starts reporting values from that Control. This process is called conflict resolution. This is useful if you want to allow different Controls to control an Action in the game, but only take input from one Control at the same time. |
| 4 | +A binding conflict is when an [action](./actions.md) with more than one [control](./controls.md) [bound](./bindings.md) to it recieves values from multiple controls. |
5 | 5 |
|
6 | | -For more information, see: [Dealing with binding conflicts](./dealing-with-binding-conflicts.md). |
| 6 | +For example, if the left and right triggers of a gamepad are both bound to an "accelerate" action in your game, each trigger could be pressed in to different amounts. This conflict of recieving two different values for the same action is resolved by the Input System. |
7 | 7 |
|
| 8 | +## Conflict Resolution |
8 | 9 |
|
| 10 | +For [value type actions](./action-and-control-types.md), the Input System continuously monitors all the controls bound to the action, and then chooses the one which is the **most actuated** to be the control driving the action. Most actuated means the largest absolute value is being reported, whether positive or negative in the case of a 1D axis, and regardless of direction in the case of 2D and 3D axes. The value of the most actuated control is reported in callbacks, and triggered whenever the value changes. |
9 | 11 |
|
10 | | -There are two situations where a given input may lead to ambiguity: |
| 12 | +If a different bound control is actuated more, that control becomes the control driving the action. This process is called **conflict resolution**. This is useful if you want to allow different Controls to control an Action in the game, but only take input from one Control at the same time. |
11 | 13 |
|
12 | | -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. |
13 | | -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`. |
14 | | - |
15 | | -#### Multiple, concurrently used Controls |
16 | | - |
17 | | ->__Note:__ This section does not apply to [`PassThrough`](RespondingToActions.md#pass-through) Actions as they are by design meant to allow multiple concurrent inputs. |
18 | | -
|
19 | | -For a [`Button`](RespondingToActions.md#button) or [`Value`](RespondingToActions.md#value) Action, there can only be one Control at any time that is "driving" the Action. This Control is considered the [`activeControl`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_activeControl). |
| 14 | +## Ambiguous situations |
20 | 15 |
|
21 | | -When an Action is bound to multiple Controls, the [`activeControl`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_activeControl) at any point is the one with the greatest level of ["actuation"](Controls.md#control-actuation), that is, the largest value returned from [`EvaluateMagnitude`](../api/UnityEngine.InputSystem.InputControl.html#UnityEngine_InputSystem_InputControl_EvaluateMagnitude_). If a Control exceeds the actuation level of the current [`activeControl`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_activeControl), it will itself become the active Control. |
22 | | - |
23 | | -The following example demonstrates this mechanism with a [`Button`](RespondingToActions.md#button) Action and also demonstrates the difference to a [`PassThrough`](RespondingToActions.md#pass-through) Action. |
24 | | - |
25 | | -```CSharp |
26 | | -// Create a button and a pass-through action and bind each of them |
27 | | -// to both triggers on the gamepad. |
28 | | -var buttonAction = new InputAction(type: InputActionType.Button, |
29 | | - binding: "<Gamepad>/*Trigger"); |
30 | | -var passThroughAction = new InputAction(type: InputActionType.PassThrough, |
31 | | - binding: "<Gamepad>/*Trigger"); |
| 16 | +There are two situations where a given input might lead to ambiguity: |
32 | 17 |
|
33 | | -buttonAction.performed += c => Debug.Log("${c.control.name} pressed (Button)"); |
34 | | -passThroughAction.performed += c => Debug.Log("${c.control.name} changed (Pass-Through)"); |
35 | | - |
36 | | -buttonAction.Enable(); |
37 | | -passThroughAction.Enable(); |
38 | | - |
39 | | -// Press the left trigger all the way down. |
40 | | -// This will trigger both buttonAction and passThroughAction. Both will |
41 | | -// see leftTrigger becoming the activeControl. |
42 | | -Set(gamepad.leftTrigger, 1f); |
43 | | - |
44 | | -// Will log |
45 | | -// "leftTrigger pressed (Button)" and |
46 | | -// "leftTrigger changed (Pass-Through)" |
47 | | -
|
48 | | -// Press the right trigger halfway down. |
49 | | -// This will *not* trigger or otherwise change buttonAction as the right trigger |
50 | | -// is actuated *less* than the left one that is already driving action. |
51 | | -// However, passThrough action is not performing such tracking and will thus respond |
52 | | -// directly to the value change. It will perform and make rightTrigger its activeControl. |
53 | | -Set(gamepad.rightTrigger, 0.5f); |
| 18 | +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. |
| 19 | +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`. |
54 | 20 |
|
55 | | -// Will log |
56 | | -// "rightTrigger changed (Pass-Through)" |
| 21 | +## Multiple concurrently used controls |
57 | 22 |
|
58 | | -// Release the left trigger. |
59 | | -// For buttonAction, this will mean that now all controls feeding into the action have |
60 | | -// been released and thus the button releases. activeControl will go back to null. |
61 | | -// For passThrough action, this is just another value change. So, the action performs |
62 | | -// and its active control changes to leftTrigger. |
63 | | -Set(gamepad.leftTrigger, 0f); |
| 23 | +>__Note:__ This section does not apply to [pass-through](./configure-action-type.md) actions, which do not perform conflict resolution, and are intended allow multiple concurrent inputs. |
64 | 24 |
|
65 | | -// Will log |
66 | | -// "leftTrigger changed (Pass-Through)" |
67 | | -``` |
| 25 | +For a **Button** or **Value** [action type](./configure-action-type.md), there can only be one control at any time that is "driving" the action. This control is considered the [`activeControl`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_activeControl). |
68 | 26 |
|
69 | | -For [composite bindings](#composite-bindings), magnitudes of the composite as a whole rather than for individual Controls are tracked. However, [`activeControl`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_activeControl) will stick track individual Controls from the composite. |
| 27 | +When an action is bound to multiple controls, the active control at any point is the one with the greatest level of ["actuation"](./control-actuation.md) (the one with the largest value returned from [`EvaluateMagnitude`](../api/UnityEngine.InputSystem.InputControl.html#UnityEngine_InputSystem_InputControl_EvaluateMagnitude_)). If a different control exceeds the actuation level of the current active control, it becomes the active control. |
70 | 28 |
|
71 | | -##### Disabling Conflict Resolution |
| 29 | +For [composite bindings](./composite-bindings.md), magnitudes of the composite as a whole rather than for individual controls are tracked. However, [`activeControl`](../api/UnityEngine.InputSystem.InputAction.html#UnityEngine_InputSystem_InputAction_activeControl) will still track individual Controls from the composite. |
72 | 30 |
|
73 | | -Conflict resolution is always applied to [Button](RespondingToActions.md#button) and [Value](RespondingToActions.md#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: |
| 31 | +## Disabling Conflict Resolution |
74 | 32 |
|
75 | | -```CSharp |
76 | | -var action = new InputAction(type: InputActionType.PassThrough, binding: "<Gamepad>/buttonSouth"); |
77 | | -action.Enable(); |
78 | | -``` |
| 33 | +Conflict resolution is always applied to **Button** or **Value** [action types](./configure-action-type.md). However, it can be undesirable in situations when an action is simply used to gather all inputs from bound Controls. For example, if you have a **Button** type action bound to the **A** button on all gamepads, a user holding down **A** on one gamepad means that the **A** button on other gamepads is ignored. |
79 | 34 |
|
80 | | -By using the [Pass-Through](RespondingToActions.md#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. |
| 35 | +By using the **Pass Through** action type, conflict resolution is bypassed, which means pressing the **A** button on one gamepad will not result in presses on other gamepads being ignored. |
81 | 36 |
|
82 | | -#### Multiple input sequences (such as keyboard shortcuts) |
| 37 | +## Multiple input sequences (such as keyboard shortcuts) |
83 | 38 |
|
84 | | ->__Note__: The mechanism described here only applies to Actions that are part of the same [`InputActionMap`](../api/UnityEngine.InputSystem.InputActionMap.html) or [`InputActionAsset`](../api/UnityEngine.InputSystem.InputActionAsset.html). |
| 39 | +>__Note__: The mechanism described here only applies to Actions that are part of the same [action map](./action-maps-panel.md) or [action assets](./action-assets.md). |
85 | 40 |
|
86 | | -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. |
| 41 | +Inputs used in combinations with other inputs can 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. |
87 | 42 |
|
88 | | -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: |
| 43 | +The way the Input System handles this, is that Bindings are processed in the order of decreasing complexity. This metric is derived automatically from the Binding: |
89 | 44 |
|
90 | | -* A binding that is *not* part of a [composite](#composite-bindings) is assigned a complexity of 1. |
91 | | -* A binding that *is* part of a [composite](#composite-bindings) is assigned a complexity equal to the number of part bindings in the composite. |
| 45 | +* A binding that is *not* part of a [composite](composite-bindings.md) is assigned a complexity of 1. |
| 46 | +* A binding that *is* part of a [composite](composite-bindings.md) is assigned a complexity equal to the number of part bindings in the composite. |
92 | 47 |
|
93 | | -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. |
| 48 | +In our example, this means that a **one-modifier composite** binding to **Shift** + **B** has a higher complexity than a Binding to **B** and gets processed first. |
94 | 49 |
|
95 | | -Additionally, the first Binding that results in the Action changing [phase](RespondingToActions.md#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. |
| 50 | +Additionally, the first Binding that results in the Action changing [phase](./set-callbacks-on-actions.md) will consume the input. This results in other Bindings to the same input not being processed. This means in our example, when the **Shift** + **B** binding consumes the **B** input, the Binding to **B** is skipped. |
96 | 51 |
|
97 | 52 | The following example illustrates how this works at the API level. |
98 | 53 |
|
|
0 commit comments