CurvedUIHandSwitcher.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. using UnityEngine;
  2. using System.Collections;
  3. namespace CurvedUI {
  4. /// <summary>
  5. /// This script switches the hand controlling the UI when a click on the other controller's trigger is detected.
  6. /// This emulates the functionality seen in SteamVR overlay or Oculus Home.
  7. /// Works both for SteamVR and Oculus SDK.
  8. /// </summary>
  9. public class CurvedUIHandSwitcher : MonoBehaviour
  10. {
  11. #pragma warning disable 0649
  12. #pragma warning disable 414
  13. [SerializeField]
  14. GameObject LaserBeam;
  15. [SerializeField]
  16. [Tooltip("If true, when player clicks the trigger on the other hand, we'll instantly set it as UI controlling hand and move the pointer to it.")]
  17. bool autoSwitchHands = true;
  18. #pragma warning restore 414
  19. #pragma warning restore 0649
  20. #if CURVEDUI_OCULUSVR
  21. //variables
  22. OVRInput.Controller activeCont;
  23. bool initialized = false;
  24. void Update()
  25. {
  26. if (CurvedUIInputModule.ControlMethod != CurvedUIInputModule.CUIControlMethod.OCULUSVR) return;
  27. activeCont = OVRInput.GetActiveController();
  28. if (!initialized && CurvedUIInputModule.Instance.OculusTouchUsedControllerTransform != null)
  29. {
  30. //Launch Hand Switch. This will place the laser pointer in the current hand.
  31. SwitchHandTo(CurvedUIInputModule.Instance.UsedHand);
  32. initialized = true;
  33. }
  34. //for Oculus Go and GearVR, switch automatically if a different controller is connected.
  35. //This covers the case where User changes hand setting in Oculus Go menu and gets back to our app.
  36. if (activeCont == OVRInput.Controller.LTrackedRemote && CurvedUIInputModule.Instance.UsedHand != CurvedUIInputModule.Hand.Left)
  37. SwitchHandTo(CurvedUIInputModule.Hand.Left);
  38. else if (activeCont == OVRInput.Controller.RTrackedRemote && CurvedUIInputModule.Instance.UsedHand != CurvedUIInputModule.Hand.Right)
  39. SwitchHandTo(CurvedUIInputModule.Hand.Right);
  40. if(autoSwitchHands){
  41. //For Oculus Rift, we wait for the click before we change the pointer.
  42. if (IsButtonDownOnController(OVRInput.Controller.LTouch) && CurvedUIInputModule.Instance.UsedHand != CurvedUIInputModule.Hand.Left)
  43. {
  44. SwitchHandTo(CurvedUIInputModule.Hand.Left);
  45. }
  46. else if (IsButtonDownOnController(OVRInput.Controller.RTouch) && CurvedUIInputModule.Instance.UsedHand != CurvedUIInputModule.Hand.Right)
  47. {
  48. SwitchHandTo(CurvedUIInputModule.Hand.Right);
  49. }
  50. }
  51. }
  52. bool IsButtonDownOnController(OVRInput.Controller cont, OVRInput.Controller cont2 = OVRInput.Controller.None)
  53. {
  54. return OVRInput.GetDown(CurvedUIInputModule.Instance.OculusTouchInteractionButton, cont) || (cont2 != OVRInput.Controller.None && OVRInput.GetDown(CurvedUIInputModule.Instance.OculusTouchInteractionButton, cont2));
  55. }
  56. #elif CURVEDUI_STEAMVR_LEGACY
  57. void Start()
  58. {
  59. //connect to steamVR's OnModelLoaded events so we can update the pointer the moment controller is detected.
  60. CurvedUIInputModule.Right.ModelLoaded += OnModelLoaded;
  61. CurvedUIInputModule.Left.ModelLoaded += OnModelLoaded;
  62. }
  63. void OnModelLoaded(object sender)
  64. {
  65. SwitchHandTo(CurvedUIInputModule.Instance.UsedHand);
  66. }
  67. void Update()
  68. {
  69. if (CurvedUIInputModule.ControlMethod != CurvedUIInputModule.CUIControlMethod.STEAMVR_LEGACY) return;
  70. if(autoSwitchHands){
  71. if (CurvedUIInputModule.Right != null && CurvedUIInputModule.Right.IsTriggerDown && CurvedUIInputModule.Instance.UsedHand != CurvedUIInputModule.Hand.Right)
  72. {
  73. SwitchHandTo(CurvedUIInputModule.Hand.Right);
  74. }
  75. else if (CurvedUIInputModule.Left != null && CurvedUIInputModule.Left.IsTriggerDown && CurvedUIInputModule.Instance.UsedHand != CurvedUIInputModule.Hand.Left)
  76. {
  77. SwitchHandTo(CurvedUIInputModule.Hand.Left);
  78. }
  79. }
  80. }
  81. #elif CURVEDUI_STEAMVR_2
  82. void Start()
  83. {
  84. //initial setup in proper hand
  85. SwitchHandTo(CurvedUIInputModule.Instance.UsedHand);
  86. }
  87. void Update()
  88. {
  89. if (CurvedUIInputModule.ControlMethod != CurvedUIInputModule.CUIControlMethod.STEAMVR_2) return;
  90. //Switch hands during runtime when user clicks the action button on another controller
  91. if (autoSwitchHands && CurvedUIInputModule.Instance.SteamVRClickAction != null)
  92. {
  93. if (CurvedUIInputModule.Instance.SteamVRClickAction.GetState(Valve.VR.SteamVR_Input_Sources.RightHand) && CurvedUIInputModule.Instance.UsedHand != CurvedUIInputModule.Hand.Right){
  94. SwitchHandTo(CurvedUIInputModule.Hand.Right);
  95. }
  96. else if (CurvedUIInputModule.Instance.SteamVRClickAction.GetState(Valve.VR.SteamVR_Input_Sources.LeftHand) && CurvedUIInputModule.Instance.UsedHand != CurvedUIInputModule.Hand.Left ){
  97. SwitchHandTo(CurvedUIInputModule.Hand.Left);
  98. }
  99. }
  100. }
  101. #elif CURVEDUI_UNITY_XR
  102. void Start()
  103. {
  104. //initial setup in proper hand
  105. SwitchHandTo(CurvedUIInputModule.Instance.UsedHand);
  106. }
  107. void Update()
  108. {
  109. if (!autoSwitchHands || CurvedUIInputModule.ControlMethod != CurvedUIInputModule.CUIControlMethod.UNITY_XR) return;
  110. bool pressed = false;
  111. if (CurvedUIInputModule.Instance.RightXRController != null && CurvedUIInputModule.Instance.UsedHand != CurvedUIInputModule.Hand.Right)
  112. {
  113. //get pressed ui button state on right controller.
  114. CurvedUIInputModule.Instance.RightXRController.inputDevice.IsPressed(CurvedUIInputModule.Instance.RightXRController.uiPressUsage,
  115. out pressed, CurvedUIInputModule.Instance.RightXRController.axisToPressThreshold);
  116. if(pressed)
  117. SwitchHandTo(CurvedUIInputModule.Hand.Right);
  118. }
  119. if (CurvedUIInputModule.Instance.LeftXRController != null && CurvedUIInputModule.Instance.UsedHand != CurvedUIInputModule.Hand.Left)
  120. {
  121. //get pressed ui button state on left controller.
  122. CurvedUIInputModule.Instance.LeftXRController.inputDevice.IsPressed(CurvedUIInputModule.Instance.LeftXRController.uiPressUsage,
  123. out pressed, CurvedUIInputModule.Instance.LeftXRController.axisToPressThreshold);
  124. if(pressed)
  125. SwitchHandTo(CurvedUIInputModule.Hand.Left);
  126. }
  127. }
  128. #endif
  129. #region HELPER FUNCTIONS
  130. void SwitchHandTo(CurvedUIInputModule.Hand newHand)
  131. {
  132. CurvedUIInputModule.Instance.UsedHand = newHand;
  133. if (CurvedUIInputModule.Instance.ControllerTransform)
  134. {
  135. LaserBeam.transform.SetParent(CurvedUIInputModule.Instance.ControllerTransform);
  136. LaserBeam.transform.ResetTransform();
  137. LaserBeam.transform.LookAt(LaserBeam.transform.position + CurvedUIInputModule.Instance.ControllerPointingDirection);
  138. }
  139. else Debug.LogError("CURVEDUI: No Active controller that can be used as a parent of the pointer. Is the controller gameobject present on the scene and active?");
  140. }
  141. #endregion
  142. }
  143. }