123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- 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
- }
- }
|