A game about forced loneliness, made by TACStudios
1using System.Linq;
2using UnityEngine.InputSystem.Utilities;
3#if UNITY_EDITOR
4using UnityEditor;
5using UnityEngine.InputSystem.Editor;
6using UnityEngine.InputSystem.HID.Editor;
7#endif
8
9namespace UnityEngine.InputSystem.HID
10{
11 using ShouldCreateHIDCallback = System.Func<HID.HIDDeviceDescriptor, bool?>;
12
13 /// <summary>
14 /// Adds support for generic HID devices to the input system.
15 /// </summary>
16 /// <remarks>
17 /// Even without this module, HIDs can be used on platforms where we
18 /// support HID has a native backend (Windows and OSX, at the moment).
19 /// However, each supported HID requires a layout specifically targeting
20 /// it as a product.
21 ///
22 /// What this module adds is the ability to turn any HID with usable
23 /// controls into an InputDevice. It will make a best effort to figure
24 /// out a suitable class for the device and will use the HID elements
25 /// present in the HID report descriptor to populate the device.
26 ///
27 /// If there is an existing product-specific layout for a HID, it will
28 /// take precedence and HIDSupport will leave the device alone.
29 /// </remarks>
30 public static class HIDSupport
31 {
32 /// <summary>
33 /// A pair of HID usage page and HID usage number.
34 /// </summary>
35 /// <remarks>
36 /// Used to describe a HID usage for the <see cref="supportedHIDUsages"/> property.
37 /// </remarks>
38 public struct HIDPageUsage
39 {
40 /// <summary>
41 /// The usage page.
42 /// </summary>
43 public HID.UsagePage page;
44
45 /// <summary>
46 /// A number specifying the usage on the usage page.
47 /// </summary>
48 public int usage;
49
50 /// <summary>
51 /// Create a HIDPageUsage struct by specifying a page and usage.
52 /// </summary>
53 public HIDPageUsage(HID.UsagePage page, int usage)
54 {
55 this.page = page;
56 this.usage = usage;
57 }
58
59 /// <summary>
60 /// Create a HIDPageUsage struct from the GenericDesktop usage page by specifying the usage.
61 /// </summary>
62 public HIDPageUsage(HID.GenericDesktop usage)
63 {
64 page = HID.UsagePage.GenericDesktop;
65 this.usage = (int)usage;
66 }
67 }
68
69 private static HIDPageUsage[] s_SupportedHIDUsages;
70
71 /// <summary>
72 /// An array of HID usages the input is configured to support.
73 /// </summary>
74 /// <remarks>
75 /// The input system will only create <see cref="InputDevice"/>s for HIDs with usages
76 /// listed in this array. Any other HID will be ignored. This saves the input system from
77 /// spending resources on creating layouts and devices for HIDs which are not supported or
78 /// not usable for game input.
79 ///
80 /// By default, this includes only <see cref="HID.GenericDesktop.Joystick"/>,
81 /// <see cref="HID.GenericDesktop.Gamepad"/> and <see cref="HID.GenericDesktop.MultiAxisController"/>,
82 /// but you can set this property to include any other HID usages.
83 ///
84 /// Note that currently on macOS, the only HID usages which can be enabled are
85 /// <see cref="HID.GenericDesktop.Joystick"/>, <see cref="HID.GenericDesktop.Gamepad"/>,
86 /// <see cref="HID.GenericDesktop.MultiAxisController"/>, <see cref="HID.GenericDesktop.TabletPCControls"/>,
87 /// and <see cref="HID.GenericDesktop.AssistiveControl"/>.
88 /// </remarks>
89 public static ReadOnlyArray<HIDPageUsage> supportedHIDUsages
90 {
91 get => s_SupportedHIDUsages;
92 set
93 {
94 s_SupportedHIDUsages = value.ToArray();
95
96 // Add HIDs we now support.
97 InputSystem.s_Manager.AddAvailableDevicesThatAreNowRecognized();
98
99 // Remove HIDs we no longer support.
100 for (var i = 0; i < InputSystem.devices.Count; ++i)
101 {
102 var device = InputSystem.devices[i];
103 if (device is HID hid && !s_SupportedHIDUsages.Contains(new HIDPageUsage(hid.hidDescriptor.usagePage, hid.hidDescriptor.usage)))
104 {
105 // Remove the entire generated layout. This will also remove all devices based on it.
106 InputSystem.RemoveLayout(device.layout);
107 --i;
108 }
109 }
110 }
111 }
112
113 /// <summary>
114 /// Add support for generic HIDs to InputSystem.
115 /// </summary>
116#if UNITY_DISABLE_DEFAULT_INPUT_PLUGIN_INITIALIZATION
117 public
118#else
119 internal
120#endif
121 static void Initialize()
122 {
123 s_SupportedHIDUsages = new[]
124 {
125 new HIDPageUsage(HID.GenericDesktop.Joystick),
126 new HIDPageUsage(HID.GenericDesktop.Gamepad),
127 new HIDPageUsage(HID.GenericDesktop.MultiAxisController),
128 };
129
130 InputSystem.RegisterLayout<HID>();
131 InputSystem.onFindLayoutForDevice += HID.OnFindLayoutForDevice;
132
133 // Add toolbar button to any devices using the "HID" interface. Opens
134 // a windows to browse the HID descriptor of the device.
135 #if UNITY_EDITOR
136 InputDeviceDebuggerWindow.onToolbarGUI +=
137 device =>
138 {
139 if (device.description.interfaceName == HID.kHIDInterface)
140 {
141 if (GUILayout.Button(s_HIDDescriptor, EditorStyles.toolbarButton))
142 {
143 HIDDescriptorWindow.CreateOrShowExisting(device.deviceId, device.description);
144 }
145 }
146 };
147 #endif
148 }
149
150 #if UNITY_EDITOR
151 private static readonly GUIContent s_HIDDescriptor = new GUIContent("HID Descriptor");
152 #endif
153 }
154}