WebGLGamepad.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #if UNITY_WEBGL || UNITY_EDITOR
  2. using System;
  3. using System.ComponentModel;
  4. using UnityEngine.InputSystem.Layouts;
  5. using UnityEngine.InputSystem.LowLevel;
  6. using UnityEngine.InputSystem.WebGL.LowLevel;
  7. using UnityEngine.InputSystem.Utilities;
  8. namespace UnityEngine.InputSystem.WebGL.LowLevel
  9. {
  10. internal unsafe struct WebGLGamepadState : IInputStateTypeInfo
  11. {
  12. public const int NumAxes = 4;
  13. public const int NumButtons = 16;
  14. private const int ButtonOffset = NumAxes * 4;
  15. // Stick default format is already two floats so all we need to do is move the sticks and
  16. // put inverts on Y.
  17. [InputControl(name = "leftStick", offset = 0)]
  18. [InputControl(name = "rightStick", offset = 8)]
  19. [InputControl(name = "leftStick/y", parameters = "invert")]
  20. [InputControl(name = "rightStick/y", parameters = "invert")]
  21. // All the buttons we need to bump from single bits to full floats and reset bit offsets.
  22. [InputControl(name = "buttonSouth", offset = ButtonOffset + 0 * 4, bit = 0, format = "FLT")]
  23. [InputControl(name = "buttonEast", offset = ButtonOffset + 1 * 4, bit = 0, format = "FLT")]
  24. [InputControl(name = "buttonWest", offset = ButtonOffset + 2 * 4, bit = 0, format = "FLT")]
  25. [InputControl(name = "buttonNorth", offset = ButtonOffset + 3 * 4, bit = 0, format = "FLT")]
  26. [InputControl(name = "leftShoulder", offset = ButtonOffset + 4 * 4, bit = 0, format = "FLT")]
  27. [InputControl(name = "rightShoulder", offset = ButtonOffset + 5 * 4, bit = 0, format = "FLT")]
  28. [InputControl(name = "leftTrigger", offset = ButtonOffset + 6 * 4, bit = 0, format = "FLT")]
  29. [InputControl(name = "rightTrigger", offset = ButtonOffset + 7 * 4, bit = 0, format = "FLT")]
  30. [InputControl(name = "select", offset = ButtonOffset + 8 * 4, bit = 0, format = "FLT")]
  31. [InputControl(name = "start", offset = ButtonOffset + 9 * 4, bit = 0, format = "FLT")]
  32. [InputControl(name = "leftStickPress", offset = ButtonOffset + 10 * 4, bit = 0, format = "FLT")]
  33. [InputControl(name = "rightStickPress", offset = ButtonOffset + 11 * 4, bit = 0, format = "FLT")]
  34. [InputControl(name = "dpad", offset = ButtonOffset + 12 * 4, bit = 0, sizeInBits = 4 * 4 * 8)]
  35. [InputControl(name = "dpad/up", offset = 0, bit = 0, format = "FLT")]
  36. [InputControl(name = "dpad/down", offset = 4, bit = 0, format = "FLT")]
  37. [InputControl(name = "dpad/left", offset = 8, bit = 0, format = "FLT")]
  38. [InputControl(name = "dpad/right", offset = 12, bit = 0, format = "FLT")]
  39. public fixed float values[NumButtons + NumAxes];
  40. public float leftTrigger
  41. {
  42. get => GetValue(NumAxes + 6);
  43. set => SetValue(NumAxes + 6, value);
  44. }
  45. public float rightTrigger
  46. {
  47. get => GetValue(NumAxes + 7);
  48. set => SetValue(NumAxes + 7, value);
  49. }
  50. public Vector2 leftStick
  51. {
  52. get => new Vector2(GetValue(0), GetValue(1));
  53. set
  54. {
  55. SetValue(0, value.x);
  56. SetValue(1, value.y);
  57. }
  58. }
  59. public Vector2 rightStick
  60. {
  61. get => new Vector2(GetValue(2), GetValue(3));
  62. set
  63. {
  64. SetValue(2, value.x);
  65. SetValue(3, value.y);
  66. }
  67. }
  68. public FourCC format
  69. {
  70. get { return new FourCC('H', 'T', 'M', 'L'); }
  71. }
  72. public WebGLGamepadState WithButton(GamepadButton button, float value = 1)
  73. {
  74. int index;
  75. switch (button)
  76. {
  77. case GamepadButton.South: index = 0; break;
  78. case GamepadButton.East: index = 1; break;
  79. case GamepadButton.West: index = 2; break;
  80. case GamepadButton.North: index = 3; break;
  81. case GamepadButton.LeftShoulder: index = 4; break;
  82. case GamepadButton.RightShoulder: index = 5; break;
  83. case GamepadButton.Select: index = 8; break;
  84. case GamepadButton.Start: index = 9; break;
  85. case GamepadButton.LeftStick: index = 10; break;
  86. case GamepadButton.RightStick: index = 11; break;
  87. case GamepadButton.DpadUp: index = 12; break;
  88. case GamepadButton.DpadDown: index = 13; break;
  89. case GamepadButton.DpadLeft: index = 14; break;
  90. case GamepadButton.DpadRight: index = 15; break;
  91. default:
  92. throw new InvalidEnumArgumentException(nameof(button), (int)button, typeof(GamepadButton));
  93. }
  94. SetValue(NumAxes + index, value);
  95. return this;
  96. }
  97. private float GetValue(int index)
  98. {
  99. fixed(float* valuePtr = values)
  100. return valuePtr[index];
  101. }
  102. private void SetValue(int index, float value)
  103. {
  104. fixed(float* valuePtr = values)
  105. valuePtr[index] = value;
  106. }
  107. }
  108. [Serializable]
  109. internal struct WebGLDeviceCapabilities
  110. {
  111. public int numAxes;
  112. public int numButtons;
  113. public string mapping;
  114. public string ToJson()
  115. {
  116. return JsonUtility.ToJson(this);
  117. }
  118. public static WebGLDeviceCapabilities FromJson(string json)
  119. {
  120. if (string.IsNullOrEmpty(json))
  121. throw new ArgumentNullException(nameof(json));
  122. return JsonUtility.FromJson<WebGLDeviceCapabilities>(json);
  123. }
  124. }
  125. }
  126. namespace UnityEngine.InputSystem.WebGL
  127. {
  128. /// <summary>
  129. /// Gamepad on WebGL that uses the "standard" mapping.
  130. /// </summary>
  131. ///
  132. /// <seealso href="https://w3c.github.io/gamepad/#remapping"/>
  133. [InputControlLayout(stateType = typeof(WebGLGamepadState), displayName = "WebGL Gamepad (\"standard\" mapping)")]
  134. [Scripting.Preserve]
  135. public class WebGLGamepad : Gamepad
  136. {
  137. }
  138. }
  139. #endif // UNITY_WEBGL || UNITY_EDITOR