No Description
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.

AndroidSupport.cs 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #if UNITY_EDITOR || UNITY_ANDROID
  2. using System.Linq;
  3. using UnityEngine.InputSystem.Layouts;
  4. using UnityEngine.InputSystem.LowLevel;
  5. using UnityEngine.InputSystem.Android.LowLevel;
  6. namespace UnityEngine.InputSystem.Android
  7. {
  8. /// <summary>
  9. /// Initializes custom android devices.
  10. /// You can use 'adb shell dumpsys input' from terminal to output information about all input devices.
  11. /// </summary>
  12. #if UNITY_DISABLE_DEFAULT_INPUT_PLUGIN_INITIALIZATION
  13. public
  14. #else
  15. internal
  16. #endif
  17. class AndroidSupport
  18. {
  19. internal const string kAndroidInterface = "Android";
  20. public static void Initialize()
  21. {
  22. InputSystem.RegisterLayout<AndroidGamepad>(
  23. matches: new InputDeviceMatcher()
  24. .WithInterface(kAndroidInterface)
  25. .WithDeviceClass("AndroidGameController"));
  26. InputSystem.RegisterLayout<AndroidJoystick>(
  27. matches: new InputDeviceMatcher()
  28. .WithInterface(kAndroidInterface)
  29. .WithDeviceClass("AndroidGameController"));
  30. InputSystem.RegisterLayout<DualShock4GamepadAndroid>();
  31. InputSystem.RegisterLayout<XboxOneGamepadAndroid>();
  32. ////TODO: capability matching does not yet support bitmasking so these remain handled by OnFindLayoutForDevice for now
  33. InputSystem.RegisterLayout<AndroidGamepadWithDpadAxes>();
  34. InputSystem.RegisterLayout<AndroidGamepadWithDpadButtons>();
  35. InputSystem.RegisterProcessor<AndroidCompensateDirectionProcessor>();
  36. InputSystem.RegisterProcessor<AndroidCompensateRotationProcessor>();
  37. // Add sensors
  38. InputSystem.RegisterLayout<AndroidAccelerometer>(
  39. matches: new InputDeviceMatcher()
  40. .WithInterface(kAndroidInterface)
  41. .WithDeviceClass("AndroidSensor")
  42. .WithCapability("sensorType", AndroidSensorType.Accelerometer));
  43. InputSystem.RegisterLayout<AndroidMagneticFieldSensor>(
  44. matches: new InputDeviceMatcher()
  45. .WithInterface(kAndroidInterface)
  46. .WithDeviceClass("AndroidSensor")
  47. .WithCapability("sensorType", AndroidSensorType.MagneticField));
  48. InputSystem.RegisterLayout<AndroidGyroscope>(
  49. matches: new InputDeviceMatcher()
  50. .WithInterface(kAndroidInterface)
  51. .WithDeviceClass("AndroidSensor")
  52. .WithCapability("sensorType", AndroidSensorType.Gyroscope));
  53. InputSystem.RegisterLayout<AndroidLightSensor>(
  54. matches: new InputDeviceMatcher()
  55. .WithInterface(kAndroidInterface)
  56. .WithDeviceClass("AndroidSensor")
  57. .WithCapability("sensorType", AndroidSensorType.Light));
  58. InputSystem.RegisterLayout<AndroidPressureSensor>(
  59. matches: new InputDeviceMatcher()
  60. .WithInterface(kAndroidInterface)
  61. .WithDeviceClass("AndroidSensor")
  62. .WithCapability("sensorType", AndroidSensorType.Pressure));
  63. InputSystem.RegisterLayout<AndroidProximity>(
  64. matches: new InputDeviceMatcher()
  65. .WithInterface(kAndroidInterface)
  66. .WithDeviceClass("AndroidSensor")
  67. .WithCapability("sensorType", AndroidSensorType.Proximity));
  68. InputSystem.RegisterLayout<AndroidGravitySensor>(
  69. matches: new InputDeviceMatcher()
  70. .WithInterface(kAndroidInterface)
  71. .WithDeviceClass("AndroidSensor")
  72. .WithCapability("sensorType", AndroidSensorType.Gravity));
  73. InputSystem.RegisterLayout<AndroidLinearAccelerationSensor>(
  74. matches: new InputDeviceMatcher()
  75. .WithInterface(kAndroidInterface)
  76. .WithDeviceClass("AndroidSensor")
  77. .WithCapability("sensorType", AndroidSensorType.LinearAcceleration));
  78. InputSystem.RegisterLayout<AndroidRotationVector>(
  79. matches: new InputDeviceMatcher()
  80. .WithInterface(kAndroidInterface)
  81. .WithDeviceClass("AndroidSensor")
  82. .WithCapability("sensorType", AndroidSensorType.RotationVector));
  83. InputSystem.RegisterLayout<AndroidRelativeHumidity>(
  84. matches: new InputDeviceMatcher()
  85. .WithInterface(kAndroidInterface)
  86. .WithDeviceClass("AndroidSensor")
  87. .WithCapability("sensorType", AndroidSensorType.RelativeHumidity));
  88. InputSystem.RegisterLayout<AndroidAmbientTemperature>(
  89. matches: new InputDeviceMatcher()
  90. .WithInterface(kAndroidInterface)
  91. .WithDeviceClass("AndroidSensor")
  92. .WithCapability("sensorType", AndroidSensorType.AmbientTemperature));
  93. InputSystem.RegisterLayout<AndroidGameRotationVector>(
  94. matches: new InputDeviceMatcher()
  95. .WithInterface(kAndroidInterface)
  96. .WithDeviceClass("AndroidSensor")
  97. .WithCapability("sensorType", AndroidSensorType.GameRotationVector));
  98. InputSystem.RegisterLayout<AndroidStepCounter>(
  99. matches: new InputDeviceMatcher()
  100. .WithInterface(kAndroidInterface)
  101. .WithDeviceClass("AndroidSensor")
  102. .WithCapability("sensorType", AndroidSensorType.StepCounter));
  103. InputSystem.onFindLayoutForDevice += OnFindLayoutForDevice;
  104. }
  105. internal static string OnFindLayoutForDevice(ref InputDeviceDescription description,
  106. string matchedLayout, InputDeviceExecuteCommandDelegate executeCommandDelegate)
  107. {
  108. // If we already have a matching layout, someone registered a better match.
  109. // We only want to act as a fallback.
  110. if (!string.IsNullOrEmpty(matchedLayout) && matchedLayout != "AndroidGamepad" && matchedLayout != "AndroidJoystick")
  111. return null;
  112. if (description.interfaceName != "Android" || string.IsNullOrEmpty(description.capabilities))
  113. return null;
  114. ////TODO: these should just be Controller and Sensor; the interface is already Android
  115. switch (description.deviceClass)
  116. {
  117. case "AndroidGameController":
  118. {
  119. var caps = AndroidDeviceCapabilities.FromJson(description.capabilities);
  120. // Note: Gamepads have both AndroidInputSource.Gamepad and AndroidInputSource.Joystick in input source, while
  121. // Joysticks don't have AndroidInputSource.Gamepad in their input source
  122. if ((caps.inputSources & AndroidInputSource.Gamepad) != AndroidInputSource.Gamepad)
  123. return "AndroidJoystick";
  124. if (caps.motionAxes == null)
  125. return "AndroidGamepadWithDpadButtons";
  126. // Vendor Ids, Product Ids can be found here http://www.linux-usb.org/usb.ids
  127. const int kVendorMicrosoft = 0x045e;
  128. const int kVendorSony = 0x054c;
  129. // Tested with controllers: PS4 DualShock; XboxOne; Nvidia Shield
  130. // Tested on devices: Shield console Android 9; Galaxy s9+ Android 10
  131. if (caps.motionAxes.Contains(AndroidAxis.Z) &&
  132. caps.motionAxes.Contains(AndroidAxis.Rz) &&
  133. caps.motionAxes.Contains(AndroidAxis.HatX) &&
  134. caps.motionAxes.Contains(AndroidAxis.HatY))
  135. {
  136. if (caps.vendorId == kVendorMicrosoft)
  137. return "XboxOneGamepadAndroid";
  138. if (caps.vendorId == kVendorSony)
  139. return "DualShock4GamepadAndroid";
  140. }
  141. // Fallback to generic gamepads
  142. if (caps.motionAxes.Contains(AndroidAxis.HatX) &&
  143. caps.motionAxes.Contains(AndroidAxis.HatY))
  144. return "AndroidGamepadWithDpadAxes";
  145. return "AndroidGamepadWithDpadButtons";
  146. }
  147. default:
  148. return null;
  149. }
  150. }
  151. }
  152. }
  153. #endif // UNITY_EDITOR || UNITY_ANDROID