HeadCursorVisual.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. using UnityEngine;
  2. using Rokid.UXR.Utility;
  3. using UnityEngine.EventSystems;
  4. namespace Rokid.UXR.Interaction
  5. {
  6. public class HeadCursorVisual : AutoInjectBehaviour, IHeadHandDriver
  7. {
  8. [SerializeField]
  9. private RayInteractor rayInteractor;
  10. [Tooltip("光标Size")]
  11. [SerializeField]
  12. private float cursorAngularSize = 100;
  13. [Autowrited("Cursor_Focus")]
  14. private Transform focusCursor;
  15. [Autowrited("Cursor_Press")]
  16. private Transform pressCursor;
  17. [Autowrited("Cursor_Drag")]
  18. private Transform dragCursor;
  19. [Autowrited("Cursor_Disable")]
  20. private Transform disableCursor;
  21. private bool handPress;
  22. private bool triggerCanDraggable = false;
  23. private bool trackSuccess = false;
  24. private bool leftHandLost = true;
  25. private bool rightHandLost = true;
  26. private float scaleRelease = 1.5f;
  27. private float scalePress = 1.0f;
  28. private float startSmoothPinchDistance = 0.06f;
  29. private void Start()
  30. {
  31. rayInteractor.WhenPostprocessed += UpdateVisual;
  32. rayInteractor.WhenStateChanged += UpdateVisualState;
  33. GesEventInput.OnTrackedFailed += OnTrackedFailed;
  34. GesEventInput.OnTrackedSuccess += OnTrackedSuccess;
  35. }
  36. private void OnTrackedFailed(HandType hand)
  37. {
  38. if (hand == HandType.LeftHand)
  39. {
  40. leftHandLost = true;
  41. }
  42. if (hand == HandType.RightHand)
  43. {
  44. rightHandLost = true;
  45. }
  46. }
  47. private void OnTrackedSuccess(HandType hand)
  48. {
  49. if (hand == HandType.LeftHand)
  50. {
  51. leftHandLost = false;
  52. }
  53. if (hand == HandType.RightHand)
  54. {
  55. rightHandLost = false;
  56. }
  57. }
  58. private void OnDestroy()
  59. {
  60. rayInteractor.WhenPostprocessed -= UpdateVisual;
  61. rayInteractor.WhenStateChanged -= UpdateVisualState;
  62. GesEventInput.OnTrackedFailed -= OnTrackedFailed;
  63. GesEventInput.OnTrackedSuccess -= OnTrackedSuccess;
  64. }
  65. private void OnEnable()
  66. {
  67. RKPointerLisener.OnGraphicPointerEnter += OnPointerEnter;
  68. RKPointerLisener.OnGraphicPointerExit += OnPointerExit;
  69. RKPointerLisener.OnGraphicPointerHover += OnPointerHover;
  70. }
  71. private void OnDisable()
  72. {
  73. RKPointerLisener.OnGraphicPointerEnter -= OnPointerEnter;
  74. RKPointerLisener.OnGraphicPointerExit -= OnPointerExit;
  75. RKPointerLisener.OnGraphicPointerHover -= OnPointerHover;
  76. IsInHover = false;
  77. }
  78. private Vector3 ComputeScaleWithAngularScale(Vector3 targetPoint)
  79. {
  80. float cursorDistance = Vector3.Distance(MainCameraCache.mainCamera.transform.position, targetPoint);
  81. float desiredScale = Utils.ScaleFromAngularSizeAndDistance(cursorAngularSize, cursorDistance);
  82. return Vector3.one * desiredScale;
  83. }
  84. private void UpdateVisual()
  85. {
  86. if (rayInteractor.State == InteractorState.Disabled)
  87. {
  88. gameObject.SetActive(false);
  89. return;
  90. }
  91. gameObject.SetActive(true);
  92. Vector3 EndPosition;
  93. Vector3 EndNormal;
  94. if (IsInHover && HoverNormal != Vector3.zero && HoverPosition != Vector3.zero)
  95. {
  96. EndPosition = HoverPosition;
  97. EndNormal = HoverNormal;
  98. }
  99. else
  100. {
  101. EndPosition = rayInteractor.End;
  102. EndNormal = rayInteractor.Forward;
  103. }
  104. if (rayInteractor.State == InteractorState.Select || rayInteractor.State == InteractorState.Hover)
  105. {
  106. this.transform.position = EndPosition - EndNormal * 0.001f;
  107. if (rayInteractor.CollisionInfo != null)
  108. {
  109. Quaternion rotation = Quaternion.FromToRotation(Vector3.forward, -rayInteractor.CollisionInfo.Value.Normal);
  110. this.transform.eulerAngles = new Vector3(rotation.eulerAngles.x, rotation.eulerAngles.y, 0);
  111. }
  112. else
  113. {
  114. this.transform.rotation = Quaternion.LookRotation(EndPosition - MainCameraCache.mainCamera.transform.position, Vector3.up);
  115. }
  116. this.transform.localScale = ComputeScaleWithAngularScale(EndPosition);
  117. if (triggerCanDraggable == false && CanDrag())
  118. {
  119. triggerCanDraggable = true;
  120. }
  121. }
  122. else if (rayInteractor.State == InteractorState.Normal)
  123. {
  124. this.transform.rotation = Quaternion.LookRotation(EndPosition - MainCameraCache.mainCamera.transform.position, Vector3.up);
  125. this.transform.localScale = ComputeScaleWithAngularScale(EndPosition);
  126. this.transform.position = EndPosition - EndNormal * 0.001f;
  127. triggerCanDraggable = false;
  128. }
  129. if (!leftHandLost || !rightHandLost)
  130. {
  131. disableCursor.gameObject.SetActive(false);
  132. if (triggerCanDraggable)
  133. {
  134. focusCursor.gameObject.SetActive(false);
  135. pressCursor.gameObject.SetActive(false);
  136. dragCursor.gameObject.SetActive(true);
  137. }
  138. else
  139. {
  140. bool press = rayInteractor.State == InteractorState.Select;
  141. focusCursor.gameObject.SetActive(!press);
  142. pressCursor.gameObject.SetActive(press);
  143. dragCursor.gameObject.SetActive(false);
  144. }
  145. }
  146. else
  147. {
  148. disableCursor.gameObject.SetActive(true);
  149. focusCursor.gameObject.SetActive(false);
  150. pressCursor.gameObject.SetActive(false);
  151. dragCursor.gameObject.SetActive(false);
  152. }
  153. }
  154. private bool CanDrag()
  155. {
  156. IDraggable[] draggables = rayInteractor.Interactable?.GetComponentsInChildren<IDraggable>();
  157. if (draggables != null && draggables.Length > 0)
  158. {
  159. return true;
  160. }
  161. return false;
  162. }
  163. private void UpdateVisualState(InteractorStateChangeArgs args) => UpdateVisual();
  164. #region ForCursorHoverPose
  165. private bool IsInHover;
  166. private Vector3 HoverPosition;
  167. private Vector3 HoverNormal;
  168. private void OnPointerEnter(PointerEventData eventData)
  169. {
  170. if (eventData.pointerCurrentRaycast.gameObject != null)
  171. {
  172. IsInHover = true;
  173. HoverPosition = Vector3.zero;
  174. HoverNormal = Vector3.zero;
  175. }
  176. }
  177. private void OnPointerExit(PointerEventData eventData)
  178. {
  179. IsInHover = false;
  180. HoverPosition = Vector3.zero;
  181. HoverNormal = Vector3.zero;
  182. }
  183. private void OnPointerHover(PointerEventData eventData)
  184. {
  185. HoverPosition = eventData.pointerCurrentRaycast.worldPosition;
  186. HoverNormal = eventData.pointerCurrentRaycast.worldNormal;
  187. }
  188. public void OnChangeHoldHandType(HandType hand)
  189. {
  190. }
  191. public void OnHandPress(HandType hand)
  192. {
  193. handPress = true;
  194. }
  195. public void OnHandRelease()
  196. {
  197. handPress = false;
  198. }
  199. public void OnBeforeChangeHoldHandType(HandType hand)
  200. {
  201. }
  202. #endregion
  203. }
  204. }