ThreeDofEventInput.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. using UnityEngine;
  2. using System;
  3. using UnityEngine.EventSystems;
  4. using Rokid.UXR.Native;
  5. using Rokid.UXR.Module;
  6. using Rokid.UXR.Utility;
  7. namespace Rokid.UXR.Interaction
  8. {
  9. /// <summary>
  10. /// The 3dof event input class provides an external interface for 3dof interaction
  11. /// </summary>
  12. public class ThreeDofEventInput : MonoSingleton<ThreeDofEventInput>, IEventInput
  13. {
  14. public static event Action<Vector3> OnPhoneRayForward;
  15. public static event Action<Vector3> OnOriRot;
  16. public static event Action OnActiveThreeDofModule;
  17. public static event Action OnReleaseThreeDofModule;
  18. public static event Action OnThreeDofReset;
  19. public Transform Interactor { get; set; }
  20. private bool dragging = false;
  21. private float[] data = new float[4];
  22. private Quaternion rotation = Quaternion.identity;
  23. private bool initialize = false;
  24. private bool muteModuleActiveSound = false;
  25. private bool MuteModuleActiveSound { get { return muteModuleActiveSound; } set { muteModuleActiveSound = value; } }
  26. private HandType hand = HandType.None;
  27. public HandType HandType { get { return hand; } set { hand = value; } }
  28. private string persistKey = "uxr_threedofray_offset";
  29. private Vector3 cameraOffset = new Vector3(0, 0, 0);
  30. protected override void Awake()
  31. {
  32. NativeInterface.NativeAPI.OpenPhoneTracker();
  33. RKPointerLisener.OnPointerDragBegin += OnPointerDragBegin;
  34. RKPointerLisener.OnPointerDragEnd += OnPointerDragEnd;
  35. }
  36. private void Start()
  37. {
  38. if (SystemInfo.deviceModel.Equals("Rokid RG-stationPro"))
  39. {
  40. string value = NativeInterface.NativeAPI.GetPersistValue(persistKey);
  41. if (!string.IsNullOrEmpty(value))
  42. {
  43. float offsetY = Convert.ToSingle(value);
  44. RKLog.KeyInfo("====ThreeDofEventController==== GetOffsetY : " + offsetY);
  45. biasRotation = new Vector3(0, offsetY, 0);
  46. }
  47. cameraOffset = new Vector3(0, NativeInterface.NativeAPI.GetHeadPoseOffset().rotation.eulerAngles.y, 0);
  48. }
  49. }
  50. private void OnPointerDragBegin(PointerEventData data)
  51. {
  52. dragging = true;
  53. }
  54. private void OnPointerDragEnd(PointerEventData data)
  55. {
  56. dragging = false;
  57. }
  58. private void Update()
  59. {
  60. if (!initialize)
  61. return;
  62. if (InputModuleManager.Instance.GetThreeDofActive())
  63. {
  64. if (RKNativeInput.Instance.GetKeyDown(RKKeyEvent.KEY_RESET_RAY) || IsDoubleClick())
  65. {
  66. ResetImuAxisY();
  67. }
  68. }
  69. else if (Utils.IsAndroidPlatfrom())
  70. {
  71. if (Input.GetKeyUp(KeyCode.LeftArrow) || Input.GetKeyUp(KeyCode.RightArrow) || Input.GetKeyUp(KeyCode.UpArrow) || Input.GetKeyUp(KeyCode.DownArrow)
  72. || RKNativeInput.Instance.GetKeyUp(RKKeyEvent.KEY_LEFT) || RKNativeInput.Instance.GetKeyUp(RKKeyEvent.KEY_RIGHT) || RKNativeInput.Instance.GetKeyUp(RKKeyEvent.KEY_UP) || RKNativeInput.Instance.GetKeyUp(RKKeyEvent.KEY_DOWN)
  73. || Input.GetKeyUp(KeyCode.JoystickButton0) || Input.GetKeyDown(KeyCode.Joystick1Button3) || Input.GetKeyDown(KeyCode.JoystickButton3) || IsDoubleClick())
  74. {
  75. ActiveModule();
  76. ResetImuAxisY();
  77. }
  78. }
  79. #if UNITY_EDITOR
  80. if (Input.GetKeyDown(KeyCode.H))
  81. {
  82. ActiveModule();
  83. ResetImuAxisY();
  84. }
  85. #endif
  86. NativeInterface.NativeAPI.GetPhonePose(data);
  87. rotation[0] = data[0];
  88. rotation[1] = data[1];
  89. rotation[2] = -data[2];
  90. rotation[3] = data[3];
  91. OnData(rotation);
  92. }
  93. public void Initialize(Transform parent)
  94. {
  95. if (Interactor == null)
  96. {
  97. GameObject go = GameObject.Find("ThreeDofRayInteractor");
  98. if (go == null)
  99. {
  100. go = GameObject.Instantiate(Resources.Load<GameObject>("Prefabs/Interactor/ThreeDofRayInteractor"));
  101. }
  102. Interactor = go.transform;
  103. Interactor.name = "ThreeDofRayInteractor";
  104. Interactor.SetParent(transform);
  105. }
  106. Interactor.SetParent(transform);
  107. this.transform.SetParent(parent);
  108. initialize = true;
  109. }
  110. public void Release()
  111. {
  112. OnReleaseThreeDofModule?.Invoke();
  113. Destroy(this.gameObject);
  114. }
  115. public void ActiveModule()
  116. {
  117. ThreeDofEventInput.OnActiveThreeDofModule?.Invoke();
  118. RKVirtualController.Instance.Change(ControllerType.PHONE3DOF);
  119. EventSystem.current.pixelDragThreshold = 60;
  120. }
  121. // private void OnApplicationPause(bool pauseStatus)
  122. // {
  123. // if (pauseStatus)
  124. // {
  125. // NativeInterface.NativeAPI.ClosePhoneTracker();
  126. // }
  127. // else
  128. // {
  129. // NativeInterface.NativeAPI.OpenPhoneTracker();
  130. // }
  131. // }
  132. protected override void OnDestroy()
  133. {
  134. // SDK 不再关闭3dof 射线算法
  135. // NativeInterface.NativeAPI.ClosePhoneTracker();
  136. OnPhoneRayForward = null;
  137. RKPointerLisener.OnPointerDragBegin -= OnPointerDragBegin;
  138. RKPointerLisener.OnPointerDragEnd -= OnPointerDragEnd;
  139. initialize = false;
  140. }
  141. Vector3 biasRotation = Vector3.zero;
  142. Vector3 localRotation = Vector3.zero;
  143. Vector3 laserRotation = Vector3.zero;
  144. Quaternion phoneRotation = Quaternion.identity;
  145. void OnData(Quaternion q)
  146. {
  147. phoneRotation = q;
  148. laserRotation = q.eulerAngles;
  149. //调整射线和实际的偏差值,biasRotation用来重置摄像方向
  150. localRotation = laserRotation + biasRotation;
  151. Loom.QueueOnMainThread(() =>
  152. {
  153. OnPhoneRayForward?.Invoke(localRotation);
  154. OnOriRot?.Invoke(q.eulerAngles);
  155. });
  156. }
  157. public void ResetImuAxisY()
  158. {
  159. biasRotation = new Vector3(0, MainCameraCache.mainCamera.transform.rotation.eulerAngles.y - laserRotation.y, 0);
  160. RKLog.KeyInfo("====ThreeDofEventController==== 重置ImuAxisY : " + laserRotation);
  161. if (SystemInfo.deviceModel.Equals("Rokid RG-stationPro"))
  162. NativeInterface.NativeAPI.SetPersistValue(persistKey, biasRotation.y.ToString());
  163. // PlayModuleChangeAudio();
  164. OnThreeDofReset?.Invoke();
  165. }
  166. #region IsLongDown
  167. float longDownTime = 1.5f;
  168. float downTime = 0;
  169. bool triggerLongDown;
  170. private bool IsLongDown()
  171. {
  172. // Disalbe LongPress when enable Button Mouse & TouchPad mode
  173. if (InputModuleManager.Instance.GetButtonMouseActive() || InputModuleManager.Instance.GetTouchPadActive())
  174. {
  175. return false;
  176. }
  177. if (Input.GetKeyDown(KeyCode.JoystickButton0) || Input.GetMouseButtonDown(0))
  178. {
  179. triggerLongDown = false;
  180. downTime = 0;
  181. }
  182. if ((Input.GetKey(KeyCode.JoystickButton0) || Input.GetMouseButton(0)) && !triggerLongDown)
  183. {
  184. downTime += Time.deltaTime;
  185. if (downTime > longDownTime)
  186. {
  187. triggerLongDown = true;
  188. return true;
  189. }
  190. }
  191. return false;
  192. }
  193. #endregion
  194. #region IsDoubleClick
  195. float doubleClickTime = 2.0f;
  196. float clickTime = 0;
  197. int clickCount = 0;
  198. private bool IsDoubleClick()
  199. {
  200. clickTime += Time.deltaTime;
  201. if (Input.touchCount > 0)
  202. {
  203. Touch touch = Input.GetTouch(0);
  204. if (touch.phase == TouchPhase.Began)
  205. {
  206. clickCount++;
  207. }
  208. }
  209. if (Input.GetKeyDown(KeyCode.Joystick1Button3) || Input.GetKeyDown(KeyCode.JoystickButton3))
  210. {
  211. clickCount++;
  212. }
  213. if (clickTime < doubleClickTime)
  214. {
  215. if (clickCount == 2)
  216. {
  217. clickTime = 0;
  218. clickCount = 0;
  219. return true;
  220. }
  221. }
  222. else
  223. {
  224. clickCount = 0;
  225. clickTime = 0;
  226. }
  227. return false;
  228. }
  229. #endregion
  230. }
  231. }