XRSimulatedControllerState.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. using System.Runtime.InteropServices;
  2. using UnityEngine;
  3. using UnityEngine.InputSystem.Layouts;
  4. using UnityEngine.InputSystem.LowLevel;
  5. using UnityEngine.InputSystem.Utilities;
  6. namespace SC.XR.Unity.Simulation {
  7. /// <summary>
  8. /// Button indices for <see cref="XRSimulatedControllerState.buttons"/>
  9. /// </summary>
  10. public enum ControllerButton
  11. {
  12. /// <summary>
  13. /// The primary face button being pressed on a device, or sole button if only one is available.
  14. /// </summary>
  15. PrimaryButton,
  16. /// <summary>
  17. /// The primary face button being touched on a device.
  18. /// </summary>
  19. PrimaryTouch,
  20. /// <summary>
  21. /// The secondary face button being pressed on a device.
  22. /// </summary>
  23. SecondaryButton,
  24. /// <summary>
  25. /// The secondary face button being touched on a device.
  26. /// </summary>
  27. SecondaryTouch,
  28. /// <summary>
  29. /// A binary measure of whether the device is being gripped.
  30. /// </summary>
  31. GripButton,
  32. /// <summary>
  33. /// A binary measure of whether the index finger is activating the trigger.
  34. /// </summary>
  35. TriggerButton,
  36. /// <summary>
  37. /// Represents a menu button, used to pause, go back, or otherwise exit gameplay.
  38. /// </summary>
  39. MenuButton,
  40. /// <summary>
  41. /// Represents the primary 2D axis being clicked or otherwise depressed.
  42. /// </summary>
  43. Primary2DAxisClick,
  44. /// <summary>
  45. /// Represents the primary 2D axis being touched.
  46. /// </summary>
  47. Primary2DAxisTouch,
  48. /// <summary>
  49. /// Represents the secondary 2D axis being clicked or otherwise depressed.
  50. /// </summary>
  51. Secondary2DAxisClick,
  52. /// <summary>
  53. /// Represents the secondary 2D axis being touched.
  54. /// </summary>
  55. Secondary2DAxisTouch,
  56. /// <summary>
  57. /// Indicates whether the user is present and interacting with the device.
  58. /// </summary>
  59. UserPresence,
  60. }
  61. /// <summary>
  62. /// State for input device representing a simulated XR handed controller.
  63. /// </summary>
  64. [StructLayout(LayoutKind.Explicit, Size = 63)]
  65. public struct XRSimulatedControllerState : IInputStateTypeInfo
  66. {
  67. /// <summary>
  68. /// Memory format identifier for <see cref="XRSimulatedControllerState"/>.
  69. /// </summary>
  70. /// <seealso cref="InputStateBlock.format"/>
  71. public static FourCC formatId => new FourCC('X', 'R', 'S', 'C');
  72. /// <summary>
  73. /// See <a href="https://docs.unity3d.com/Packages/com.unity.inputsystem@1.2/api/UnityEngine.InputSystem.LowLevel.IInputStateTypeInfo.html">IInputStateTypeInfo</a>.format.
  74. /// </summary>
  75. public FourCC format => formatId;
  76. /// <summary>
  77. /// The primary touchpad or joystick on a device.
  78. /// </summary>
  79. [InputControl(usage = "Primary2DAxis", aliases = new[] { "thumbstick", "joystick" })]
  80. [FieldOffset(0)]
  81. public Vector2 primary2DAxis;
  82. /// <summary>
  83. /// A trigger-like control, pressed with the index finger.
  84. /// </summary>
  85. [InputControl(usage = "Trigger", layout = "Axis")]
  86. [FieldOffset(8)]
  87. public float trigger;
  88. /// <summary>
  89. /// Represents the user's grip on the controller.
  90. /// </summary>
  91. [InputControl(usage = "Grip", layout = "Axis")]
  92. [FieldOffset(12)]
  93. public float grip;
  94. /// <summary>
  95. /// A secondary touchpad or joystick on a device.
  96. /// </summary>
  97. [InputControl(usage = "Secondary2DAxis")]
  98. [FieldOffset(16)]
  99. public Vector2 secondary2DAxis;
  100. /// <summary>
  101. /// All the buttons on this device.
  102. /// </summary>
  103. [InputControl(name = nameof(XRSimulatedController.primaryButton), usage = "PrimaryButton", layout = "Button", bit = (uint)ControllerButton.PrimaryButton)]
  104. [InputControl(name = nameof(XRSimulatedController.primaryTouch), usage = "PrimaryTouch", layout = "Button", bit = (uint)ControllerButton.PrimaryTouch)]
  105. [InputControl(name = nameof(XRSimulatedController.secondaryButton), usage = "SecondaryButton", layout = "Button", bit = (uint)ControllerButton.SecondaryButton)]
  106. [InputControl(name = nameof(XRSimulatedController.secondaryTouch), usage = "SecondaryTouch", layout = "Button", bit = (uint)ControllerButton.SecondaryTouch)]
  107. [InputControl(name = nameof(XRSimulatedController.gripButton), usage = "GripButton", layout = "Button", bit = (uint)ControllerButton.GripButton, alias = "gripPressed")]
  108. [InputControl(name = nameof(XRSimulatedController.triggerButton), usage = "TriggerButton", layout = "Button", bit = (uint)ControllerButton.TriggerButton, alias = "triggerPressed")]
  109. [InputControl(name = nameof(XRSimulatedController.menuButton), usage = "MenuButton", layout = "Button", bit = (uint)ControllerButton.MenuButton)]
  110. [InputControl(name = nameof(XRSimulatedController.primary2DAxisClick), usage = "Primary2DAxisClick", layout = "Button", bit = (uint)ControllerButton.Primary2DAxisClick)]
  111. [InputControl(name = nameof(XRSimulatedController.primary2DAxisTouch), usage = "Primary2DAxisTouch", layout = "Button", bit = (uint)ControllerButton.Primary2DAxisTouch)]
  112. [InputControl(name = nameof(XRSimulatedController.secondary2DAxisClick), usage = "Secondary2DAxisClick", layout = "Button", bit = (uint)ControllerButton.Secondary2DAxisClick)]
  113. [InputControl(name = nameof(XRSimulatedController.secondary2DAxisTouch), usage = "Secondary2DAxisTouch", layout = "Button", bit = (uint)ControllerButton.Secondary2DAxisTouch)]
  114. [InputControl(name = nameof(XRSimulatedController.userPresence), usage = "UserPresence", layout = "Button", bit = (uint)ControllerButton.UserPresence)]
  115. [FieldOffset(24)]
  116. public ushort buttons;
  117. /// <summary>
  118. /// Value representing the current battery life of this device.
  119. /// </summary>
  120. [InputControl(usage = "BatteryLevel", layout = "Axis")]
  121. [FieldOffset(26)]
  122. public float batteryLevel;
  123. /// <summary>
  124. /// Represents the values being tracked for this device.
  125. /// </summary>
  126. [InputControl(usage = "TrackingState", layout = "Integer")]
  127. [FieldOffset(30)]
  128. public int trackingState;
  129. /// <summary>
  130. /// Informs to the developer whether the device is currently being tracked.
  131. /// </summary>
  132. [InputControl(usage = "IsTracked", layout = "Button")]
  133. [FieldOffset(34)]
  134. public bool isTracked;
  135. /// <summary>
  136. /// The position of the device.
  137. /// </summary>
  138. [InputControl(usage = "DevicePosition")]
  139. [FieldOffset(35)]
  140. public Vector3 devicePosition;
  141. /// <summary>
  142. /// The rotation of this device.
  143. /// </summary>
  144. [InputControl(usage = "DeviceRotation")]
  145. [FieldOffset(47)]
  146. public Quaternion deviceRotation;
  147. /// <summary>
  148. /// Set the button mask for the given <paramref name="button"/>.
  149. /// </summary>
  150. /// <param name="button">Button whose state to set.</param>
  151. /// <param name="state">Whether to set the bit on or off.</param>
  152. /// <returns>The same <see cref="XRSimulatedControllerState"/> with the change applied.</returns>
  153. /// <seealso cref="buttons"/>
  154. public XRSimulatedControllerState WithButton(ControllerButton button, bool state = true)
  155. {
  156. var bit = 1 << (int)button;
  157. if (state)
  158. buttons |= (ushort)bit;
  159. else
  160. buttons &= (ushort)~bit;
  161. return this;
  162. }
  163. /// <summary>
  164. /// See <see cref="MonoBehaviour"/>.
  165. /// </summary>
  166. public void Reset()
  167. {
  168. primary2DAxis = default;
  169. trigger = default;
  170. grip = default;
  171. secondary2DAxis = default;
  172. buttons = default;
  173. batteryLevel = default;
  174. trackingState = default;
  175. isTracked = default;
  176. devicePosition = default;
  177. deviceRotation = Quaternion.identity;
  178. }
  179. }
  180. }