155 lines
5.9 KiB
C#
155 lines
5.9 KiB
C#
using System.Linq;
|
|
using UnityEngine.InputSystem.Utilities;
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
using UnityEngine.InputSystem.Editor;
|
|
using UnityEngine.InputSystem.HID.Editor;
|
|
#endif
|
|
|
|
namespace UnityEngine.InputSystem.HID
|
|
{
|
|
using ShouldCreateHIDCallback = System.Func<HID.HIDDeviceDescriptor, bool?>;
|
|
|
|
/// <summary>
|
|
/// Adds support for generic HID devices to the input system.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Even without this module, HIDs can be used on platforms where we
|
|
/// support HID has a native backend (Windows and OSX, at the moment).
|
|
/// However, each supported HID requires a layout specifically targeting
|
|
/// it as a product.
|
|
///
|
|
/// What this module adds is the ability to turn any HID with usable
|
|
/// controls into an InputDevice. It will make a best effort to figure
|
|
/// out a suitable class for the device and will use the HID elements
|
|
/// present in the HID report descriptor to populate the device.
|
|
///
|
|
/// If there is an existing product-specific layout for a HID, it will
|
|
/// take precedence and HIDSupport will leave the device alone.
|
|
/// </remarks>
|
|
public static class HIDSupport
|
|
{
|
|
/// <summary>
|
|
/// A pair of HID usage page and HID usage number.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Used to describe a HID usage for the <see cref="supportedHIDUsages"/> property.
|
|
/// </remarks>
|
|
public struct HIDPageUsage
|
|
{
|
|
/// <summary>
|
|
/// The usage page.
|
|
/// </summary>
|
|
public HID.UsagePage page;
|
|
|
|
/// <summary>
|
|
/// A number specifying the usage on the usage page.
|
|
/// </summary>
|
|
public int usage;
|
|
|
|
/// <summary>
|
|
/// Create a HIDPageUsage struct by specifying a page and usage.
|
|
/// </summary>
|
|
public HIDPageUsage(HID.UsagePage page, int usage)
|
|
{
|
|
this.page = page;
|
|
this.usage = usage;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a HIDPageUsage struct from the GenericDesktop usage page by specifying the usage.
|
|
/// </summary>
|
|
public HIDPageUsage(HID.GenericDesktop usage)
|
|
{
|
|
page = HID.UsagePage.GenericDesktop;
|
|
this.usage = (int)usage;
|
|
}
|
|
}
|
|
|
|
private static HIDPageUsage[] s_SupportedHIDUsages;
|
|
|
|
/// <summary>
|
|
/// An array of HID usages the input is configured to support.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The input system will only create <see cref="InputDevice"/>s for HIDs with usages
|
|
/// listed in this array. Any other HID will be ignored. This saves the input system from
|
|
/// spending resources on creating layouts and devices for HIDs which are not supported or
|
|
/// not usable for game input.
|
|
///
|
|
/// By default, this includes only <see cref="HID.GenericDesktop.Joystick"/>,
|
|
/// <see cref="HID.GenericDesktop.Gamepad"/> and <see cref="HID.GenericDesktop.MultiAxisController"/>,
|
|
/// but you can set this property to include any other HID usages.
|
|
///
|
|
/// Note that currently on macOS, the only HID usages which can be enabled are
|
|
/// <see cref="HID.GenericDesktop.Joystick"/>, <see cref="HID.GenericDesktop.Gamepad"/>,
|
|
/// <see cref="HID.GenericDesktop.MultiAxisController"/>, <see cref="HID.GenericDesktop.TabletPCControls"/>,
|
|
/// and <see cref="HID.GenericDesktop.AssistiveControl"/>.
|
|
/// </remarks>
|
|
public static ReadOnlyArray<HIDPageUsage> supportedHIDUsages
|
|
{
|
|
get => s_SupportedHIDUsages;
|
|
set
|
|
{
|
|
s_SupportedHIDUsages = value.ToArray();
|
|
|
|
// Add HIDs we now support.
|
|
InputSystem.s_Manager.AddAvailableDevicesThatAreNowRecognized();
|
|
|
|
// Remove HIDs we no longer support.
|
|
for (var i = 0; i < InputSystem.devices.Count; ++i)
|
|
{
|
|
var device = InputSystem.devices[i];
|
|
if (device is HID hid && !s_SupportedHIDUsages.Contains(new HIDPageUsage(hid.hidDescriptor.usagePage, hid.hidDescriptor.usage)))
|
|
{
|
|
// Remove the entire generated layout. This will also remove all devices based on it.
|
|
InputSystem.RemoveLayout(device.layout);
|
|
--i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add support for generic HIDs to InputSystem.
|
|
/// </summary>
|
|
#if UNITY_DISABLE_DEFAULT_INPUT_PLUGIN_INITIALIZATION
|
|
public
|
|
#else
|
|
internal
|
|
#endif
|
|
static void Initialize()
|
|
{
|
|
s_SupportedHIDUsages = new[]
|
|
{
|
|
new HIDPageUsage(HID.GenericDesktop.Joystick),
|
|
new HIDPageUsage(HID.GenericDesktop.Gamepad),
|
|
new HIDPageUsage(HID.GenericDesktop.MultiAxisController),
|
|
};
|
|
|
|
InputSystem.RegisterLayout<HID>();
|
|
InputSystem.onFindLayoutForDevice += HID.OnFindLayoutForDevice;
|
|
|
|
// Add toolbar button to any devices using the "HID" interface. Opens
|
|
// a windows to browse the HID descriptor of the device.
|
|
#if UNITY_EDITOR
|
|
InputDeviceDebuggerWindow.onToolbarGUI +=
|
|
device =>
|
|
{
|
|
if (device.description.interfaceName == HID.kHIDInterface)
|
|
{
|
|
if (GUILayout.Button(s_HIDDescriptor, EditorStyles.toolbarButton))
|
|
{
|
|
HIDDescriptorWindow.CreateOrShowExisting(device.deviceId, device.description);
|
|
}
|
|
}
|
|
};
|
|
#endif
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
private static readonly GUIContent s_HIDDescriptor = new GUIContent("HID Descriptor");
|
|
#endif
|
|
}
|
|
}
|