Enum InputActionType
Determines the behavior with which an InputAction triggers.
Namespace: UnityEngine.InputSystem
Syntax
public enum InputActionType
Remarks
While all actions essentially function the same way, there are differences in how an action will react to changes in values on the controls it is bound to.
The most straightforward type of behavior is PassThrough which does not expect any kind of value change pattern but simply triggers the action on every single value change. A pass-through action will not use started or canceled except on bindings that have an interaction added to them. Pass-through actions are most useful for sourcing input from arbitrary many controls and simply piping all input through without much processing on the side of the action.
// An action that triggers every time any button on the gamepad is
// pressed or released.
var action = new InputAction(
type: InputActionType.PassThrough,
binding: "<Gamepad>/<Button>");
action.performed +=
ctx =>
{
var button = (ButtonControl)ctx.control;
if (button.wasPressedThisFrame)
Debug.Log($"Button {ctx.control} was pressed");
else if (button.wasReleasedThisFrame)
Debug.Log($"Button {ctx.control} was released");
// NOTE: We may get calls here in which neither the if nor the else
// clause are true here. A button like the gamepad left and right
// triggers, for example, do not just have a binary on/off state
// but rather a [0..1] value range.
};
action.Enable();
Note that pass-through actions do not perform any kind of disambiguation of input which makes them great for just forwarding input from any connected controls but makes them a poor choice when only one input should be generated from however many connected controls there are. For more details, see here.
The other two behavior types are Button and Value.
A Value action starts (started) as soon as its input moves away from its default value. After that it immediately performs (performed) and every time the input changes value it performs again except if the input moves back to the default value -- in which case the action cancels (canceled).
Also, unlike both Button and PassThrough actions, Value actions perform what's called "initial state check" on the first input update after the action was enabled. What this does is check controls bound to the action and if they are already actuated (that is, at non-default value), the action will immediately be started and performed. What this means in practice is that when a value action is bound to, say, the left stick on a gamepad and the stick is already moved out of its resting position, then the action will immediately trigger instead of first requiring the stick to be moved slightly.
Button and PassThrough actions, on the other hand, perform no such initial state check. For buttons, for example, this means that if a button is already pressed when an action is enabled, it first has to be released and then pressed again for the action to be triggered.
// An action that starts when the left stick on the gamepad is actuated
// and stops when the stick is released.
var action = new InputAction(
type: InputActionType.Value,
binding: "<Gamepad>/leftStick");
action.started +=
ctx =>
{
Debug.Log("--- Stick Starts ---");
};
action.performed +=
ctx =>
{
Debug.Log("Stick Value: " + ctx.ReadValue<Vector2D>();
};
action.canceled +=
ctx =>
{
Debug.Log("# Stick Released");
};
action.Enable();
A Button action essentially operates like a Value action except that it does not perform an initial state check.
One final noteworthy difference of both Button and Value compared to PassThrough is that both of them perform what is referred to as "disambiguation" when multiple actions are bound to the control. PassThrough does not care how many controls are bound to the action -- it simply passes every input through as is, no matter where it comes from.
Button and Value, on the other hand, will treat input differently
if it is coming from several sources at the same time. Note that this can only happen when there
are multiple controls bound to a single actions -- either by a single binding resolving to
more than one control (e.g. "*/{PrimaryAction}"
) or by multiple bindings all targeting
the same action and being active at the same time. If only a single control is bound to an
action, then the disambiguation code is automatically bypassed.
Disambiguation works the following way: when an action has not yet been started, it will react to the first input that has a non-default value. Once it receives such an input, it will start tracking the source of that input. While the action is in-progress, if it receives input from a source other than the control it is currently tracking, it will check whether the input has a greater magnitude (see EvaluateMagnitude()) than the control the action is already tracking. If so, the action will switch from its current control to the control with the stronger input.
Note that this process does also works in reverse. When the control currently driving the action lowers its value below that of another control that is also actuated and bound to the action, the action will switch to that control.
Put simply, a Button or Value action bound to multiple controls will always track the control with the strongest input.
Fields
Name | Description | Value |
---|---|---|
Button | An action that acts as a trigger. A button action has a defined trigger point that corresponds to Performed. After being performed, the action goes back to waiting state to await the next triggering. Note that a button action may still use Started and does not necessarily trigger immediately on input. For example, if HoldInteraction is used, the action will start as soon as a bound button crosses its press threshold but will not trigger until the button is held for the set hold duration (duration). Irrespective of which type an action is set to, it is possible to find out whether it was or is considered pressed and/or released using IsPressed(), WasPressedThisFrame(), and WasReleasedThisFrame().
|
|
PassThrough | An action that has no specific type of behavior and instead acts as a simple pass-through for any value change on any bound control. In effect, this turns an action from a single value producer into a mere input "sink". This is in some ways similar to Value. However, there are two key differences. For one, the action will not perform any disambiguation when bound to multiple controls concurrently. This means that if, for example, the action is bound to both the left and the right stick on a Gamepad, and the left stick goes to (0.5,0.5) and the right stick then goes to (0.25,0.25), the action will perform twice yielding a value of (0.5,0.5) first and a value of (0.25, 0.25) next. This is different from Value where upon actuation to (0.5,0.5), the left stick would get to drive the action and the actuation of the right stick would be ignored as it does not exceed the magnitude of the actuation on the left stick. The second key difference is that only Performed is used and will get triggered on every value change regardless of what the value is. This is different from Value where the action will trigger Started when moving away from its default value and will trigger Canceled when going back to the default value. Note that a pass-through action my still get cancelled and thus see canceled getting called. This happens when a factor other than input on a device causes an action in progress to be cancelled. An example of this is when an action is disabled (see Disable()) or when focus is lost (see backgroundBehavior) and a device connection to an action is reset (see ResetDevice(InputDevice, Boolean)). Also note that for a pass-through action, calling ReadValue<TValue>() is often not very useful as it will only return the value of the very last control that fed into the action. For pass-through actions, it is usually best to listen to performed in order to be notified about every single value change. Where this is not necessary, it is generally better to employ a Value action instead. |
|
Value | An action that reads a single value from its connected sources. If multiple bindings actuate at the same time, performs disambiguation (see ../manual/ActionBindings.html#disambiguation) to detect the highest value contributor at any one time. A value action starts (Started) and then performs (Performed) as soon as a bound control changes to a non-default value. For example, if an action is bound to leftStick and the stick moves from (0,0) to (0.5,0.5), the action starts and performs. After being started, the action will perform on every value change that is not the default value. In the example here, if the stick goes to (0.75,0.75) and then to (1,1), the action will perform twice. Finally, if the control value changes back to the default value, the action is canceled (Canceled). Meaning that if the stick moves back to (0,0), canceled will be triggered. |