暫無描述
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.

iOSStepCounter.cs 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #if UNITY_EDITOR || UNITY_IOS || PACKAGE_DOCS_GENERATION
  2. using System.Runtime.InteropServices;
  3. using AOT;
  4. using Unity.Collections.LowLevel.Unsafe;
  5. using UnityEngine.InputSystem.Layouts;
  6. using UnityEngine.InputSystem.LowLevel;
  7. using UnityEngine.InputSystem.Utilities;
  8. namespace UnityEngine.InputSystem.iOS.LowLevel
  9. {
  10. /// <summary>
  11. /// Describes the access for motion related features.
  12. /// </summary>
  13. /// <remarks>Enum values map values from CoreMotion.framework/Headers/CMAuthorization.h</remarks>
  14. public enum MotionAuthorizationStatus
  15. {
  16. /// <summary>
  17. /// The access status was not yet determined.
  18. /// </summary>
  19. NotDetermined = 0,
  20. /// <summary>
  21. /// Access was denied due system settings.
  22. /// </summary>
  23. Restricted,
  24. /// <summary>
  25. /// Access was denied by the user.
  26. /// </summary>
  27. Denied,
  28. /// <summary>
  29. /// Access was allowed by the user.
  30. /// </summary>
  31. Authorized
  32. }
  33. [StructLayout(LayoutKind.Sequential)]
  34. internal struct iOSStepCounterState : IInputStateTypeInfo
  35. {
  36. public static FourCC kFormat = new FourCC('I', 'S', 'C', 'S');
  37. public FourCC format => kFormat;
  38. [InputControl(name = "stepCounter", layout = "Integer")]
  39. public int stepCounter;
  40. }
  41. /// <summary>
  42. /// Step Counter (also known as pedometer) sensor for iOS.
  43. /// </summary>
  44. /// <remarks>
  45. /// You need to enable Motion Usage in Input System settings (see <see cref="InputSettings.iOSSettings.motionUsage"/>), to be allowed
  46. /// to access the sensor on the user's device.
  47. /// <example>
  48. /// <code>
  49. /// void Start()
  50. /// {
  51. /// InputSystem.EnableDevice(StepCounter.current);
  52. /// }
  53. ///
  54. /// void OnGUI()
  55. /// {
  56. /// GUILayout.Label(StepCounter.current.stepCounter.ReadValue().ToString());
  57. /// }
  58. /// </code>
  59. /// </example>
  60. /// </remarks>
  61. /// <seealso cref="InputSettings.iOSSettings.motionUsage"/>
  62. [InputControlLayout(stateType = typeof(iOSStepCounterState), variants = "StepCounter", hideInUI = true)]
  63. public class iOSStepCounter : StepCounter
  64. {
  65. private const int kCommandFailure = -1;
  66. private const int kCommandSuccess = 1;
  67. internal delegate void OnDataReceivedDelegate(int deviceId, int numberOfSteps);
  68. [StructLayout(LayoutKind.Sequential)]
  69. private struct iOSStepCounterCallbacks
  70. {
  71. internal OnDataReceivedDelegate onData;
  72. }
  73. [DllImport("__Internal")]
  74. private static extern int _iOSStepCounterEnable(int deviceId, ref iOSStepCounterCallbacks callbacks, int sizeOfCallbacks);
  75. [DllImport("__Internal")]
  76. private static extern int _iOSStepCounterDisable(int deviceId);
  77. [DllImport("__Internal")]
  78. private static extern int _iOSStepCounterIsEnabled(int deviceId);
  79. [DllImport("__Internal")]
  80. private static extern int _iOSStepCounterIsAvailable();
  81. [DllImport("__Internal")]
  82. private static extern int _iOSStepCounterGetAuthorizationStatus();
  83. [MonoPInvokeCallback(typeof(OnDataReceivedDelegate))]
  84. private static void OnDataReceived(int deviceId, int numberOfSteps)
  85. {
  86. var stepCounter = (iOSStepCounter)InputSystem.GetDeviceById(deviceId);
  87. InputSystem.QueueStateEvent(stepCounter, new iOSStepCounterState {stepCounter = numberOfSteps});
  88. }
  89. #if UNITY_EDITOR
  90. private bool m_Enabled = false;
  91. #endif
  92. protected override unsafe long ExecuteCommand(InputDeviceCommand* commandPtr)
  93. {
  94. var t = commandPtr->type;
  95. if (t == QueryEnabledStateCommand.Type)
  96. {
  97. #if UNITY_EDITOR
  98. ((QueryEnabledStateCommand*)commandPtr)->isEnabled = m_Enabled;
  99. #else
  100. ((QueryEnabledStateCommand*)commandPtr)->isEnabled = _iOSStepCounterIsEnabled(deviceId) != 0;
  101. #endif
  102. return kCommandSuccess;
  103. }
  104. if (t == EnableDeviceCommand.Type)
  105. {
  106. if (InputSystem.settings.iOS.motionUsage.enabled == false)
  107. {
  108. Debug.LogError("Please enable Motion Usage in Input Settings before using Step Counter.");
  109. return kCommandFailure;
  110. }
  111. #if UNITY_EDITOR
  112. m_Enabled = true;
  113. return kCommandSuccess;
  114. #else
  115. var callbacks = new iOSStepCounterCallbacks();
  116. callbacks.onData = OnDataReceived;
  117. return _iOSStepCounterEnable(deviceId, ref callbacks, Marshal.SizeOf(callbacks));
  118. #endif
  119. }
  120. if (t == DisableDeviceCommand.Type)
  121. {
  122. #if UNITY_EDITOR
  123. m_Enabled = false;
  124. return kCommandSuccess;
  125. #else
  126. return _iOSStepCounterDisable(deviceId);
  127. #endif
  128. }
  129. if (t == QueryCanRunInBackground.Type)
  130. {
  131. ((QueryCanRunInBackground*)commandPtr)->canRunInBackground = true;
  132. return kCommandSuccess;
  133. }
  134. if (t == RequestResetCommand.Type)
  135. {
  136. #if UNITY_EDITOR
  137. m_Enabled = false;
  138. #else
  139. _iOSStepCounterDisable(deviceId);
  140. #endif
  141. return kCommandSuccess;
  142. }
  143. return kCommandFailure;
  144. }
  145. /// <summary>
  146. /// Does the phone support the pedometer?
  147. /// </summary>
  148. public static bool IsAvailable()
  149. {
  150. #if UNITY_EDITOR
  151. return false;
  152. #else
  153. return _iOSStepCounterIsAvailable() != 0;
  154. #endif
  155. }
  156. /// <summary>
  157. /// Indicates whether the app is authorized to gather data for step counter sensor.
  158. /// </summary>
  159. public static MotionAuthorizationStatus AuthorizationStatus
  160. {
  161. get
  162. {
  163. #if UNITY_EDITOR
  164. return MotionAuthorizationStatus.NotDetermined;
  165. #else
  166. return (MotionAuthorizationStatus)_iOSStepCounterGetAuthorizationStatus();
  167. #endif
  168. }
  169. }
  170. }
  171. }
  172. #endif