暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

XInputController.cs 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. using System;
  2. using UnityEngine.InputSystem.Controls;
  3. using UnityEngine.InputSystem.Layouts;
  4. ////TODO: expose user index
  5. ////TODO: set displayNames of the controls according to Xbox controller standards
  6. namespace UnityEngine.InputSystem.XInput
  7. {
  8. /// <summary>
  9. /// An XInput-compatible game controller.
  10. /// </summary>
  11. /// <remarks>
  12. /// Note that on non-Microsoft platforms, XInput controllers will not actually use the XInput interface
  13. /// but will rather be interfaced with through different APIs -- on OSX, for example, HID is used to
  14. /// interface with Xbox controlllers. In those cases, XInput-specific functionality (like <see cref="Capabilities"/>)
  15. /// will not be available.
  16. ///
  17. /// On Windows, XInput controllers will be reported with <see cref="InputDeviceDescription.interfaceName"/>
  18. /// set to <c>"XInput"</c> and with a JSON representation of <a
  19. /// href="https://docs.microsoft.com/en-us/windows/win32/api/xinput/ns-xinput-xinput_capabilities">XINPUT_CAPABILITIES</a>
  20. /// available in <see cref="InputDeviceDescription.capabilities"/>. This means that you match on those
  21. /// <c>subType</c> and/or <c>flags</c> for example.
  22. ///
  23. /// <example>
  24. /// <code>
  25. /// // Create an XInput-specific guitar layout subtype.
  26. /// // NOTE: Works only on Windows.
  27. /// InputSystem.RegisterLayout(@"
  28. /// {
  29. /// ""name"" : ""XInputGuitar"",
  30. /// ""displayName"" : ""Guitar"",
  31. /// ""extend"" : ""XInputController"",
  32. /// ""device"" : {
  33. /// ""interface"" : ""XInput"",
  34. /// ""capabilities"" : [
  35. /// { ""path"" : ""subType"", ""value"" : ""6"" }
  36. /// ]
  37. /// }
  38. /// }
  39. /// ");
  40. /// </code>
  41. /// </example>
  42. ///
  43. /// Now, when an XInput controller is connected and reports itself with the
  44. /// subtype "Guitar", it is turned into an "XInputGuitar" instead of an
  45. /// "XInputController".
  46. /// </remarks>
  47. [InputControlLayout(displayName = "Xbox Controller")]
  48. public class XInputController : Gamepad
  49. {
  50. /// <summary>
  51. /// Same as <see cref="Gamepad.startButton"/>.
  52. /// </summary>
  53. /// <value>Same control as <see cref="Gamepad.startButton"/>.</value>
  54. // Change the display names for the buttons to conform to Xbox conventions.
  55. [InputControl(name = "buttonSouth", displayName = "A")]
  56. [InputControl(name = "buttonEast", displayName = "B")]
  57. [InputControl(name = "buttonWest", displayName = "X")]
  58. [InputControl(name = "buttonNorth", displayName = "Y")]
  59. [InputControl(name = "leftShoulder", displayName = "Left Bumper", shortDisplayName = "LB")]
  60. [InputControl(name = "rightShoulder", displayName = "Right Bumper", shortDisplayName = "RB")]
  61. [InputControl(name = "leftTrigger", shortDisplayName = "LT")]
  62. [InputControl(name = "rightTrigger", shortDisplayName = "RT")]
  63. // This follows Xbox One conventions; on Xbox 360, this is start=start and select=back.
  64. [InputControl(name = "start", displayName = "Menu", alias = "menu")]
  65. [InputControl(name = "select", displayName = "View", alias = "view")]
  66. public ButtonControl menu { get; protected set; }
  67. /// <summary>
  68. /// Same as <see cref="Gamepad.selectButton"/>
  69. /// </summary>
  70. /// <value>Same control as <see cref="Gamepad.selectButton"/>.</value>
  71. public ButtonControl view { get; protected set; }
  72. /// <summary>
  73. /// What specific kind of XInput controller this is.
  74. /// </summary>
  75. /// <value>XInput device subtype.</value>
  76. /// <remarks>
  77. /// When the controller is picked up through interfaces other than XInput or through old versions of
  78. /// XInput, this will always be <see cref="DeviceSubType.Unknown"/>. Put another way, this value is
  79. /// meaningful only on recent Microsoft platforms.
  80. /// </remarks>
  81. /// <seealso href="https://docs.microsoft.com/en-us/windows/win32/xinput/xinput-and-controller-subtypes"/>
  82. public DeviceSubType subType
  83. {
  84. get
  85. {
  86. if (!m_HaveParsedCapabilities)
  87. ParseCapabilities();
  88. return m_SubType;
  89. }
  90. }
  91. /// <summary>
  92. /// Return the device flags as reported by XInput.
  93. /// </summary>
  94. /// <value>XInput device flags.</value>
  95. /// <seealso href="https://docs.microsoft.com/en-us/windows/win32/api/xinput/ns-xinput-xinput_capabilities"/>
  96. public DeviceFlags flags
  97. {
  98. get
  99. {
  100. if (!m_HaveParsedCapabilities)
  101. ParseCapabilities();
  102. return m_Flags;
  103. }
  104. }
  105. /// <inheritdoc />
  106. protected override void FinishSetup()
  107. {
  108. base.FinishSetup();
  109. menu = startButton;
  110. view = selectButton;
  111. }
  112. private bool m_HaveParsedCapabilities;
  113. private DeviceSubType m_SubType;
  114. private DeviceFlags m_Flags;
  115. private void ParseCapabilities()
  116. {
  117. if (!string.IsNullOrEmpty(description.capabilities))
  118. {
  119. var capabilities = JsonUtility.FromJson<Capabilities>(description.capabilities);
  120. m_SubType = capabilities.subType;
  121. m_Flags = capabilities.flags;
  122. }
  123. m_HaveParsedCapabilities = true;
  124. }
  125. /// <summary>
  126. /// Controller type enumeration in <c>Type</c> field of <c>XINPUT_CAPABILITIES</c>.
  127. /// </summary>
  128. /// <remarks>
  129. /// See <a href="https://docs.microsoft.com/en-us/windows/win32/api/xinput/ns-xinput-xinput_capabilities">MSDN</a>.
  130. /// </remarks>
  131. internal enum DeviceType
  132. {
  133. Gamepad = 0x00
  134. }
  135. /// <summary>
  136. /// Controller subtype enumeration in <c>SubType</c> field of <c>XINPUT_CAPABILITIES</c>.
  137. /// </summary>
  138. /// <remarks>
  139. /// See <a href="https://docs.microsoft.com/en-us/windows/win32/xinput/xinput-and-controller-subtypes">MSDN</a>.
  140. /// </remarks>
  141. public enum DeviceSubType
  142. {
  143. Unknown = 0x00,
  144. Gamepad = 0x01,
  145. Wheel = 0x02,
  146. ArcadeStick = 0x03,
  147. FlightStick = 0x04,
  148. DancePad = 0x05,
  149. Guitar = 0x06,
  150. GuitarAlternate = 0x07,
  151. DrumKit = 0x08,
  152. GuitarBass = 0x0B,
  153. ArcadePad = 0x13
  154. }
  155. /// <summary>
  156. /// Controller flags in <c>Flags</c> field of <c>XINPUT_CAPABILITIES</c>.
  157. /// </summary>
  158. /// <remarks>
  159. /// See <a href="https://docs.microsoft.com/en-us/windows/win32/api/xinput/ns-xinput-xinput_capabilities">MSDN</a>.
  160. /// </remarks>
  161. [Flags]
  162. public new enum DeviceFlags
  163. {
  164. ForceFeedbackSupported = 0x01,
  165. Wireless = 0x02,
  166. VoiceSupported = 0x04,
  167. PluginModulesSupported = 0x08,
  168. NoNavigation = 0x10,
  169. }
  170. [Serializable]
  171. internal struct Capabilities
  172. {
  173. public DeviceType type;
  174. public DeviceSubType subType;
  175. public DeviceFlags flags;
  176. }
  177. }
  178. }