File size: 6,018 Bytes
18a519f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | 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
}
}
|