Class InputDevice
Represents an input device which is always the root of a hierarchy of InputControl instances.
Inherited Members
Namespace: UnityEngine.InputSystem
Assembly: Unity.InputSystem.dll
Syntax
public class InputDevice : InputControl
Remarks
Input devices act as the container for control hierarchies. Every hierarchy has to have a device at the root. Devices cannot occur as children of other controls.
Devices are usually created automatically in response to hardware being discovered by the Unity runtime. However, it is possible to manually add devices using methods such as AddDevice<TDevice>(string).
// Add a "synthetic" gamepad that isn't actually backed by hardware.
var gamepad = InputSystem.AddDevice<Gamepad>();
There are subclasses representing the most common types of devices, like Mouse, Keyboard, Gamepad, and Touchscreen.
To create your own types of devices, you can derive from InputDevice and register your device as a new "layout".
// 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;
}
Devices can have usages like any other control (usages). Unlike other controls, however, usages of InputDevices are allowed to be changed on the fly without requiring a change to the device layout (see SetDeviceUsage(InputDevice, string)).
For a more complete example of how to implement custom input devices, check out the "Custom Device" sample which you can install from the Unity package manager.
And, as always, you can also find more information in the manual.
Constructors
InputDevice()
This constructor is public for the sake of Activator.CreateInstance
only. To construct
devices, use methods such as AddDevice<TDevice>(string). Manually
using new
on InputDevice will not result in a usable device.
Declaration
public InputDevice()
See Also
Fields
InvalidDeviceId
Value of an invalid deviceId.
Declaration
public const int InvalidDeviceId = 0
Field Value
Type | Description |
---|---|
int |
Remarks
The input system will not assigned this ID to any device.
See Also
Properties
added
Whether the device has been added to the system.
Declaration
public bool added { get; }
Property Value
Type | Description |
---|---|
bool | If true, the device is currently among the devices in devices. |
Remarks
Devices may be removed at any time. Either when their hardware is unplugged or when they are manually removed through RemoveDevice(InputDevice) or by being excluded through supportedDevices. When a device is removed, its instance, however, will not disappear. This property can be used to check whether the device is part of the current set of active devices.
See Also
allControls
A flattened list of controls that make up the device.
Declaration
public ReadOnlyArray<InputControl> allControls { get; }
Property Value
Type | Description |
---|---|
ReadOnlyArray<InputControl> |
Remarks
Does not allocate.
See Also
canRunInBackground
If true, the device is capable of delivering input while the application is running in the background, i.e.
while Application.isFocused
is false.
Declaration
public bool canRunInBackground { get; }
Property Value
Type | Description |
---|---|
bool | Whether the device can generate input while in the background. |
Remarks
The value of this property is determined by three separator factors.
For one, native devices have an inherent value for this property that can be retrieved through QueryCanRunInBackground. This determines whether at the input collection level, the device is capable of producing input independent of application. This is rare and only a select set of hardware, platform, and SDK/API combinations support this. The prominent class of input devices that in general do support this behavior are VR devices.
Furthermore, the property may be force-set through a device's layout by means of canRunInBackground.
Lastly, in the editor, the value of the property may be overridden depending on editorInputBehaviorInPlayMode in case certain devices are automatically kept running in play mode even when no Game View has focus.
Be aware that as far as players are concerned, only certain platforms support running Unity while not having focus. On mobile platforms, for example, this is generally not supported. In this case, the value of this property has no impact on input while the application does not have focus. See backgroundBehavior for more details.
See Also
description
Metadata describing the device (product name etc.).
Declaration
public InputDeviceDescription description { get; }
Property Value
Type | Description |
---|---|
InputDeviceDescription |
Remarks
The description of a device is unchanging over its lifetime and does not comprise data about a device's configuration (which is considered mutable).
In most cases, the description for a device is supplied by the Unity runtime. This it the case for all native input devices. However, it is also possible to inject new devices in the form of device descriptions into the system using AddDevice(InputDeviceDescription).
The description of a device is what is matched by an InputDeviceMatcher to find the layout to use for a device.
See Also
deviceId
Unique numeric ID for the device.
Declaration
public int deviceId { get; }
Property Value
Type | Description |
---|---|
int |
Remarks
This is only assigned once a device has been added to the system. No two devices will receive the same ID and no device will receive an ID that another device used before even if the device was removed. The only exception to this is if a device gets re-created as part of a layout change. For example, if a new layout is registered that replaces the Mouse layout, all Mouse devices will get recreated but will keep their existing device IDs.
IDs are assigned by the input runtime.
See Also
enabled
Whether the device is currently enabled (that is, sends and receives events).
Declaration
public bool enabled { get; }
Property Value
Type | Description |
---|---|
bool |
Remarks
A device that is disabled will not receive events. I.e. events that are being sent to the device will be ignored.
When disabling a native device, a disable command will also be sent to the runtime. It depends on the specific runtime whether the device command is supported but if it is, the device will be disabled in the runtime and no longer send events. This is especially important for devices such as sensors that incur both computation and battery consumption overhead while enabled.
Specific types of devices can choose to start out in disabled state by default. This is generally the case for sensors to ensure that their overhead is only incurred when actually being used by the application.
See Also
lastUpdateTime
Timestamp of last state event used to update the device.
Declaration
public double lastUpdateTime { get; }
Property Value
Type | Description |
---|---|
double |
Remarks
Events other than StateEvent and DeltaStateEvent will not cause lastUpdateTime to be changed. The "timeline" is reset to 0 when entering play mode. If there are any events incoming or device updates which occur prior to entering play mode, these will appear negative.
See Also
native
Whether the device comes from the runtime
Declaration
public bool native { get; }
Property Value
Type | Description |
---|---|
bool | Whether the device has been discovered by the Unity runtime. |
Remarks
Devices can be discovered when reported by the runtime or they can be added manually through the various AddDevice APIs. Devices reported by the runtime will return true for this property whereas devices added manually will return false.
Devices reported by the runtime will usually come from the Unity engine itself.
See Also
remote
Whether the device is mirrored from a remote input system and not actually present as a "real" device in the local system.
Declaration
public bool remote { get; }
Property Value
Type | Description |
---|---|
bool | Whether the device mirrors a device from a remotely connected input system. |
See Also
updateBeforeRender
Whether the device requires an extra update before rendering.
Declaration
public bool updateBeforeRender { get; }
Property Value
Type | Description |
---|---|
bool |
Remarks
The value of this property is determined by updateBeforeRender in the device's control layout.
The extra update is necessary for tracking devices that are used in rendering code. For example, the eye transforms of an HMD should be refreshed right before rendering as refreshing only in the beginning of the frame will lead to a noticeable lag.
See Also
valueSizeInBytes
Size in bytes of values that the control returns.
Declaration
public override int valueSizeInBytes { get; }
Property Value
Type | Description |
---|---|
int |
Overrides
See Also
valueType
Returns the underlying value type of this control.
Declaration
public override Type valueType { get; }
Property Value
Type | Description |
---|---|
Type | Type of values produced by the control. |
Overrides
Remarks
This is the type of values that are returned when reading the current value of a control or when reading a value of a control from an event.
See Also
wasUpdatedThisFrame
Declaration
public bool wasUpdatedThisFrame { get; }
Property Value
Type | Description |
---|---|
bool |
See Also
Methods
CompareValue(void*, void*)
Compare the value of the control as read from firstStatePtr
to that read from
secondStatePtr
and return true if they are equal.
Declaration
public override bool CompareValue(void* firstStatePtr, void* secondStatePtr)
Parameters
Type | Name | Description |
---|---|---|
void* | firstStatePtr | Memory containing the control's stateBlock. |
void* | secondStatePtr | Memory containing the control's stateBlock |
Returns
Type | Description |
---|---|
bool | True if the value of the control is equal in both |
Overrides
Remarks
Unlike CompareValue(void*, void*), this method will have to do more than just compare the memory for the control in the two state buffers. It will have to read out state for the control and run the full processing machinery for the control to turn the state into a final, processed value. CompareValue is thus more costly than CompareValue(void*, void*).
This method will apply epsilons (Epsilon) when comparing floats.
See Also
ExecuteCommand(InputDeviceCommand*)
Declaration
protected virtual long ExecuteCommand(InputDeviceCommand* commandPtr)
Parameters
Type | Name | Description |
---|---|---|
InputDeviceCommand* | commandPtr |
Returns
Type | Description |
---|---|
long |
See Also
ExecuteCommand<TCommand>(ref TCommand)
Perform a device-specific command.
Declaration
public long ExecuteCommand<TCommand>(ref TCommand command) where TCommand : struct, IInputDeviceCommandInfo
Parameters
Type | Name | Description |
---|---|---|
TCommand | command | Data for the command to be performed. |
Returns
Type | Description |
---|---|
long | A transfer-specific return code. Negative values are considered failure codes. |
Type Parameters
Name | Description |
---|---|
TCommand |
Remarks
Commands allow devices to set up custom protocols without having to extend the device API. This is most useful for devices implemented in the native Unity runtime which, through the command interface, may provide custom, device-specific functions.
This is a low-level API. It works in a similar way to DeviceIoControl on Windows and ioctl on UNIX-like systems.
See Also
MakeCurrent()
Make this the current device of its type.
Declaration
public virtual void MakeCurrent()
Remarks
This method is called automatically by the input system when a device is
added or when input is received on it. Many types of devices have .current
getters that allow querying the last used device of a specific type directly (for
example, see current).
There is one special case, however, related to noise. A device that has noisy controls
(i.e. controls for which noisy is true) may receive input events
that contain no meaningful user interaction but are simply just noise from the device. A
good example of this is the PS4 gamepad which has a built-in gyro and may thus constantly
feed events into the input system even if not being actually in use. If, for example, an
Xbox gamepad and PS4 gamepad are both connected to a PC and the user is playing with the
Xbox gamepad, the PS4 gamepad would still constantly make itself current
by simply flooding the system with events. Hence why by default, noise on .current
getters
will be filtered out and a device will only see MakeCurrent
getting called if their input
was detected on non-noisy controls.
See Also
OnAdded()
Called by the system when the device is added to devices.
Declaration
protected virtual void OnAdded()
Remarks
This is called after the device has already been added.
See Also
OnConfigurationChanged()
Called by the system when the device configuration is changed. This happens when the backend sends a DeviceConfigurationEvent for the device.
Declaration
protected virtual void OnConfigurationChanged()
Remarks
This method can be used to flush out cached information. An example of where this happens is KeyControl caching information about the display name of a control. As this depends on the current keyboard layout, the information has to be fetched dynamically (this happens using QueryKeyNameCommand). Whenever the keyboard layout changes, the system sends a DeviceConfigurationEvent for the Keyboard at which point the device flushes all cached key names.
See Also
OnRemoved()
Called by the system when the device is removed from devices.
Declaration
protected virtual void OnRemoved()
Remarks
This is called after the device has already been removed.
See Also
ReadValueFromBufferAsObject(void*, int)
Declaration
public override object ReadValueFromBufferAsObject(void* buffer, int bufferSize)
Parameters
Type | Name | Description |
---|---|---|
void* | buffer | |
int | bufferSize |
Returns
Type | Description |
---|---|
object |
Overrides
See Also
ReadValueFromStateAsObject(void*)
Read the control's final, processed value from the given state and return the value as an object.
Declaration
public override object ReadValueFromStateAsObject(void* statePtr)
Parameters
Type | Name | Description |
---|---|---|
void* | statePtr |
Returns
Type | Description |
---|---|
object | The control's value as stored in |
Overrides
Remarks
This method allocates GC memory and should not be used during normal gameplay operation.
Exceptions
Type | Condition |
---|---|
ArgumentNullException |
|
See Also
ReadValueFromStateIntoBuffer(void*, void*, int)
Read the control's final, processed value from the given state and store it in the given buffer.
Declaration
public override void ReadValueFromStateIntoBuffer(void* statePtr, void* bufferPtr, int bufferSize)
Parameters
Type | Name | Description |
---|---|---|
void* | statePtr | State to read the value for the control from. |
void* | bufferPtr | Buffer to store the value in. |
int | bufferSize | Size of |
Overrides
Exceptions
Type | Condition |
---|---|
ArgumentNullException |
|
ArgumentException |
|