docs.unity.cn

Input System 1.6.1

    Show / Hide Table of Contents

    Class InputSystem

    This is the central hub for the input system.

    Inheritance
    Object
    InputSystem
    Namespace: UnityEngine.InputSystem
    Syntax
    public static class InputSystem
    Remarks

    This class has the central APIs for working with the input system. You can manage devices available in the system (AddDevice<TDevice>(String), devices, onDeviceChange and related APIs) or extend the input system with custom functionality (RegisterLayout<T>(String, Nullable<InputDeviceMatcher>), RegisterInteraction<T>(String), RegisterProcessor<T>(String), RegisterBindingComposite<T>(String), and related APIs).

    To control haptics globally, you can use PauseHaptics(), ResumeHaptics(), and ResetHaptics().

    To enable and disable individual devices (such as Sensor devices), you can use EnableDevice(InputDevice) and DisableDevice(InputDevice, Boolean).

    The input system is initialized as part of Unity starting up. It is generally safe to call the APIs here from any of Unity's script callbacks.

    Note that, like most Unity APIs, most of the properties and methods in this API can only be called on the main thread. However, select APIs like QueueEvent(InputEventPtr) can be called from threads. Where this is the case, it is stated in the documentation.

    Properties

    devices

    The list of currently connected devices.

    Declaration
    public static ReadOnlyArray<InputDevice> devices { get; }
    Property Value
    Type Description
    ReadOnlyArray<InputDevice>

    Currently connected devices.

    Remarks

    Note that accessing this property does not allocate. It gives read-only access directly to the system's internal array of devices.

    The value returned by this property should not be held on to. When the device setup in the system changes, any value previously returned by this property may become invalid. Query the property directly whenever you need it.

    See Also
    AddDevice<TDevice>(String)
    RemoveDevice(InputDevice)

    disconnectedDevices

    Devices that have been disconnected but are retained by the input system in case they are plugged back in.

    Declaration
    public static ReadOnlyArray<InputDevice> disconnectedDevices { get; }
    Property Value
    Type Description
    ReadOnlyArray<InputDevice>

    Devices that have been retained by the input system in case they are plugged back in.

    Remarks

    During gameplay it is undesirable to have the system allocate and release managed memory as devices are unplugged and plugged back in as it would ultimately lead to GC spikes during gameplay. To avoid that, input devices that have been reported by the UnityEngine.InputSystem.LowLevel.IInputRuntime and are removed through DeviceRemoveEvent are retained by the system and then reused if the device is plugged back in.

    Note that the devices moved to disconnected status will still see a Removed notification and a Added notification when plugged back in.

    To determine if a newly discovered device is one we have seen before, the system uses a simple approach of comparing InputDeviceDescription. Note that there can be errors and a device may be incorrectly classified as Reconnected when in fact it is a different device from before. The problem is that based on information made available by platforms, it can be inherently difficult to determine whether a device is indeed the very same one.

    For example, it is often not possible to determine with 100% certainty whether an identical looking device to one we've previously seen on a different USB port is indeed the very same device. OSs will usually reattach a USB device to its previous instance if it is plugged into the same USB port but create a new instance of the same device is plugged into a different port.

    For devices that do relay their serial the matching is reliable.

    The list can be purged by calling FlushDisconnectedDevices(). Doing so, will release all reference we hold to the devices or any controls inside of them and allow the devices to be reclaimed by the garbage collector.

    Note that if you call RemoveDevice(InputDevice) explicitly, the given device is not retained by the input system and will not appear on this list.

    Also note that devices on this list will be lost when domain reloads happen in the editor (i.e. on script recompilation and when entering play mode).

    See Also
    FlushDisconnectedDevices()

    metrics

    Get various up-to-date metrics about the input system.

    Declaration
    public static InputMetrics metrics { get; }
    Property Value
    Type Description
    InputMetrics

    Up-to-date metrics on input system activity.

    onAnyButtonPress

    Listen through onEvent for a button to be pressed.

    Declaration
    public static IObservable<InputControl> onAnyButtonPress { get; }
    Property Value
    Type Description
    IObservable<InputControl>
    Remarks

    The listener will get triggered whenever a ButtonControl on any device in the list of devices goes from not being pressed to being pressed.

    // Response to the first button press. Calls our delegate
    // and then immediately stops listening.
    InputSystem.onAnyButtonPress
        .CallOnce(ctrl => Debug.Log($"Button {ctrl} was pressed"));

    Note that the listener will get triggered from the first button that was found in a pressed state in a given InputEvent. If multiple buttons are pressed in an event, the listener will not get triggered multiple times. To get all button presses in an event, use GetAllButtonPresses(InputEventPtr, Single, Boolean) and instead listen directly through onEvent.

    InputSystem.onEvent
        .Where(e => e.HasButtonPress())
        .CallOnce(eventPtr =>
        {
            foreach (var button in l.eventPtr.GetAllButtonPresses())
                Debug.Log($"Button {button} was pressed");
        });

    There is a certain overhead to listening for button presses so it is best to have listeners installed only while the information is actually needed.

    // Script that will spawn a new player when a button on a device is pressed.
    public class JoinPlayerOnPress : MonoBehaviour
    {
        // We instantiate this GameObject to create a new player object.
        // Expected to have a PlayerInput component in its hierarchy.
        public GameObject playerPrefab;
    
        // We want to remove the event listener we install through InputSystem.onAnyButtonPress
        // after we're done so remember it here.
        private IDisposable m_EventListener;
    
        // When enabled, we install our button press listener.
        void OnEnable()
        {
            // Start listening.
            m_EventListener =
                InputSystem.onAnyButtonPress
                    .Call(OnButtonPressed)
        }
    
        // When disabled, we remove our button press listener.
        void OnDisable()
        {
            m_EventListener.Dispose();
        }
    
        void OnButtonPressed(InputControl button)
        {
            var device = button.device;
    
            // Ignore presses on devices that are already used by a player.
            if (PlayerInput.FindFirstPairedToDevice(device) != null)
                return;
    
            // Create a new player.
            var player = PlayerInput.Instantiate(playerPrefab, pairWithDevice: device);
    
            // If the player did not end up with a valid input setup,
            // unjoin the player.
            if (player.hasMissingRequiredDevices)
                Destroy(player);
    
            // If we only want to join a single player, could uninstall our listener here
            // or use CallOnce() instead of Call() when we set it up.
        }
    }
    See Also
    isPressed
    onEvent

    onEvent

    Called during Update() for each event that is processed.

    Declaration
    public static InputEventListener onEvent { get; set; }
    Property Value
    Type Description
    InputEventListener
    Remarks

    Every time the input system updates (see updateMode or Update() for details about when and how this happens), it flushes all events from the internal event buffer.

    As the Input System reads events from the buffer one by one, it will trigger this callback for each event which originates from a recognized device, before then proceeding to process the event. If any of the callbacks sets handled to true, the event will be skipped and ignored.

    Note that a device that is disabled (see enabled) may still get this event signalled for it. A DisableDeviceCommand will usually be sent to backends when a device is disabled but a backend may or may not respond to the command and thus may or may not keep sending events for the device.

    Note that the Input System does NOT sort events by timestamps (time). Instead, they are consumed in the order they are produced. This means that they will also surface on this callback in that order.

    // Treat left+right mouse button as middle mouse button.
    // (Note: This example is more for demonstrative purposes; it isn't necessarily a good use case)
    InputSystem.onEvent +=
       (eventPtr, device) =>
       {
           // Only deal with state events.
           if (!eventPtr.IsA<StateEvent>())
               return;
    
           if (!(device is Mouse mouse))
               return;
    
           mouse.leftButton.ReadValueFromEvent(eventPtr, out var lmbDown);
           mouse.rightButton.ReadValueFromEvent(eventPtr, out var rmbDown);
    
           if (lmbDown > 0 && rmbDown > 0)
               mouse.middleButton.WriteValueIntoEvent(1f, eventPtr);
       };

    The property returns an InputEventListener struct that, beyond adding and removing callbacks, can be used to flexibly listen in on the event stream.

    // Listen for mouse events.
    InputSystem.onEvent
        .ForDevice(Mouse.current)
        .Call(e => Debug.Log("Mouse event"));

    If you are looking for a way to capture events, InputEventTrace may be of interest and an alternative to directly hooking into this event.

    If you are looking to monitor changes to specific input controls, state change monitors (see AddChangeMonitor(InputControl, IInputStateChangeMonitor, Int64, UInt32) are usually a more efficient and convenient way to set this up.

    Exceptions
    Type Condition
    ArgumentNullException

    Delegate reference is null.

    See Also
    QueueEvent(InputEventPtr)
    InputEvent
    Update()
    updateMode

    pollingFrequency

    Frequency at which devices that need polling are being queried in the background.

    Declaration
    public static float pollingFrequency { get; set; }
    Property Value
    Type Description
    Single

    Polled device sampling frequency in Hertz.

    Remarks

    Input data is gathered from platform APIs either as events or polled periodically.

    In the former case, where we get input as events, the platform is responsible for monitoring input devices and sending their state changes which the Unity runtime receives and queues as InputEvents. This form of input collection usually happens on a system-specific thread (which may be Unity's main thread) as part of how the Unity player loop operates. In most cases, this means that this form of input will invariably get picked up once per frame.

    In the latter case, where input has to be explicitly polled from the system, the Unity runtime will periodically sample the state of input devices and send it off as input events. Wherever possible, this happens in the background at a fixed frequency on a dedicated thread. The pollingFrequency property controls the rate at which this sampling happens.

    The unit is Hertz. A value of 120, for example, means that devices are sampled 120 times per second.

    The default polling frequency is 60 Hz.

    For devices that are polled, the frequency setting will directly translate to changes in the time patterns. At 60 Hz, for example, timestamps for a specific, polled device will be spaced at roughly 1/60th of a second apart.

    Note that it depends on the platform which devices are polled (if any). On Win32, for example, only XInput gamepads are polled.

    Also note that the polling frequency applies to all devices that are polled. It is not possible to set polling frequency on a per-device basis.

    remoting

    The local InputRemoting instance which can mirror local input to a remote input system or can make input in a remote system available locally.

    Declaration
    public static InputRemoting remoting { get; }
    Property Value
    Type Description
    InputRemoting
    Remarks

    In the editor, this is always initialized. In players, this will be null if remoting is disabled (which it is by default in release players).

    settings

    The current configuration of the input system.

    Declaration
    public static InputSettings settings { get; set; }
    Property Value
    Type Description
    InputSettings

    Global configuration object for the input system.

    Remarks

    The input system can be configured on a per-project basis. Settings can either be created and installed on the fly or persisted as assets in the project.

    Exceptions
    Type Condition
    ArgumentNullException

    Value is null when setting the property.

    version

    The current version of the input system package.

    Declaration
    public static Version version { get; }
    Property Value
    Type Description
    Version

    Current version of the input system.

    Methods

    AddDevice(String, String, String)

    Add a new device by instantiating the given device layout.

    Declaration
    public static InputDevice AddDevice(string layout, string name = null, string variants = null)
    Parameters
    Type Name Description
    String layout

    Name of the layout to instantiate. Must be a device layout. Note that layout names are case-insensitive.

    String name

    Name to assign to the device. If null, the layout's display name (displayName is used instead. Note that device names are made unique automatically by the system by appending numbers to them (e.g. "gamepad", "gamepad1", "gamepad2", etc.).

    String variants

    Semicolon-separated list of layout variants to use for the device.

    Returns
    Type Description
    InputDevice

    The newly created input device.

    Remarks

    The device will be added to the devices list and a notification on onDeviceChange will be triggered.

    Note that adding a device to the system will allocate and also create garbage on the GC heap.

    // This is one way to instantiate the "Gamepad" layout.
    InputSystem.AddDevice("Gamepad");
    
    // In this case, because the "Gamepad" layout is based on the Gamepad
    // class, we can also do this instead:
    InputSystem.AddDevice<Gamepad>();
    Exceptions
    Type Condition
    ArgumentNullException

    layout is null or empty.

    See Also
    AddDevice<TDevice>(String)
    RemoveDevice(InputDevice)
    onDeviceChange
    Added
    devices
    RegisterLayout(Type, String, Nullable<InputDeviceMatcher>)

    AddDevice(InputDevice)

    Add the given device back to the system.

    Declaration
    public static void AddDevice(InputDevice device)
    Parameters
    Type Name Description
    InputDevice device

    An input device. If the device is currently already added to the system (i.e. is in devices), the method will do nothing.

    Remarks

    This can be used when a device has been manually removed with RemoveDevice(InputDevice).

    The device will be added to the devices list and a notification on onDeviceChange will be triggered.

    It may be tempting to do the following but this will not work:

    // This will *NOT* work.
    var device = new Gamepad();
    InputSystem.AddDevice(device);

    InputDevices, like InputControls in general, cannot simply be instantiated with new but must be created by the input system instead.

    Exceptions
    Type Condition
    ArgumentNullException
    See Also
    RemoveDevice(InputDevice)
    AddDevice<TDevice>(String)
    devices

    AddDevice(InputDeviceDescription)

    Tell the input system that a new device has become available.

    Declaration
    public static InputDevice AddDevice(InputDeviceDescription description)
    Parameters
    Type Name Description
    InputDeviceDescription description

    Description of the input device.

    Returns
    Type Description
    InputDevice

    The newly created device that has been added to devices.

    Remarks

    This method is different from methods such as AddDevice(String, String, String) or AddDevice<TDevice>(String) in that it employs the usual matching process the same way that it happens when the Unity runtime reports an input device.

    In particular, the same procedure described in the documentation for onFindLayoutForDevice is employed where all registered InputDeviceMatchers are matched against the supplied device description and the most suitable match determines the layout to use. This in turn is run through onFindLayoutForDevice to determine the final layout to use.

    If no suitable layout can be found, the method throws ArgumentException.

    InputSystem.AddDevice(
        new InputDeviceDescription
        {
            interfaceName = "Custom",
            product = "Product"
        });

    Exceptions
    Type Condition
    ArgumentException

    The given description is empty -or- no layout can be found that matches the given device description.

    AddDevice<TDevice>(String)

    Add a new device by instantiating the layout registered for type TDevice.

    Declaration
    public static TDevice AddDevice<TDevice>(string name = null)
        where TDevice : InputDevice
    Parameters
    Type Name Description
    String name

    Name to assign to the device. If null, the layout's display name (displayName is used instead. Note that device names are made unique automatically by the system by appending numbers to them (e.g. "gamepad", "gamepad1", "gamepad2", etc.).

    Returns
    Type Description
    TDevice

    The newly added device.

    Type Parameters
    Name Description
    TDevice

    Type of device to add.

    Remarks

    The device will be added to the devices list and a notification on onDeviceChange will be triggered.

    Note that adding a device to the system will allocate and also create garbage on the GC heap.

    // Add a gamepad.
    InputSystem.AddDevice<Gamepad>();
    Exceptions
    Type Condition
    InvalidOperationException

    Instantiating the layout for TDevice did not produce a device of type TDevice.

    See Also
    RemoveDevice(InputDevice)
    onDeviceChange
    Added
    devices

    AddDeviceUsage(InputDevice, String)

    Add a usage tag to the given device.

    Declaration
    public static void AddDeviceUsage(InputDevice device, string usage)
    Parameters
    Type Name Description
    InputDevice device

    Device to add the usage to.

    String usage

    New usage to add to the device.

    Remarks

    Usages allow to "tag" a specific device such that the tag can then be used in lookups and bindings. A common use is for identifying the handedness of an XRController but the usages can be arbitrary strings.

    This method adds a new usage to the device's set of usages. If the device already has the given usage, the method does nothing. To instead set the device's usages to a single one, use SetDeviceUsage(InputDevice, String). To remove usages from a device, call RemoveDeviceUsage(InputDevice, String).

    The set of usages a device has can be queried with usages (a device is an InputControl and thus, like controls, has an associated set of usages).

    If the set of usages on the device changes as a result of calling this method, onDeviceChange will be triggered with UsageChanged.

    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    ArgumentException

    usage is null or empty.

    See Also
    usages
    SetDeviceUsage(InputDevice, String)
    RemoveDeviceUsage(InputDevice, String)
    CommonUsages
    UsageChanged

    AddDeviceUsage(InputDevice, InternedString)

    Add a usage tag to the given device.

    Declaration
    public static void AddDeviceUsage(InputDevice device, InternedString usage)
    Parameters
    Type Name Description
    InputDevice device

    Device to add the usage to.

    InternedString usage

    New usage to add to the device.

    Remarks

    Usages allow to "tag" a specific device such that the tag can then be used in lookups and bindings. A common use is for identifying the handedness of an XRController but the usages can be arbitrary strings.

    This method adds a new usage to the device's set of usages. If the device already has the given usage, the method does nothing. To instead set the device's usages to a single one, use SetDeviceUsage(InputDevice, InternedString). To remove usages from a device, call RemoveDeviceUsage(InputDevice, InternedString).

    The set of usages a device has can be queried with usages (a device is an InputControl and thus, like controls, has an associated set of usages).

    If the set of usages on the device changes as a result of calling this method, onDeviceChange will be triggered with UsageChanged.

    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    ArgumentException

    usage is empty.

    See Also
    usages
    SetDeviceUsage(InputDevice, InternedString)
    RemoveDeviceUsage(InputDevice, InternedString)
    CommonUsages
    UsageChanged

    DisableAllEnabledActions()

    Disable all actions (and implicitly all action sets) that are currently enabled.

    Declaration
    public static void DisableAllEnabledActions()
    See Also
    ListEnabledActions()
    Disable()

    DisableDevice(InputDevice, Boolean)

    Disable the given device, i.e. "mute" it.

    Declaration
    public static void DisableDevice(InputDevice device, bool keepSendingEvents = false)
    Parameters
    Type Name Description
    InputDevice device

    Device to disable. If already disabled, the method will do nothing.

    Boolean keepSendingEvents

    If true, no DisableDeviceCommand will be sent for the device. This means that the backend sending input events will not be notified about the device being disabled and will thus keep sending events. This can be useful when input is being rerouted from one device to another. For example, TouchSimulation uses this to disable the Mouse while redirecting its events to input on a Touchscreen.

    This parameter is false by default.

    Remarks

    A disabled device will not receive input and will remain in its default state. It will remain present in the system but without actually feeding input into it.

    Disabling devices is most useful for Sensor devices on battery-powered platforms where having a sensor enabled will increase energy consumption. Sensors will usually start out in disabled state and can be enabled, when needed, with EnableDevice(InputDevice) and disabled again wth this method.

    However, disabling a device can be useful in other situations, too. For example, when simulating input (say, mouse input) locally from a remote source, it can be desirable to turn off the respective local device.

    To remove a device altogether, use RemoveDevice(InputDevice) instead. This will not only silence input but remove the InputDevice instance from the system altogether.

    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    See Also
    EnableDevice(InputDevice)
    enabled

    EnableDevice(InputDevice)

    (Re-)enable the given device.

    Declaration
    public static void EnableDevice(InputDevice device)
    Parameters
    Type Name Description
    InputDevice device

    Device to enable. If already enabled, the method will do nothing.

    Remarks

    This can be used after a device has been disabled with DisableDevice(InputDevice, Boolean) or with devices that start out in disabled state (usually the case for all Sensor devices).

    When enabled, a device will receive input when available.

    // Enable the gyroscope, if present.
    if (Gyroscope.current != null)
        InputSystem.EnableDevice(Gyroscope.current);
    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    See Also
    DisableDevice(InputDevice, Boolean)
    enabled

    FindControl(String)

    Find the first control that matches the given control path.

    Declaration
    public static InputControl FindControl(string path)
    Parameters
    Type Name Description
    String path

    Path of a control, e.g. "<Gamepad>/buttonSouth". See InputControlPath for details.

    Returns
    Type Description
    InputControl

    The first control that matches the given path or null if no control matches.

    Remarks

    If multiple controls match the given path, which result is considered the first is indeterminate.

    // Add gamepad.
    InputSystem.AddDevice<Gamepad>();
    
    // Look up various controls on it.
    var aButton = InputSystem.FindControl("<Gamepad>/buttonSouth");
    var leftStickX = InputSystem.FindControl("*/leftStick/x");
    var bButton = InputSystem.FindControl"*/{back}");
    
    // This one returns the gamepad itself as devices are also controls.
    var gamepad = InputSystem.FindControl("<Gamepad>");
    Exceptions
    Type Condition
    ArgumentNullException

    path is null or empty.

    See Also
    InputControlPath
    path

    FindControls(String)

    Find all controls that match the given InputControlPath.

    Declaration
    public static InputControlList<InputControl> FindControls(string path)
    Parameters
    Type Name Description
    String path

    Control path to search for

    Returns
    Type Description
    InputControlList<InputControl>

    List of InputControl which matched the given search criteria

    Examples
    // Find all gamepads (literally: that use the "Gamepad" layout).
    InputSystem.FindControls("<Gamepad>");
    
    // Find all sticks on all gamepads.
    InputSystem.FindControls("<Gamepad>/*stick");
    
    // Same but filter stick by type rather than by name.
    InputSystem.FindControls<StickControl>("<Gamepad>/*");
    See Also
    FindControls<TControl>(String)
    FindControls<TControl>(String, ref InputControlList<TControl>)

    FindControls<TControl>(String)

    Find all controls that match the given InputControlPath.

    Declaration
    public static InputControlList<TControl> FindControls<TControl>(string path)
        where TControl : InputControl
    Parameters
    Type Name Description
    String path

    Control path to search for

    Returns
    Type Description
    InputControlList<TControl>

    Generic list of InputControl which matched the given search criteria

    Type Parameters
    Name Description
    TControl

    Type of control InputControl.

    See Also
    FindControls<TControl>(String)
    FindControls<TControl>(String, ref InputControlList<TControl>)

    FindControls<TControl>(String, ref InputControlList<TControl>)

    Populate a list with all controls that match the given InputControlPath.

    Declaration
    public static int FindControls<TControl>(string path, ref InputControlList<TControl> controls)
        where TControl : InputControl
    Parameters
    Type Name Description
    String path

    Control path to search for

    InputControlList<TControl> controls

    Generic list of InputControl to populate with the search results

    Returns
    Type Description
    Int32

    Count of controls which matched the given search criteria

    Type Parameters
    Name Description
    TControl

    Type of control InputControl.

    See Also
    FindControls<TControl>(String)
    FindControls<TControl>(String, ref InputControlList<TControl>)

    FlushDisconnectedDevices()

    Purge all disconnected devices from disconnectedDevices.

    Declaration
    public static void FlushDisconnectedDevices()
    Remarks

    This will release all references held on to for these devices or any of their controls and will allow the devices to be reclaimed by the garbage collector.

    See Also
    disconnectedDevices

    GetDevice(String)

    Return the device with given name or layout . Returns null if no such device currently exists.

    Declaration
    public static InputDevice GetDevice(string nameOrLayout)
    Parameters
    Type Name Description
    String nameOrLayout

    Unique device name or layout to search for.

    Returns
    Type Description
    InputDevice

    The device matching the given search criteria or null.

    See Also
    GetDevice(Type)
    GetDevice<TDevice>()
    AddDevice<TDevice>(String)

    GetDevice(Type)

    Return the most recently used device that is assignable to the given type . Returns null if no such device currently exists.

    Declaration
    public static InputDevice GetDevice(Type type)
    Parameters
    Type Name Description
    Type type

    Type of the device

    Returns
    Type Description
    InputDevice

    The device that is assignable to the given type or null.

    See Also
    GetDevice(String)
    GetDevice<TDevice>()

    GetDevice<TDevice>()

    Return the most recently used device that is assignable to the given type TDevice. Returns null if no such device currently exists.

    Declaration
    public static TDevice GetDevice<TDevice>()
        where TDevice : InputDevice
    Returns
    Type Description
    TDevice

    The device that is assignable to the given type or null.

    Type Parameters
    Name Description
    TDevice

    Type of device to look for.

    See Also
    GetDevice(String)
    GetDevice(Type)

    GetDevice<TDevice>(String)

    Return the device of the given type TDevice that has the given usage assigned. Returns null if no such device currently exists.

    Declaration
    public static TDevice GetDevice<TDevice>(string usage)
        where TDevice : InputDevice
    Parameters
    Type Name Description
    String usage

    Usage of the device, e.g. "LeftHand".

    Returns
    Type Description
    TDevice

    The device with the given type and usage or null.

    Type Parameters
    Name Description
    TDevice

    Type of device to look for.

    Remarks

    Devices usages are most commonly employed to "tag" devices for a specific role. A common scenario, for example, is to distinguish which hand a specific XRController is associated with. However, arbitrary usages can be assigned to devices.

    See Also
    GetDevice<TDevice>(InternedString)
    SetDeviceUsage(InputDevice, String)
    usages

    GetDevice<TDevice>(InternedString)

    Return the device of the given type TDevice that has the given usage assigned. Returns null if no such device currently exists.

    Declaration
    public static TDevice GetDevice<TDevice>(InternedString usage)
        where TDevice : InputDevice
    Parameters
    Type Name Description
    InternedString usage

    Usage of the device, e.g. "LeftHand".

    Returns
    Type Description
    TDevice

    The device with the given type and usage or null.

    Type Parameters
    Name Description
    TDevice

    Type of device to look for.

    Remarks

    Devices usages are most commonly employed to "tag" devices for a specific role. A common scenario, for example, is to distinguish which hand a specific XRController is associated with. However, arbitrary usages can be assigned to devices.

    // Get the left hand XRController.
    var leftHand = InputSystem.GetDevice<XRController>(CommonUsages.leftHand);
    
    // Mark gamepad #2 as being for player 1.
    InputSystem.SetDeviceUsage(Gamepad.all[1], "Player1");
    // And later look it up.
    var player1Gamepad = InputSystem.GetDevice<Gamepad>(new InternedString("Player1"));

    See Also
    GetDevice(String)
    SetDeviceUsage(InputDevice, String)
    usages

    GetDeviceById(Int32)

    Look up a device by its unique ID.

    Declaration
    public static InputDevice GetDeviceById(int deviceId)
    Parameters
    Type Name Description
    Int32 deviceId

    Unique ID of device. Such as given by deviceId.

    Returns
    Type Description
    InputDevice

    The device for the given ID or null if no device with the given ID exists (or no longer exists).

    Remarks

    Device IDs are not reused in a given session of the application (or Unity editor).

    See Also
    deviceId
    deviceId
    UnityEngine.InputSystem.LowLevel.IInputRuntime.AllocateDeviceId

    GetNameOfBaseLayout(String)

    Return the name of the layout that the layout registered as layoutName is based on.

    Declaration
    public static string GetNameOfBaseLayout(string layoutName)
    Parameters
    Type Name Description
    String layoutName

    Name of a layout as registered with a method such as RegisterLayout<T>(String, Nullable<InputDeviceMatcher>). Case-insensitive.

    Returns
    Type Description
    String

    Name of the immediate parent layout of layoutName or null if no layout with the given name is registered or if it is not based on another layout or if it is a layout override.

    Remarks

    This method does not work for layout overrides (which can be based on multiple base layouts). To find out which layouts a specific override registered with RegisterLayoutOverride(String, String) is based on, load the layout with LoadLayout(String) and inspect baseLayouts. This method will return null when layoutName is the name of a layout override.

    One advantage of this method over calling LoadLayout(String) and looking at baseLayouts is that this method does not have to actually load the layout but instead only performs a simple lookup.

    // Prints "Pointer".
    Debug.Log(InputSystem.GetNameOfBaseLayout("Mouse"));
    
    // Also works for control layouts. Prints "Axis".
    Debug.Log(InputSystem.GetNameOfBaseLayout("Button"));
    Exceptions
    Type Condition
    ArgumentNullException

    layoutName is null or empty.

    See Also
    baseLayouts

    GetUnsupportedDevices()

    Return the list of devices that have been reported by the UnityEngine.InputSystem.LowLevel.IInputRuntime but could not be matched to any known InputControlLayout.

    Declaration
    public static List<InputDeviceDescription> GetUnsupportedDevices()
    Returns
    Type Description
    List<InputDeviceDescription>

    A list of descriptions of devices that could not be recognized.

    Remarks

    If new layouts are added to the system or if additional InputDeviceMatcher are added to existing layouts, devices in this list may appear or disappear.

    See Also
    InputDeviceMatcher
    RegisterLayoutMatcher(String, InputDeviceMatcher)

    GetUnsupportedDevices(List<InputDeviceDescription>)

    Populate a list of devices that have been reported by the UnityEngine.InputSystem.LowLevel.IInputRuntime but could not be matched to any known InputControlLayout.

    Declaration
    public static int GetUnsupportedDevices(List<InputDeviceDescription> descriptions)
    Parameters
    Type Name Description
    List<InputDeviceDescription> descriptions

    A list to be populated with descriptions of devices that could not be recognized.

    Returns
    Type Description
    Int32

    The number of devices that could not be recognized.

    Remarks

    If new layouts are added to the system or if additional InputDeviceMatcher are added to existing layouts, devices in this list may appear or disappear.

    See Also
    InputDeviceMatcher
    RegisterLayoutMatcher(String, InputDeviceMatcher)

    IsFirstLayoutBasedOnSecond(String, String)

    Check whether the first layout is based on the second.

    Declaration
    public static bool IsFirstLayoutBasedOnSecond(string firstLayoutName, string secondLayoutName)
    Parameters
    Type Name Description
    String firstLayoutName

    Name of a registered InputControlLayout.

    String secondLayoutName

    Name of a registered InputControlLayout.

    Returns
    Type Description
    Boolean

    True if firstLayoutName is based on secondLayoutName.

    Remarks

    This is

    Exceptions
    Type Condition
    ArgumentNullException

    firstLayoutName is null or empty -or- secondLayoutName is null or empty.

    ListEnabledActions()

    Return a list of all the actions that are currently enabled in the system.

    Declaration
    public static List<InputAction> ListEnabledActions()
    Returns
    Type Description
    List<InputAction>

    A new list instance containing all currently enabled actions.

    Remarks

    To avoid allocations, use ListEnabledActions(List<InputAction>).

    See Also
    enabled

    ListEnabledActions(List<InputAction>)

    Add all actions that are currently enabled in the system to the given list.

    Declaration
    public static int ListEnabledActions(List<InputAction> actions)
    Parameters
    Type Name Description
    List<InputAction> actions

    List to add actions to.

    Returns
    Type Description
    Int32

    The number of actions added to the list.

    Remarks

    If the capacity of the given list is large enough, this method will not allocate memory.

    Exceptions
    Type Condition
    ArgumentNullException

    actions is null.

    ListInteractions()

    Gets the names of of all currently registered interactions.

    Declaration
    public static IEnumerable<string> ListInteractions()
    Returns
    Type Description
    IEnumerable<String>

    A list of currently registered interaction names.

    See Also
    IInputInteraction
    RegisterInteraction(Type, String)
    TryGetInteraction(String)

    ListLayouts()

    Return a list with the names of all layouts that have been registered.

    Declaration
    public static IEnumerable<string> ListLayouts()
    Returns
    Type Description
    IEnumerable<String>

    A list of layout names.

    See Also
    LoadLayout(String)
    ListLayoutsBasedOn(String)
    RegisterLayout(Type, String, Nullable<InputDeviceMatcher>)

    ListLayoutsBasedOn(String)

    List all the layouts that are based on the given layout.

    Declaration
    public static IEnumerable<string> ListLayoutsBasedOn(string baseLayout)
    Parameters
    Type Name Description
    String baseLayout

    Name of a registered layout.

    Returns
    Type Description
    IEnumerable<String>

    The names of all registered layouts based on baseLayout.

    Remarks

    The list will not include layout overrides (see RegisterLayoutOverride(String, String)).

    // List all gamepad layouts in the system.
    Debug.Log(string.Join("\n", InputSystem.ListLayoutsBasedOn("Gamepad"));
    Exceptions
    Type Condition
    ArgumentNullException

    baseLayout is null or empty.

    ListProcessors()

    List the names of all processors have been registered.

    Declaration
    public static IEnumerable<string> ListProcessors()
    Returns
    Type Description
    IEnumerable<String>

    List of registered processors.

    Remarks

    Note that the result will include both "proper" names and aliases registered for processors. If, for example, a given type JitterProcessor has been registered under both "Jitter" and "Randomize", it will appear in the list with both those names.

    See Also
    TryGetProcessor(String)
    RegisterProcessor<T>(String)

    LoadLayout(String)

    Load a registered layout.

    Declaration
    public static InputControlLayout LoadLayout(string name)
    Parameters
    Type Name Description
    String name

    Name of the layout to load. Note that layout names are case-insensitive.

    Returns
    Type Description
    InputControlLayout

    The constructed layout instance or null if no layout of the given name could be found.

    Remarks

    The result of this method is what's called a "fully merged" layout, i.e. a layout with the information of all the base layouts as well as from all overrides merged into it. See MergeLayout(InputControlLayout) for details.

    What this means in practice is that all inherited controls and settings will be present on the layout.

    // List all controls defined for gamepads. var gamepadLayout = InputSystem.LoadLayout("Gamepad"); foreach (var control in gamepadLayout.controls) { // There may be control elements that are not introducing new controls but rather // change settings on controls added indirectly by other layouts referenced from // Gamepad. These are not adding new controls so we skip them here. if (control.isModifyingExistingControl) continue; Debug.Log($"Control: {control.name} ({control.layout])"); }

    However, note that controls which are added from other layouts referenced by the loaded layout will not necessarily be visible on it (they will only if referenced by a InputControlLayout.ControlItem where isModifyingExistingControl is true). For example, let's assume we have the following layout which adds a device with a single stick.

    InputSystem.RegisterLayout(@"
        {
            ""name"" : ""DeviceWithStick"",
            ""controls"" : [
                { ""name"" : ""stick"", ""layout"" : ""Stick"" }
            ]
        }
    ");

    If we load this layout, the "stick" control will be visible on the layout but the X and Y (as well as up/down/left/right) controls added by the "Stick" layout will not be.

    Exceptions
    Type Condition
    ArgumentNullException

    name is null or empty.

    See Also
    RegisterLayout(Type, String, Nullable<InputDeviceMatcher>)

    LoadLayout<TControl>()

    Load the layout registered for the given type.

    Declaration
    public static InputControlLayout LoadLayout<TControl>()
        where TControl : InputControl
    Returns
    Type Description
    InputControlLayout

    The layout registered for TControl or null if no such layout exists.

    Type Parameters
    Name Description
    TControl

    An InputControl type.

    Remarks

    This method is equivalent to calling LoadLayout(String) with the name of the layout under which TControl has been registered.

    // Load the InputControlLayout generated from StickControl.
    var stickLayout = InputSystem.LoadLayout<StickControl>();
    See Also
    LoadLayout(String)

    PauseHaptics()

    Pause haptic effect playback on all devices.

    Declaration
    public static void PauseHaptics()
    Remarks

    Calls PauseHaptics() on all InputDevice that implement the interface.

    Examples
    // When going into the menu from gameplay, pause haptics.
    gameplayControls.backAction.onPerformed +=
        ctx =>
        {
            gameplayControls.Disable();
            menuControls.Enable();
            InputSystem.PauseHaptics();
        };
    See Also
    ResumeHaptics()
    ResetHaptics()

    QueueConfigChangeEvent(InputDevice, Double)

    Queue a DeviceConfigurationEvent that signals that the configuration of the given device has changed and that cached configuration will thus have to be refreshed.

    Declaration
    public static void QueueConfigChangeEvent(InputDevice device, double time = -1)
    Parameters
    Type Name Description
    InputDevice device

    Device whose configuration has changed.

    Double time

    Timestamp for the event. If not supplied, the current time will be used.

    Remarks

    All state of an input device that is not input or output state is considered its "configuration".

    A simple example is keyboard layouts. A Keyboard will typically have an associated keyboard layout that dictates the function of each key and which can be changed by the user at the system level. In the input system, the current keyboard layout can be queried via keyboardLayout. When the layout changes at the system level, the input backend sends a configuration change event to signal that the configuration of the keyboard has changed and that cached data may be outdated. In response, Keyboard will flush out cached information such as the name of the keyboard layout and display names (displayName) of individual keys which causes them to be fetched again from the backend the next time they are accessed.

    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    InvalidOperationException

    device has not been added (added; AddDevice(InputDevice)) and thus cannot receive events.

    QueueDeltaStateEvent<TDelta>(InputControl, TDelta, Double)

    Queue a DeltaStateEvent to update part of the input state of the given device.

    Declaration
    public static void QueueDeltaStateEvent<TDelta>(InputControl control, TDelta delta, double time = -1)
        where TDelta : struct
    Parameters
    Type Name Description
    InputControl control

    Control on a device to update state of.

    TDelta delta

    New state for the control. Type of state must match the state of the control.

    Double time
    Type Parameters
    Name Description
    TDelta
    Exceptions
    Type Condition
    ArgumentNullException

    control is null.

    InvalidOperationException
    ArgumentException

    QueueEvent(InputEventPtr)

    Add an event to the internal event queue.

    Declaration
    public static void QueueEvent(InputEventPtr eventPtr)
    Parameters
    Type Name Description
    InputEventPtr eventPtr

    Event to add to the internal event buffer.

    Remarks

    The event will be copied in full to the internal event buffer meaning that you can release memory for the event after it has been queued. The internal event buffer is flushed on the next input system update (see Update()). Note that if input is process in FixedUpdate() (see updateMode), then the event may not get processed until its time timestamp is within the update window of the input system.

    As part of queuing, the event will receive its own unique ID (see eventId). Note that this ID will be written into the memory buffer referenced by meaning that after calling QueueEvent, you will see the event ID with which the event was queued.

    Events that are queued during event processing will get processed in the same update. This happens, for example, when queuing input from within onEvent or from action callbacks such as performed.

    The total size of InputEvents processed in a single update is limited by maxEventBytesPerUpdate. This also prevents deadlocks when each processing of an event leads to one or more additional events getting queued.

    // Queue an input event on the first gamepad.
    var gamepad = Gamepad.all[0];
    using (StateEvent.From(gamepad, out var eventPtr))
    {
        gamepad.leftStick.WriteValueIntoEvent(new Vector2(0.123f, 0.234f), eventPtr);
        InputSystem.QueueEvent(eventPtr);
    }
    Exceptions
    Type Condition
    ArgumentException

    eventPtr is not valid (see valid).

    InvalidOperationException

    The method was called from within event processing more than 1000 times. To avoid deadlocking, this results in an exception being thrown.

    See Also
    Update()
    onEvent
    onBeforeUpdate
    InputEvent

    QueueEvent<TEvent>(ref TEvent)

    Add an event to the internal event queue.

    Declaration
    public static void QueueEvent<TEvent>(ref TEvent inputEvent)
        where TEvent : struct, IInputEventTypeInfo
    Parameters
    Type Name Description
    TEvent inputEvent

    Event to add to the internal event buffer.

    Type Parameters
    Name Description
    TEvent

    Type of event to look enqueue.

    Remarks

    The event will be copied in full to the internal event buffer. The internal event buffer is flushed on the next input system update (see Update()). Note that if input is process in FixedUpdate() (see updateMode), then the event may not get processed until its time timestamp is within the update window of the input system.

    As part of queuing, the event will receive its own unique ID (see eventId). Note that this ID will be written into inputEvent meaning that after calling this method, you will see the event ID with which the event was queued.

    // Queue a disconnect event on the first gamepad.
    var inputEvent = DeviceRemoveEvent(Gamepad.all[0].deviceId);
    InputSystem.QueueEvent(inputEvent);
    See Also
    Update()
    onEvent
    onBeforeUpdate

    QueueStateEvent<TState>(InputDevice, TState, Double)

    Queue a StateEvent to update the input state of the given device.

    Declaration
    public static void QueueStateEvent<TState>(InputDevice device, TState state, double time = -1)
        where TState : struct, IInputStateTypeInfo
    Parameters
    Type Name Description
    InputDevice device

    Device whose input state to update

    TState state
    Double time

    Timestamp for the event. If not supplied, the current time is used. Note that if the given time is in the future and events processed in FixedUpdate (see updateMode), the event will only get processed once the actual time has caught up with the given time.

    Type Parameters
    Name Description
    TState

    Type of input state, such as MouseState. Must match the expected type of state of device.

    Remarks

    The given state must match exactly what is expected by the given device. If unsure, an alternative is to grab the state as an event directly from the device using From(InputDevice, out InputEventPtr, Allocator) which can then be queued using QueueEvent(InputEventPtr).

    // Allocates temporary, unmanaged memory for the event.
    // using statement automatically disposes the memory once we have queued the event.
    using (StateEvent.From(Mouse.current, out var eventPtr))
    {
        // Use controls on mouse to write values into event.
        Mouse.current.position.WriteValueIntoEvent(new Vector(123, 234), eventPtr);
    
        // Queue event.
        InputSystem.QueueEvent(eventPtr);
    }

    The event will only be queued and not processed right away. This means that the state of device will not change immediately as a result of calling this method. Instead, the event will be processed as part of the next input update.

    Note that this method updates the complete input state of the device including all of its controls. To update just part of the state of a device, you can use QueueDeltaStateEvent<TDelta>(InputControl, TDelta, Double) (however, note that there are some restrictions; see documentation).

    InputSystem.QueueStateEvent(Mouse.current, new MouseState { position = new Vector(123, 234) });

    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    InvalidOperationException

    device has not been added to the system (AddDevice(InputDevice)) and thus cannot receive events.

    ArgumentException

    QueueTextEvent(InputDevice, Char, Double)

    Queue a TextEvent on the given device.

    Declaration
    public static void QueueTextEvent(InputDevice device, char character, double time = -1)
    Parameters
    Type Name Description
    InputDevice device

    Device to queue the event on.

    Char character

    Text character to input through the event.

    Double time

    Optional event time stamp. If not supplied, the current time will be used.

    Remarks

    Text input is sent to devices character by character. This allows sending strings of arbitrary length without necessary incurring GC overhead.

    For the event to have any effect on device, the device must implement ITextInputReceiver. It will see OnTextInput(Char) being called when the event is processed.

    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    InvalidOperationException

    device is a device that has not been added to the system.

    See Also
    onTextInput

    RegisterBindingComposite(Type, String)

    Register a new type of binding composite with the system.

    Declaration
    public static void RegisterBindingComposite(Type type, string name)
    Parameters
    Type Name Description
    Type type

    Type that implements the binding composite. Must support InputBindingComposite.

    String name

    Name to register the binding composite with. This is used in bindings to refer to the composite.

    See Also
    InputBindingComposite
    RegisterBindingComposite<T>(String)
    TryGetBindingComposite(String)

    RegisterBindingComposite<T>(String)

    Register a new type of binding composite with the system.

    Declaration
    public static void RegisterBindingComposite<T>(string name = null)
    Parameters
    Type Name Description
    String name

    Name to register the binding composite with. This is used in bindings to refer to the composite.

    Type Parameters
    Name Description
    T

    Type that implements the binding composite. Must support InputBindingComposite.

    See Also
    InputBindingComposite
    RegisterBindingComposite(Type, String)
    TryGetBindingComposite(String)

    RegisterInteraction(Type, String)

    Register a new type of interaction with the system.

    Declaration
    public static void RegisterInteraction(Type type, string name = null)
    Parameters
    Type Name Description
    Type type

    Type that implements the interaction. Must support UnityEngine.InputSystem.InputInteraction.

    String name

    Name to register the interaction with. This is used in bindings to refer to the interaction (e.g. an interactions called "Tap" can be added to a binding by listing it in its interactions property). If no name is supplied, the short name of type is used (with "Interaction" clipped off the name if the type name ends in that).

    Examples
    // Interaction that is performed when control resets to default state.
    public class ResetInteraction : InputInteraction
    {
        public void Process(ref InputInteractionContext context)
        {
            if (context.isWaiting && !context.controlHasDefaultValue)
                context.Started();
            else if (context.isStarted && context.controlHasDefaultValue)
                context.Performed();
        }
    }
    
    // Make interaction globally available on bindings.
    // "Interaction" suffix in type name will get dropped automatically.
    InputSystem.RegisterInteraction(typeof(ResetInteraction));
    
    // Set up action with binding that has the 'reset' interaction applied to it.
    var action = new InputAction(binding: "/<Gamepad>/buttonSouth", interactions: "reset");
    See Also
    IInputInteraction
    RegisterInteraction<T>(String)
    TryGetInteraction(String)
    ListInteractions()

    RegisterInteraction<T>(String)

    Register a new type of interaction with the system.

    Declaration
    public static void RegisterInteraction<T>(string name = null)
    Parameters
    Type Name Description
    String name

    Name to register the interaction with. This is used in bindings to refer to the interaction (e.g. an interactions called "Tap" can be added to a binding by listing it in its interactions property). If no name is supplied, the short name of T is used (with "Interaction" clipped off the name if the type name ends in that).

    Type Parameters
    Name Description
    T

    Type that implements the interaction. Must support UnityEngine.InputSystem.InputInteraction.

    See Also
    IInputInteraction
    RegisterInteraction(Type, String)
    TryGetInteraction(String)
    ListInteractions()

    RegisterLayout(String, String, Nullable<InputDeviceMatcher>)

    Register a layout in JSON format.

    Declaration
    public static void RegisterLayout(string json, string name = null, InputDeviceMatcher? matches = null)
    Parameters
    Type Name Description
    String json

    JSON data describing the layout.

    String name

    Optional name of the layout. If null or empty, the name is taken from the "name" property of the JSON data. If it is supplied, it will override the "name" property if present. If neither is supplied, an ArgumentException is thrown.

    Nullable<InputDeviceMatcher> matches

    Optional device matcher. If this is supplied, the layout will automatically be instantiated for newly discovered devices that match the description.

    Remarks

    The JSON format makes it possible to create new device and control layouts completely in data. They have to ultimately be based on a layout backed by a C# type, however (e.g. Gamepad).

    Note that most errors in layouts will only be detected when instantiated (i.e. when a device or control is being created from a layout). The JSON data will, however, be parsed once on registration to check for a device description in the layout. JSON format errors will thus be detected during registration.

    InputSystem.RegisterLayout(@"
       {
           ""name"" : ""MyDevice"",
           ""controls"" : [
               {
                   ""name"" : ""myButton"",
                   ""layout"" : ""Button""
               }
           ]
       }
    );
    Exceptions
    Type Condition
    ArgumentNullException

    json is null or empty.

    ArgumentException

    No name has been supplied either through name or the "name" JSON property.

    See Also
    RemoveLayout(String)

    RegisterLayout(Type, String, Nullable<InputDeviceMatcher>)

    Register a control layout based on a type.

    Declaration
    public static void RegisterLayout(Type type, string name = null, InputDeviceMatcher? matches = null)
    Parameters
    Type Name Description
    Type type

    Type to derive a control layout from. Must be derived from InputControl.

    String name

    Name to use for the layout. If null or empty, the short name of the type (Type.Name) will be used.

    Nullable<InputDeviceMatcher> matches

    Optional device matcher. If this is supplied, the layout will automatically be instantiated for newly discovered devices that match the description.

    Remarks

    When the layout is instantiated, the system will reflect on all public fields and properties of the type which have a value type derived from InputControl or which are annotated with InputControlAttribute.

    The type can be annotated with InputControlLayoutAttribute for additional options but the attribute is not necessary for a type to be usable as a control layout. Note that if the type does have InputControlLayoutAttribute and has set stateType, the system will not reflect on properties and fields in the type but do that on the given state type instead.

    // InputControlLayoutAttribute attribute is only necessary if you want
    // to override default behavior that occurs when registering your device
    // as a layout.
    // The most common use of InputControlLayoutAttribute is to direct the system
    // to a custom "state struct" through the `stateType` property. See below for details.
    [InputControlLayout(displayName = "My Device", stateType = typeof(MyDeviceState))]
    #if UNITY_EDITOR
    [InitializeOnLoad]
    #endif
    public class MyDevice : InputDevice
    {
        public ButtonControl button { get; private set; }
        public AxisControl axis { get; private set; }
    
        // Register the device.
        static MyDevice()
        {
            // In case you want instance of your device to automatically be created
            // when specific hardware is detected by the Unity runtime, you have to
            // add one or more "device matchers" (InputDeviceMatcher) for the layout.
            // These matchers are compared to an InputDeviceDescription received from
            // the Unity runtime when a device is connected. You can add them either
            // using InputSystem.RegisterLayoutMatcher() or by directly specifying a
            // matcher when registering the layout.
            InputSystem.RegisterLayout<MyDevice>(
                // For the sake of demonstration, let's assume your device is a HID
                // and you want to match by PID and VID.
                matches: new InputDeviceMatcher()
                    .WithInterface("HID")
                    .WithCapability("PID", 1234)
                    .WithCapability("VID", 5678));
        }
    
        // This is only to trigger the static class constructor to automatically run
        // in the player.
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        private static void InitializeInPlayer() {}
    
        protected override void FinishSetup()
        {
            base.FinishSetup();
            button = GetChildControl<ButtonControl>("button");
            axis = GetChildControl<AxisControl>("axis");
        }
    }
    
    // A "state struct" describes the memory format used by a device. Each device can
    // receive and store memory in its custom format. InputControls are then connected
    // the individual pieces of memory and read out values from them.
    [StructLayout(LayoutKind.Explicit, Size = 32)]
    public struct MyDeviceState : IInputStateTypeInfo
    {
        // In the case of a HID (which we assume for the sake of this demonstration),
        // the format will be "HID". In practice, the format will depend on how your
        // particular device is connected and fed into the input system.
        // The format is a simple FourCC code that "tags" state memory blocks for the
        // device to give a base level of safety checks on memory operations.
        public FourCC format => return new FourCC('H', 'I', 'D');
    
        // InputControlAttributes on fields tell the input system to create controls
        // for the public fields found in the struct.
    
        // Assume a 16bit field of buttons. Create one button that is tied to
        // bit #3 (zero-based). Note that buttons do not need to be stored as bits.
        // They can also be stored as floats or shorts, for example.
        [InputControl(name = "button", layout = "Button", bit = 3)]
        public ushort buttons;
    
        // Create a floating-point axis. The name, if not supplied, is taken from
        // the field.
        [InputControl(layout = "Axis")]
        public short axis;
    }

    Note that if matches is supplied, it will immediately be matched against the descriptions (InputDeviceDescription) of all available devices. If it matches any description where no layout matched before, a new device will immediately be created (except if suppressed by supportedDevices). If it matches a description better (see MatchPercentage(InputDeviceDescription)) than the currently used layout, the existing device will be a removed and a new device with the newly registered layout will be created.

    See StickControl or Gamepad for examples of layouts.

    Exceptions
    Type Condition
    ArgumentNullException

    type is null.

    See Also
    InputControlLayout

    RegisterLayout<T>(String, Nullable<InputDeviceMatcher>)

    Register a type as a control layout.

    Declaration
    public static void RegisterLayout<T>(string name = null, InputDeviceMatcher? matches = null)
        where T : InputControl
    Parameters
    Type Name Description
    String name

    Name to use for the layout. If null or empty, the short name of the type will be used.

    Nullable<InputDeviceMatcher> matches

    Optional device matcher. If this is supplied, the layout will automatically be instantiated for newly discovered devices that match the description.

    Type Parameters
    Name Description
    T

    Type to derive a control layout from.

    Remarks

    This method is equivalent to calling RegisterLayout(Type, String, Nullable<InputDeviceMatcher>) with typeof(T). See that method for details of the layout registration process.

    See Also
    RegisterLayout(Type, String, Nullable<InputDeviceMatcher>)

    RegisterLayoutBuilder(Func<InputControlLayout>, String, String, Nullable<InputDeviceMatcher>)

    Register a builder that delivers an InputControlLayout instance on demand.

    Declaration
    public static void RegisterLayoutBuilder(Func<InputControlLayout> buildMethod, string name, string baseLayout = null, InputDeviceMatcher? matches = null)
    Parameters
    Type Name Description
    Func<InputControlLayout> buildMethod

    Method to invoke to generate a layout when the layout is chosen. Should not cache the layout but rather return a fresh instance every time.

    String name

    Name under which to register the layout. If a layout with the same name is already registered, the call to this method will replace the existing layout.

    String baseLayout

    Name of the layout that the layout returned from buildMethod will be based on. The system needs to know this in advance in order to update devices correctly if layout registrations in the system are changed.

    Nullable<InputDeviceMatcher> matches

    Optional matcher for an InputDeviceDescription. If supplied, it is equivalent to calling RegisterLayoutMatcher(String, InputDeviceMatcher).

    Remarks

    Layout builders are most useful for procedurally building device layouts from metadata supplied by external systems. A good example is UnityEngine.InputSystem.HID where the "HID" standard includes a way for input devices to describe their various inputs and outputs in the form of a HID.HIDDeviceDescriptor. While not sufficient to build a perfectly robust InputDevice, these descriptions are usually enough to at least make the device work out-of-the-box to some extent.

    The builder method would usually use InputControlLayout.Builder to build the actual layout.

    InputSystem.RegisterLayoutBuilder(
        () =>
        {
            var builder = new InputControlLayout.Builder()
                .WithType<MyDevice>();
            builder.AddControl("button1").WithLayout("Button");
            return builder.Build();
        }, "MyCustomLayout"
    }

    Layout builders can be used in combination with onFindLayoutForDevice to build layouts dynamically for devices as they are connected to the system.

    Be aware that the same builder must not build different layouts. Each layout registered in the system is considered to be immutable for as long as it is registered. So, if a layout builder is registered under the name "Custom", for example, then every time the builder is invoked, it must return the same identical InputControlLayout.

    Exceptions
    Type Condition
    ArgumentNullException

    buildMethod is null -or- name is null or empty.

    See Also
    InputControlLayout.Builder
    onFindLayoutForDevice

    RegisterLayoutMatcher(String, InputDeviceMatcher)

    Add an additional device matcher to an existing layout.

    Declaration
    public static void RegisterLayoutMatcher(string layoutName, InputDeviceMatcher matcher)
    Parameters
    Type Name Description
    String layoutName

    Name of the device layout that should be instantiated if matcher matches an InputDeviceDescription of a discovered device.

    InputDeviceMatcher matcher

    Specification to match against InputDeviceDescription instances.

    Remarks

    Each device layout can have zero or more matchers associated with it. If any one of the matchers matches a given InputDeviceDescription (see MatchPercentage(InputDeviceDescription)) better than any other matcher (for the same or any other layout), then the given layout will be used for the discovered device.

    Note that registering a matcher may immediately lead to devices being created or recreated. If matcher matches any devices currently on the list of unsupported devices (see GetUnsupportedDevices()), new InputDevices will be created using the layout called layoutName. Also, if matcher matches the description of a device better than the matcher (if any) for the device's currently used layout, the device will be recreated using the given layout.

    Exceptions
    Type Condition
    ArgumentNullException

    layoutName is null or empty/

    ArgumentException

    matcher is empty (empty).

    See Also
    RegisterLayout(Type, String, Nullable<InputDeviceMatcher>)
    TryFindMatchingLayout(InputDeviceDescription)

    RegisterLayoutMatcher<TDevice>(InputDeviceMatcher)

    Add an additional device matcher to the layout registered for TDevice.

    Declaration
    public static void RegisterLayoutMatcher<TDevice>(InputDeviceMatcher matcher)
        where TDevice : InputDevice
    Parameters
    Type Name Description
    InputDeviceMatcher matcher

    A device matcher.

    Type Parameters
    Name Description
    TDevice

    Type that has been registered as a layout. See RegisterLayout<T>(String, Nullable<InputDeviceMatcher>).

    Remarks

    Calling this method is equivalent to calling RegisterLayoutMatcher(String, InputDeviceMatcher) with the name under which TDevice has been registered.

    Exceptions
    Type Condition
    ArgumentException

    matcher is empty (empty) -or- TDevice has not been registered as a layout.

    RegisterLayoutOverride(String, String)

    Register a layout that applies overrides to one or more other layouts.

    Declaration
    public static void RegisterLayoutOverride(string json, string name = null)
    Parameters
    Type Name Description
    String json

    Layout in JSON format.

    String name

    Optional name of the layout. If null or empty, the name is taken from the "name" property of the JSON data. If it is supplied, it will override the "name" property if present. If neither is supplied, an ArgumentException is thrown.

    Remarks

    Layout overrides are layout pieces that are applied on top of existing layouts. This can be used to modify any layout in the system non-destructively. The process works the same as extending an existing layout except that instead of creating a new layout by merging the derived layout and the base layout, the overrides are merged directly into the base layout.

    The layout merging logic used for overrides, is the same as the one used for derived layouts, i.e. MergeLayout(InputControlLayout).

    Layouts used as overrides look the same as normal layouts and have the same format. The only difference is that they are explicitly registered as overrides.

    Note that unlike "normal" layouts, layout overrides have the ability to extend multiple base layouts. The changes from the override will simply be merged into each of the layouts it extends. Use the extendMultiple rather than the extend property in JSON to give a list of base layouts instead of a single one.

    // Override default button press points on the gamepad triggers.
    InputSystem.RegisterLayoutOverride(@"
        {
            ""name"" : ""CustomTriggerPressPoints"",
            ""extend"" : ""Gamepad"",
            ""controls"" : [
                { ""name"" : ""leftTrigger"", ""parameters"" : ""pressPoint=0.25"" },
                { ""name"" : ""rightTrigger"", ""parameters"" : ""pressPoint=0.25"" }
            ]
        }
    ");

    RegisterPrecompiledLayout<TDevice>(String)

    Register a "baked" version of a device layout.

    Declaration
    public static void RegisterPrecompiledLayout<TDevice>(string metadata)
        where TDevice : InputDevice, new()
    Parameters
    Type Name Description
    String metadata

    Metadata automatically generated for the precompiled layout.

    Type Parameters
    Name Description
    TDevice

    C# class that represents the precompiled version of the device layout that the class is derived from.

    Remarks

    This method is used to register device implementations for which their layout has been "baked" into a C# class. To generate such a class, right-click a device layout in the input debugger and select "Generate Precompiled Layout". This generates a C# file containing a class that represents the precompiled version of the device layout. The class can be registered using this method.

    Note that registering a precompiled layout will not implicitly register the "normal" version of the layout. In other words, RegisterLayout<T>(String, Nullable<InputDeviceMatcher>) must be called before calling this method.

    // Register the non-precompiled, normal version of the layout.
    InputSystem.RegisterLayout<MyDevice>();
    
    // Register a precompiled version of the layout.
    InputSystem.RegisterPrecompiledLayout<PrecompiledMyDevice>(PrecompiledMyDevice.metadata);
    
    // This implicitly uses the precompiled version.
    InputSystem.AddDevice<MyDevice>();

    The main advantage of precompiled layouts is that instantiating them is many times faster than the default device creation path. By default, when creating an InputDevice, the system will have to load the InputControlLayout for the device as well as any layouts used directly or indirectly by that layout. This in itself is a slow process that generates GC heap garbage and uses .NET reflection (which itself may add additional permanent data to the GC heap). In addition, interpreting the layouts to construct an InputDevice and populate it with InputControl children is not a fast process.

    A precompiled layout, however, has all necessary construction steps "baked" into the generated code. It will not use reflection and will generally generate little to no GC heap garbage.

    A precompiled layout derives from the C# device class whose layout is "baked". If, for example, you generate a precompiled version for Keyboard, the resulting class will be derived from Keyboard. When registering the precompiled layout. If someone afterwards creates a Keyboard, the precompiled version will implicitly be instantiated and thus skips the default device creation path that will construct a Keyboard device from an InputControlLayout (it will thus not require the Keyboard layout or any other layout it depends on to be loaded).

    Note that when layout overrides (see RegisterLayoutOverride(String, String)) or new versions of existing layouts are registered (e.g. if you replace the built-in "Button" layout by registering a new layout with that name), precompiled layouts affected by the change will automatically be removed. This causes the system to fall back to the default device creation path which can take runtime layout changes into account.

    RegisterProcessor(Type, String)

    Register an InputProcessor<TValue> with the system.

    Declaration
    public static void RegisterProcessor(Type type, string name = null)
    Parameters
    Type Name Description
    Type type

    Type that implements InputProcessor.

    String name

    Name to use for the processor. If null or empty, name will be taken from the short name of type (if it ends in "Processor", that suffix will be clipped from the name). Names are case-insensitive.

    Remarks

    Processors are used by both bindings (see InputBinding) and by controls (see InputControl) to post-process input values as they are being requested from calls such as ReadValue<TValue>() or ReadValue().

    // Let's say that we want to define a processor that adds some random jitter to its input.
    // We have to pick a value type to operate on if we want to derive from InputProcessor<T>
    // so we go with float here.
    //
    // Also, as we will need to place our call to RegisterProcessor somewhere, we add attributes
    // to hook into Unity's initialization. This works differently in the editor and in the player,
    // so we use both [InitializeOnLoad] and [RuntimeInitializeOnLoadMethod].
    #if UNITY_EDITOR
    [InitializeOnLoad]
    #endif
    public class JitterProcessor : InputProcessor<float>
    {
        // Add a parameter that defines the amount of jitter we apply.
        // This will be editable in the Unity editor UI and can be set
        // programmatically in code. For example:
        //
        //    myAction.AddBinding("<Gamepad>/rightTrigger",
        //        processors: "jitter(amount=0.1)");
        //
        [Tooltip("Amount of jitter to apply. Will add a random value in the range [-amount..amount] "
                 + "to each input value.)]
        public float amount;
    
        // Process is called when an input value is read from a control. This is
        // where we perform our jitter.
        public override float Process(float value, InputControl control)
        {
            return float + Random.Range(-amount, amount);
        }
    
        // [InitializeOnLoad] will call the static class constructor which
        // we use to call Register.
        #if UNITY_EDITOR
        static JitterProcessor()
        {
            Register();
        }
        #endif
    
        // [RuntimeInitializeOnLoadMethod] will make sure that Register gets called
        // in the player on startup.
        // NOTE: This will also get called when going into play mode in the editor. In that
        //       case we get two calls to Register instead of one. We don't bother with that
        //       here. Calling RegisterProcessor twice here doesn't do any harm.
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        static void Register()
        {
            // We don't supply a name here. The input system will take "JitterProcessor"
            // and automatically snip off the "Processor" suffix thus leaving us with
            // a name of "Jitter" (all this is case-insensitive).
            InputSystem.RegisterProcessor<JitterProcessor>();
        }
    }
    
    // It doesn't really make sense in our case as the default parameter editor is just
    // fine (it will pick up the tooltip we defined above) but let's say we want to replace
    // the default float edit field we get on the "amount" parameter with a slider. We can
    // do so by defining a custom parameter editor.
    //
    // NOTE: We don't need to have a registration call here. The input system will automatically
    //       find our parameter editor based on the JitterProcessor type parameter we give to
    //       InputParameterEditor<T>.
    #if UNITY_EDITOR
    public class JitterProcessorEditor : InputParameterEditor<JitterProcessor>
    {
        public override void OnGUI()
        {
            target.amount = EditorGUILayout.Slider(m_AmountLabel, target.amount, 0, 0.25f);
        }
    
        private GUIContent m_AmountLabel = new GUIContent("Amount",
            "Amount of jitter to apply. Will add a random value in the range [-amount..amount] "
                + "to each input value.);
    }
    #endif

    Note that it is allowed to register the same processor type multiple types with different names. When doing so, the first registration is considered as the "proper" name for the processor and all subsequent registrations will be considered aliases.

    See the manual for more details.

    See Also
    InputProcessor<TValue>
    processors
    processors
    processors
    InputParameterEditor<TObject>

    RegisterProcessor<T>(String)

    Register an InputProcessor<TValue> with the system.

    Declaration
    public static void RegisterProcessor<T>(string name = null)
    Parameters
    Type Name Description
    String name

    Name to use for the processor. If null or empty, name will be taken from the short name of T (if it ends in "Processor", that suffix will be clipped from the name). Names are case-insensitive.

    Type Parameters
    Name Description
    T

    Type that implements InputProcessor.

    Remarks

    Processors are used by both bindings (see InputBinding) and by controls (see InputControl) to post-process input values as they are being requested from calls such as ReadValue<TValue>() or ReadValue().

    // Let's say that we want to define a processor that adds some random jitter to its input.
    // We have to pick a value type to operate on if we want to derive from InputProcessor<T>
    // so we go with float here.
    //
    // Also, as we will need to place our call to RegisterProcessor somewhere, we add attributes
    // to hook into Unity's initialization. This works differently in the editor and in the player,
    // so we use both [InitializeOnLoad] and [RuntimeInitializeOnLoadMethod].
    #if UNITY_EDITOR
    [InitializeOnLoad]
    #endif
    public class JitterProcessor : InputProcessor<float>
    {
        // Add a parameter that defines the amount of jitter we apply.
        // This will be editable in the Unity editor UI and can be set
        // programmatically in code. For example:
        //
        //    myAction.AddBinding("<Gamepad>/rightTrigger",
        //        processors: "jitter(amount=0.1)");
        //
        [Tooltip("Amount of jitter to apply. Will add a random value in the range [-amount..amount] "
                 + "to each input value.)]
        public float amount;
    
        // Process is called when an input value is read from a control. This is
        // where we perform our jitter.
        public override float Process(float value, InputControl control)
        {
            return float + Random.Range(-amount, amount);
        }
    
        // [InitializeOnLoad] will call the static class constructor which
        // we use to call Register.
        #if UNITY_EDITOR
        static JitterProcessor()
        {
            Register();
        }
        #endif
    
        // [RuntimeInitializeOnLoadMethod] will make sure that Register gets called
        // in the player on startup.
        // NOTE: This will also get called when going into play mode in the editor. In that
        //       case we get two calls to Register instead of one. We don't bother with that
        //       here. Calling RegisterProcessor twice here doesn't do any harm.
        [RuntimeInitializeOnLoadMethod]
        static void Register()
        {
            // We don't supply a name here. The input system will take "JitterProcessor"
            // and automatically snip off the "Processor" suffix thus leaving us with
            // a name of "Jitter" (all this is case-insensitive).
            InputSystem.RegisterProcessor<JitterProcessor>();
        }
    }
    
    // It doesn't really make sense in our case as the default parameter editor is just
    // fine (it will pick up the tooltip we defined above) but let's say we want to replace
    // the default float edit field we get on the "amount" parameter with a slider. We can
    // do so by defining a custom parameter editor.
    //
    // NOTE: We don't need to have a registration call here. The input system will automatically
    //       find our parameter editor based on the JitterProcessor type parameter we give to
    //       InputParameterEditor<T>.
    #if UNITY_EDITOR
    public class JitterProcessorEditor : InputParameterEditor<JitterProcessor>
    {
        public override void OnGUI()
        {
            target.amount = EditorGUILayout.Slider(m_AmountLabel, target.amount, 0, 0.25f);
        }
    
        private GUIContent m_AmountLabel = new GUIContent("Amount",
            "Amount of jitter to apply. Will add a random value in the range [-amount..amount] "
                + "to each input value.);
    }
    #endif

    Note that it is allowed to register the same processor type multiple types with different names. When doing so, the first registration is considered as the "proper" name for the processor and all subsequent registrations will be considered aliases.

    See the manual for more details.

    See Also
    InputProcessor<TValue>
    processors
    processors
    processors
    InputParameterEditor<TObject>

    RemoveDevice(InputDevice)

    Remove a device from the system such that it no longer receives input and is no longer part of the set of devices in devices.

    Declaration
    public static void RemoveDevice(InputDevice device)
    Parameters
    Type Name Description
    InputDevice device

    Device to remove. If the device has already been removed (i.e. if added is false), the method does nothing.

    Remarks

    Actions that are bound to controls on the device will automatically unbind when the device is removed.

    When a device is removed, onDeviceChange will be triggered with Removed. The device will be removed from devices as well as from any device-specific getters such as all.

    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    See Also
    added

    RemoveDeviceUsage(InputDevice, String)

    Remove a usage tag from the given device.

    Declaration
    public static void RemoveDeviceUsage(InputDevice device, string usage)
    Parameters
    Type Name Description
    InputDevice device

    Device to remove the usage from.

    String usage

    Usage to remove from the device.

    Remarks

    This method removes an existing usage from the given device. If the device does not have the given usage tag, the method does nothing. Use SetDeviceUsage(InputDevice, String) or AddDeviceUsage(InputDevice, String) to add usages to a device.

    The set of usages a device has can be queried with usages (a device is an InputControl and thus, like controls, has an associated set of usages).

    If the set of usages on the device changes as a result of calling this method, onDeviceChange will be triggered with UsageChanged.

    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    ArgumentException

    usage is null or empty.

    See Also
    usages
    SetDeviceUsage(InputDevice, String)
    AddDeviceUsage(InputDevice, String)
    CommonUsages
    UsageChanged

    RemoveDeviceUsage(InputDevice, InternedString)

    Remove a usage tag from the given device.

    Declaration
    public static void RemoveDeviceUsage(InputDevice device, InternedString usage)
    Parameters
    Type Name Description
    InputDevice device

    Device to remove the usage from.

    InternedString usage

    Usage to remove from the device.

    Remarks

    This method removes an existing usage from the given device. If the device does not have the given usage tag, the method does nothing. Use SetDeviceUsage(InputDevice, InternedString) or AddDeviceUsage(InputDevice, InternedString) to add usages to a device.

    The set of usages a device has can be queried with usages (a device is an InputControl and thus, like controls, has an associated set of usages).

    If the set of usages on the device changes as a result of calling this method, onDeviceChange will be triggered with UsageChanged.

    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    ArgumentException

    usage is empty.

    See Also
    usages
    SetDeviceUsage(InputDevice, InternedString)
    AddDeviceUsage(InputDevice, InternedString)
    CommonUsages
    UsageChanged

    RemoveLayout(String)

    Remove an already registered layout from the system.

    Declaration
    public static void RemoveLayout(string name)
    Parameters
    Type Name Description
    String name

    Name of the layout to remove. Note that layout names are case-insensitive.

    Remarks

    Note that removing a layout also removes all devices that directly or indirectly use the layout.

    This method can be used to remove both control or device layouts.

    ResetDevice(InputDevice, Boolean)

    Reset the state of the given device.

    Declaration
    public static void ResetDevice(InputDevice device, bool alsoResetDontResetControls = false)
    Parameters
    Type Name Description
    InputDevice device

    Device to reset. Must be added to the system.

    Boolean alsoResetDontResetControls

    If true, also reset controls that are marked as dontReset. Leads to HardReset.

    Remarks

    There are two different kinds of resets performed by the input system: a "soft" reset and a "hard" reset.

    A "hard" reset resets all controls on the device to their default state and also sends a RequestResetCommand to the backend, instructing to also reset its own internal state (if any) to the default.

    A "soft" reset will reset only controls that are not marked as noisy and not marked as dontReset. It will also not set a RequestResetCommand to the backend, i.e. the reset will be internal to the input system only (and thus can be partial in nature).

    By default, the method will perform a "soft" reset if device has noisy or dontReset controls. If it does not, it will perform a "hard" reset.

    A "hard" reset can be forced by setting alsoResetDontResetControls to true.

    // "Soft" reset the mouse. This will leave controls such as the mouse position intact
    // but will reset button press states.
    InputSystem.ResetDevice(Mouse.current);
    
    // "Hard" reset the mouse. This will wipe everything and reset the mouse to its default
    // state.
    InputSystem.ResetDevice(Mouse.current, alsoResetDontResetControls: true);

    Resetting a device will trigger a SoftReset or HardReset (based on the value of alsoResetDontResetControls) notification on onDeviceChange. Also, all InputActions currently in progress from controls on device will be cancelled (see canceled) in a way that guarantees for them to not get triggered. That is, a reset is semantically different from simply sending an event with default state. Using the latter, a button may be considered as going from pressed to released whereas with a device reset, the change back to unpressed state will not be considered a button release (and thus not trigger interactions that are waiting for a button release).

    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    InvalidOperationException

    device has not been added.

    See Also
    TrySyncDevice(InputDevice)
    HardReset
    SoftReset
    DeviceResetEvent

    ResetHaptics()

    Stop haptic effect playback on all devices.

    Declaration
    public static void ResetHaptics()
    Remarks

    Will reset haptics effects on all devices to their default state.

    Calls ResetHaptics() on all InputDevice that implement the interface.

    ResumeHaptics()

    Resume haptic effect playback on all devices.

    Declaration
    public static void ResumeHaptics()
    Remarks

    Calls ResumeHaptics() on all InputDevice that implement the interface.

    See Also
    PauseHaptics()

    SetDeviceUsage(InputDevice, String)

    Set the usage tag of the given device to usage.

    Declaration
    public static void SetDeviceUsage(InputDevice device, string usage)
    Parameters
    Type Name Description
    InputDevice device

    Device to set the usage on.

    String usage

    New usage for the device.

    Remarks

    Usages allow to "tag" a specific device such that the tag can then be used in lookups and bindings. A common use is for identifying the handedness of an XRController but the usages can be arbitrary strings.

    This method either sets the usages of the device to a single string (meaning it will clear whatever, if any usages, the device has when the method is called) or, if usage is null or empty, resets the usages of the device to be empty. To add to a device's set of usages, call AddDeviceUsage(InputDevice, String). To remove usages from a device, call RemoveDeviceUsage(InputDevice, String).

    The set of usages a device has can be queried with usages (a device is an InputControl and thus, like controls, has an associated set of usages).

    // Tag a gamepad to be associated with player #1.
    InputSystem.SetDeviceUsage(myGamepad, "Player1");
    
    // Create an action that binds to player #1's gamepad specifically.
    var action = new InputAction(binding: "<Gamepad>{Player1}/buttonSouth");
    
    // Move the tag from one gamepad to another.
    InputSystem.SetDeviceUsage(myGamepad, null); // Clears usages on 'myGamepad'.
    InputSystem.SetDeviceUsage(otherGamepad, "Player1");
    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    See Also
    usages
    AddDeviceUsage(InputDevice, String)
    RemoveDeviceUsage(InputDevice, String)
    CommonUsages
    UsageChanged

    SetDeviceUsage(InputDevice, InternedString)

    Set the usage tag of the given device to usage.

    Declaration
    public static void SetDeviceUsage(InputDevice device, InternedString usage)
    Parameters
    Type Name Description
    InputDevice device

    Device to set the usage on.

    InternedString usage

    New usage for the device.

    Remarks

    Usages allow to "tag" a specific device such that the tag can then be used in lookups and bindings. A common use is for identifying the handedness of an XRController but the usages can be arbitrary strings.

    This method either sets the usages of the device to a single string (meaning it will clear whatever, if any usages, the device has when the method is called) or, if usage is null or empty, resets the usages of the device to be empty. To add to a device's set of usages, call AddDeviceUsage(InputDevice, InternedString). To remove usages from a device, call RemoveDeviceUsage(InputDevice, InternedString).

    The set of usages a device has can be queried with usages (a device is an InputControl and thus, like controls, has an associated set of usages).

    If the set of usages on the device changes as a result of calling this method, onDeviceChange will be triggered with UsageChanged.

    // Tag a gamepad to be associated with player #1.
    InputSystem.SetDeviceUsage(myGamepad, new InternedString("Player1"));
    
    // Create an action that binds to player #1's gamepad specifically.
    var action = new InputAction(binding: "<Gamepad>{Player1}/buttonSouth");
    
    // Move the tag from one gamepad to another.
    InputSystem.SetDeviceUsage(myGamepad, null); // Clears usages on 'myGamepad'.
    InputSystem.SetDeviceUsage(otherGamepad, new InternedString("Player1"));
    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    See Also
    usages
    AddDeviceUsage(InputDevice, InternedString)
    RemoveDeviceUsage(InputDevice, InternedString)
    CommonUsages
    UsageChanged

    TryFindMatchingLayout(InputDeviceDescription)

    Try to match a description for an input device to a layout.

    Declaration
    public static string TryFindMatchingLayout(InputDeviceDescription deviceDescription)
    Parameters
    Type Name Description
    InputDeviceDescription deviceDescription

    Description of an input device.

    Returns
    Type Description
    String

    Name of the layout that has been matched to the given description or null if no matching layout was found.

    Remarks

    This method performs the same matching process that is invoked if a device is reported by the Unity runtime or using AddDevice(InputDeviceDescription). The result depends on the matches (InputDeviceMatcher) registered for the device layout in the system.

    var layoutName = InputSystem.TryFindMatchingLayout(
        new InputDeviceDescription
        {
            interface = "XInput",
            product = "Xbox Wired Controller",
            manufacturer = "Microsoft"
        }
    );
    See Also
    RegisterLayoutMatcher<TDevice>(InputDeviceMatcher)
    RegisterLayoutMatcher(String, InputDeviceMatcher)

    TryGetBindingComposite(String)

    Search for a registered binding composite type with the given name.

    Declaration
    public static Type TryGetBindingComposite(string name)
    Parameters
    Type Name Description
    String name

    Name of the registered binding composite to search for.

    Returns
    Type Description
    Type

    The type of the binding composite, if one was previously registered with the give name, otherwise null.

    See Also
    InputBindingComposite
    RegisterBindingComposite(Type, String)

    TryGetInteraction(String)

    Search for a registered interaction type with the given name.

    Declaration
    public static Type TryGetInteraction(string name)
    Parameters
    Type Name Description
    String name

    Name of the registered interaction to search for.

    Returns
    Type Description
    Type

    The type of the interaction, if one was previously registered with the give name, otherwise null.

    See Also
    IInputInteraction
    RegisterInteraction(Type, String)
    ListInteractions()

    TryGetProcessor(String)

    Return the processor type registered under the given name. If no such processor has been registered, return null.

    Declaration
    public static Type TryGetProcessor(string name)
    Parameters
    Type Name Description
    String name

    Name of processor. Case-insensitive.

    Returns
    Type Description
    Type

    The given processor type or null if not found.

    Exceptions
    Type Condition
    ArgumentNullException

    name is null or empty.

    See Also
    RegisterProcessor<T>(String)

    TrySyncDevice(InputDevice)

    Issue a RequestSyncCommand on device. This requests the device to send its current state as an event. If successful, the device will be updated in the next Update().

    Declaration
    public static bool TrySyncDevice(InputDevice device)
    Parameters
    Type Name Description
    InputDevice device

    An InputDevice that is currently part of devices.

    Returns
    Type Description
    Boolean

    True if the request succeeded, false if it fails.

    Remarks

    It depends on the backend/platform implementation whether explicit synchronization is supported. If it is, the method will return true. If it is not, the method will return false and the request is ignored.

    Exceptions
    Type Condition
    ArgumentNullException

    device is null.

    InvalidOperationException

    device has not been added.

    See Also
    RequestSyncCommand
    ResetDevice(InputDevice, Boolean)

    Update()

    Run a single update of input state.

    Declaration
    public static void Update()
    Remarks

    Except in tests and when using ProcessEventsManually, this method should not normally be called. The input system will automatically update as part of the player loop as determined by updateMode. Calling this method is equivalent to inserting extra frames, i.e. it will advance the entire state of the input system by one complete frame.

    When using Manual, this method MUST be called for input to update in the player. Not calling the method as part of the player loop may result in excessive memory consumption and/or potential loss of input.

    Each update will flush out buffered input events and cause them to be processed. This in turn will update the state of input devices (InputDevice) and trigger actions (InputAction) that monitor affected device state.

    See Also
    InputUpdateType
    updateMode

    Events

    onActionChange

    Event that is signalled when the state of enabled actions in the system changes or when actions are triggered.

    Declaration
    public static event Action<object, InputActionChange> onActionChange
    Event Type
    Type Description
    Action<Object, InputActionChange>
    Remarks

    The object received by the callback is either an InputAction, InputActionMap, or InputActionAsset depending on whether the InputActionChange affects a single action, an entire action map, or an entire action asset.

    For BoundControlsAboutToChange and BoundControlsChanged, the given object is an InputAction if the action is not part of an action map, an InputActionMap if the actions are part of a map but not part of an asset, and an InputActionAsset if the actions are part of an asset. In other words, the notification is sent for the topmost object in the hierarchy.

    Examples
    InputSystem.onActionChange +=
        (obj, change) =>
        {
            if (change == InputActionChange.ActionPerformed)
            {
                var action = (InputAction)obj;
                var control = action.activeControl;
                //...
            }
            else if (change == InputActionChange.ActionMapEnabled)
            {
                var actionMap = (InputActionMap)obj;
                //...
            }
            else if (change == InputActionChange.BoundControlsChanged)
            {
                // This is one way to deal with the fact that obj may be an InputAction
                // InputActionMap, or InputActionAsset and may be part of an InputActionAsset or not.
                var action = obj as InputAction;
                var actionMap = action?.actionMap ?? obj as InputActionMap;
                var actionAsset = actionMap?.asset ?? obj as InputActionAsset;
    
                // Note that if bound controls are changed on any map in an asset, there *will*
                // be a BoundControlsChanged notification for the entire asset.
    
                //...
            }
        };
    See Also
    controls

    onAfterUpdate

    Event that is fired after the input system has completed an update and processed all pending events.

    Declaration
    public static event Action onAfterUpdate
    Event Type
    Type Description
    Action
    See Also
    onBeforeUpdate
    Update()

    onBeforeUpdate

    Event that is fired before the input system updates.

    Declaration
    public static event Action onBeforeUpdate
    Event Type
    Type Description
    Action
    Remarks

    The input system updates in sync with player loop and editor updates. Input updates are run right before the respective script update. For example, an input update for Dynamic is run before MonoBehaviour.Update methods are executed.

    The update callback itself is triggered before the input system runs its own update and before it flushes out its event queue. This means that events queued from a callback will be fed right into the upcoming update.

    See Also
    onAfterUpdate
    Update()

    onDeviceChange

    Event that is signalled when the device setup in the system changes.

    Declaration
    public static event Action<InputDevice, InputDeviceChange> onDeviceChange
    Event Type
    Type Description
    Action<InputDevice, InputDeviceChange>

    Callback when device setup ni system changes.

    Remarks

    This can be used to detect when devices are added or removed as well as detecting when existing devices change their configuration.

    InputSystem.onDeviceChange +=
        (device, change) =>
        {
            switch (change)
            {
                case InputDeviceChange.Added:
                    Debug.Log("Device added: " + device);
                    break;
                case InputDeviceChange.Removed:
                    Debug.Log("Device removed: " + device);
                    break;
                case InputDeviceChange.ConfigurationChanged:
                    Debug.Log("Device configuration changed: " + device);
                    break;
            }
        };
    Exceptions
    Type Condition
    ArgumentNullException

    Delegate reference is null.

    See Also
    devices
    AddDevice<TDevice>(String)
    RemoveDevice(InputDevice)

    onDeviceCommand

    Event that is signalled when an InputDeviceCommand is sent to an InputDevice.

    Declaration
    public static event InputDeviceCommandDelegate onDeviceCommand
    Event Type
    Type Description
    InputDeviceCommandDelegate

    Event that gets signalled on InputDeviceCommands.

    Remarks

    This can be used to intercept commands and optionally handle them without them reaching the UnityEngine.InputSystem.LowLevel.IInputRuntime.

    The first delegate in the list that returns a result other than null is considered to have handled the command. If a command is handled by a delegate in the list, it will not be sent on to the runtime.

    Exceptions
    Type Condition
    ArgumentNullException

    Delegate reference is null.

    See Also
    ExecuteCommand<TCommand>(TCommand)
    UnityEngine.InputSystem.LowLevel.IInputRuntime.DeviceCommand(System.Int32,UnityEngine.InputSystem.LowLevel.InputDeviceCommand*)

    onFindLayoutForDevice

    Event that is signalled when the system is trying to match a layout to a device it has discovered.

    Declaration
    public static event InputDeviceFindControlLayoutDelegate onFindLayoutForDevice
    Event Type
    Type Description
    InputDeviceFindControlLayoutDelegate
    Remarks

    This event allows customizing the layout discovery process and to generate layouts on the fly, if need be. When a device is reported from the Unity runtime or through AddDevice(InputDeviceDescription), it is reported in the form of an InputDeviceDescription. The system will take that description and run it through all the InputDeviceMatchers that have been registered for layouts (RegisterLayoutMatcher<TDevice>(InputDeviceMatcher)). Based on that, it will come up with either no matching layout or with a single layout that has the highest matching score according to MatchPercentage(InputDeviceDescription) (or, in case multiple layouts have the same score, the first one to achieve that score -- which is quasi-non-deterministic).

    It will then take this layout name (which, again, may be empty) and invoke this event here passing it not only the layout name but also information such as the InputDeviceDescription for the device. Each of the callbacks hooked into the event will be run in turn. The first one to return a string that is not null and not empty will cause a switch from the layout the system has chosen to the layout that has been returned by the callback. The remaining layouts after that will then be invoked with that newly selected name but will not be able to change the name anymore.

    If none of the callbacks returns a string that is not null or empty, the system will stick with the layout that it had initially selected.

    Once all callbacks have been run, the system will either have a final layout name or not. If it does, a device is created using that layout. If it does not, no device is created.

    One thing this allows is to generate callbacks on the fly. Let's say that if an input device is reported with the "Custom" interface, we want to generate a layout for it on the fly. For details about how to build layouts dynamically from code, see InputControlLayout.Builder and RegisterLayoutBuilder(Func<InputControlLayout>, String, String, Nullable<InputDeviceMatcher>).

    InputSystem.onFindLayoutForDevice +=
        (deviceId, description, matchedLayout, runtime) =>
        {
            // If the system does have a matching layout, we do nothing.
            // This could be the case, for example, if we already generated
            // a layout for the device or if someone explicitly registered
            // a layout.
            if (!string.IsNullOrEmpty(matchedLayout))
                return null; // Tell system we did nothing.
    
            // See if the reported device uses the "Custom" interface. We
            // are only interested in those.
            if (description.interfaceName != "Custom")
                return null; // Tell system we did nothing.
    
            // So now we know that we want to build a layout on the fly
            // for this device. What we do is to register what's called a
            // layout builder. These can use C# code to build an InputControlLayout
            // on the fly.
    
            // First we need to come up with a sufficiently unique name for the layout
            // under which we register the builder. This will usually involve some
            // information from the InputDeviceDescription we have been supplied with.
            // Let's say we can sufficiently tell devices on our interface apart by
            // product name alone. So we just do this:
            var layoutName = "Custom" + description.product;
    
            // We also need an InputDeviceMatcher that in the future will automatically
            // select our newly registered layout whenever a new device of the same type
            // is connected. We can get one simply like so:
            var matcher = InputDeviceMatcher.FromDescription(description);
    
            // With these pieces in place, we can register our builder which
            // mainly consists of a delegate that will get invoked when an instance
            // of InputControlLayout is needed for the layout.
            InputSystem.RegisterLayoutBuilder(
                () =>
                {
                    // Here is where we do the actual building. In practice,
                    // this would probably look at the 'capabilities' property
                    // of the InputDeviceDescription we got and create a tailor-made
                    // layout. But what you put in the layout here really depends on
                    // the specific use case you have.
                    //
                    // We just add some preset things here which should still sufficiently
                    // serve as a demonstration.
                    //
                    // Note that we can base our layout here on whatever other layout
                    // in the system. We could extend Gamepad, for example. If we don't
                    // choose a base layout, the system automatically implies InputDevice.
    
                    var builder = new InputControlLayout.Builder()
                        .WithDisplayName(description.product);
    
                    // Add controls.
                    builder.AddControl("stick")
                        .WithLayout("Stick");
    
                    return builder.Build();
                },
                layoutName,
                matches: matcher);
    
            // So, we want the system to use our layout for the device that has just
            // been connected. We return it from this callback to do that.
            return layoutName;
        };

    Note that it may appear like one could simply use RegisterLayoutBuilder(Func<InputControlLayout>, String, String, Nullable<InputDeviceMatcher>) like below instead of going through onFindLayoutForDevice.

    InputSystem.RegisterLayoutBuilder(
        () =>
        {
            // Layout building code from above...
        },
        "CustomLayout",
        matches: new InputDeviceMatcher().WithInterface("Custom"));

    However, the difference here is that all devices using the "Custom" interface will end up with the same single layout -- which has to be identical. By hooking into onFindLayoutForDevice, it is possible to register a new layout for every new type of device that is discovered and thus build a multitude of different layouts.

    It is best to register for this callback during startup. One way to do it is to use InitializeOnLoadAttribute and RuntimeInitializeOnLoadMethod.

    See Also
    RegisterLayoutBuilder(Func<InputControlLayout>, String, String, Nullable<InputDeviceMatcher>)
    InputControlLayout

    onLayoutChange

    Event that is signalled when the layout setup in the system changes.

    Declaration
    public static event Action<string, InputControlLayoutChange> onLayoutChange
    Event Type
    Type Description
    Action<String, InputControlLayoutChange>
    Remarks

    First parameter is the name of the layout that has changed and second parameter is the type of change that has occurred.

    InputSystem.onLayoutChange +=
        (name, change) =>
        {
            switch (change)
            {
                case InputControlLayoutChange.Added:
                    Debug.Log($"New layout {name} has been added");
                    break;
                case InputControlLayoutChange.Removed:
                    Debug.Log($"Layout {name} has been removed");
                    break;
                case InputControlLayoutChange.Replaced:
                    Debug.Log($"Layout {name} has been updated");
                    break;
            }
        }
    See Also
    InputControlLayout

    onSettingsChange

    Event that is triggered if any of the properties in settings changes or if settings is replaced entirely with a new InputSettings object.

    Declaration
    public static event Action onSettingsChange
    Event Type
    Type Description
    Action
    See Also
    settings
    InputSettings
    In This Article
    • Properties
      • devices
      • disconnectedDevices
      • metrics
      • onAnyButtonPress
      • onEvent
      • pollingFrequency
      • remoting
      • settings
      • version
    • Methods
      • AddDevice(String, String, String)
      • AddDevice(InputDevice)
      • AddDevice(InputDeviceDescription)
      • AddDevice<TDevice>(String)
      • AddDeviceUsage(InputDevice, String)
      • AddDeviceUsage(InputDevice, InternedString)
      • DisableAllEnabledActions()
      • DisableDevice(InputDevice, Boolean)
      • EnableDevice(InputDevice)
      • FindControl(String)
      • FindControls(String)
      • FindControls<TControl>(String)
      • FindControls<TControl>(String, ref InputControlList<TControl>)
      • FlushDisconnectedDevices()
      • GetDevice(String)
      • GetDevice(Type)
      • GetDevice<TDevice>()
      • GetDevice<TDevice>(String)
      • GetDevice<TDevice>(InternedString)
      • GetDeviceById(Int32)
      • GetNameOfBaseLayout(String)
      • GetUnsupportedDevices()
      • GetUnsupportedDevices(List<InputDeviceDescription>)
      • IsFirstLayoutBasedOnSecond(String, String)
      • ListEnabledActions()
      • ListEnabledActions(List<InputAction>)
      • ListInteractions()
      • ListLayouts()
      • ListLayoutsBasedOn(String)
      • ListProcessors()
      • LoadLayout(String)
      • LoadLayout<TControl>()
      • PauseHaptics()
      • QueueConfigChangeEvent(InputDevice, Double)
      • QueueDeltaStateEvent<TDelta>(InputControl, TDelta, Double)
      • QueueEvent(InputEventPtr)
      • QueueEvent<TEvent>(ref TEvent)
      • QueueStateEvent<TState>(InputDevice, TState, Double)
      • QueueTextEvent(InputDevice, Char, Double)
      • RegisterBindingComposite(Type, String)
      • RegisterBindingComposite<T>(String)
      • RegisterInteraction(Type, String)
      • RegisterInteraction<T>(String)
      • RegisterLayout(String, String, Nullable<InputDeviceMatcher>)
      • RegisterLayout(Type, String, Nullable<InputDeviceMatcher>)
      • RegisterLayout<T>(String, Nullable<InputDeviceMatcher>)
      • RegisterLayoutBuilder(Func<InputControlLayout>, String, String, Nullable<InputDeviceMatcher>)
      • RegisterLayoutMatcher(String, InputDeviceMatcher)
      • RegisterLayoutMatcher<TDevice>(InputDeviceMatcher)
      • RegisterLayoutOverride(String, String)
      • RegisterPrecompiledLayout<TDevice>(String)
      • RegisterProcessor(Type, String)
      • RegisterProcessor<T>(String)
      • RemoveDevice(InputDevice)
      • RemoveDeviceUsage(InputDevice, String)
      • RemoveDeviceUsage(InputDevice, InternedString)
      • RemoveLayout(String)
      • ResetDevice(InputDevice, Boolean)
      • ResetHaptics()
      • ResumeHaptics()
      • SetDeviceUsage(InputDevice, String)
      • SetDeviceUsage(InputDevice, InternedString)
      • TryFindMatchingLayout(InputDeviceDescription)
      • TryGetBindingComposite(String)
      • TryGetInteraction(String)
      • TryGetProcessor(String)
      • TrySyncDevice(InputDevice)
      • Update()
    • Events
      • onActionChange
      • onAfterUpdate
      • onBeforeUpdate
      • onDeviceChange
      • onDeviceCommand
      • onFindLayoutForDevice
      • onLayoutChange
      • onSettingsChange
    Back to top Copyright © 2023 Unity Technologies — Terms of use
    Generated by DocFX
    on Saturday, May 27, 2023