TrackedPoseDriver.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. using System;
  2. using UnityEngine.InputSystem.LowLevel;
  3. namespace UnityEngine.InputSystem.XR
  4. {
  5. /// <summary>
  6. /// The TrackedPoseDriver component applies the current Pose value of a tracked device to the transform of the GameObject.
  7. /// TrackedPoseDriver can track multiple types of devices including XR HMDs, controllers, and remotes.
  8. /// </summary>
  9. [Serializable]
  10. [AddComponentMenu("XR/Tracked Pose Driver (New Input System)")]
  11. public class TrackedPoseDriver : MonoBehaviour
  12. {
  13. public enum TrackingType
  14. {
  15. RotationAndPosition,
  16. RotationOnly,
  17. PositionOnly
  18. }
  19. [SerializeField]
  20. TrackingType m_TrackingType;
  21. /// <summary>
  22. /// The tracking type being used by the tracked pose driver
  23. /// </summary>
  24. public TrackingType trackingType
  25. {
  26. get { return m_TrackingType; }
  27. set { m_TrackingType = value; }
  28. }
  29. public enum UpdateType
  30. {
  31. UpdateAndBeforeRender,
  32. Update,
  33. BeforeRender,
  34. }
  35. [SerializeField]
  36. UpdateType m_UpdateType = UpdateType.UpdateAndBeforeRender;
  37. /// <summary>
  38. /// The update type being used by the tracked pose driver
  39. /// </summary>
  40. public UpdateType updateType
  41. {
  42. get { return m_UpdateType; }
  43. set { m_UpdateType = value; }
  44. }
  45. [SerializeField]
  46. InputAction m_PositionAction;
  47. public InputAction positionAction
  48. {
  49. get { return m_PositionAction; }
  50. set
  51. {
  52. UnbindPosition();
  53. m_PositionAction = value;
  54. BindActions();
  55. }
  56. }
  57. [SerializeField]
  58. InputAction m_RotationAction;
  59. public InputAction rotationAction
  60. {
  61. get { return m_RotationAction; }
  62. set
  63. {
  64. UnbindRotation();
  65. m_RotationAction = value;
  66. BindActions();
  67. }
  68. }
  69. Vector3 m_CurrentPosition = Vector3.zero;
  70. Quaternion m_CurrentRotation = Quaternion.identity;
  71. bool m_RotationBound = false;
  72. bool m_PositionBound = false;
  73. void BindActions()
  74. {
  75. BindPosition();
  76. BindRotation();
  77. }
  78. void BindPosition()
  79. {
  80. if (!m_PositionBound && m_PositionAction != null)
  81. {
  82. m_PositionAction.Rename($"{gameObject.name} - TPD - Position");
  83. m_PositionAction.performed += OnPositionUpdate;
  84. m_PositionBound = true;
  85. m_PositionAction.Enable();
  86. }
  87. }
  88. void BindRotation()
  89. {
  90. if (!m_RotationBound && m_RotationAction != null)
  91. {
  92. m_RotationAction.Rename($"{gameObject.name} - TPD - Rotation");
  93. m_RotationAction.performed += OnRotationUpdate;
  94. m_RotationBound = true;
  95. m_RotationAction.Enable();
  96. }
  97. }
  98. void UnbindActions()
  99. {
  100. UnbindPosition();
  101. UnbindRotation();
  102. }
  103. void UnbindPosition()
  104. {
  105. if (m_PositionAction != null && m_PositionBound)
  106. {
  107. m_PositionAction.Disable();
  108. m_PositionAction.performed -= OnPositionUpdate;
  109. m_PositionBound = false;
  110. }
  111. }
  112. void UnbindRotation()
  113. {
  114. if (m_RotationAction != null && m_RotationBound)
  115. {
  116. m_RotationAction.Disable();
  117. m_RotationAction.performed -= OnRotationUpdate;
  118. m_RotationBound = false;
  119. }
  120. }
  121. void OnPositionUpdate(InputAction.CallbackContext context)
  122. {
  123. Debug.Assert(m_PositionBound);
  124. m_CurrentPosition = context.ReadValue<Vector3>();
  125. }
  126. void OnRotationUpdate(InputAction.CallbackContext context)
  127. {
  128. Debug.Assert(m_RotationBound);
  129. m_CurrentRotation = context.ReadValue<Quaternion>();
  130. }
  131. protected virtual void Awake()
  132. {
  133. #if UNITY_INPUT_SYSTEM_ENABLE_VR
  134. if (HasStereoCamera())
  135. {
  136. UnityEngine.XR.XRDevice.DisableAutoXRCameraTracking(GetComponent<Camera>(), true);
  137. }
  138. #endif
  139. }
  140. protected void OnEnable()
  141. {
  142. InputSystem.onAfterUpdate += UpdateCallback;
  143. BindActions();
  144. }
  145. void OnDisable()
  146. {
  147. UnbindActions();
  148. InputSystem.onAfterUpdate -= UpdateCallback;
  149. }
  150. protected virtual void OnDestroy()
  151. {
  152. #if UNITY_INPUT_SYSTEM_ENABLE_VR
  153. if (HasStereoCamera())
  154. {
  155. UnityEngine.XR.XRDevice.DisableAutoXRCameraTracking(GetComponent<Camera>(), false);
  156. }
  157. #endif
  158. }
  159. protected void UpdateCallback()
  160. {
  161. if (InputState.currentUpdateType == InputUpdateType.BeforeRender)
  162. OnBeforeRender();
  163. else
  164. OnUpdate();
  165. }
  166. protected virtual void OnUpdate()
  167. {
  168. if (m_UpdateType == UpdateType.Update ||
  169. m_UpdateType == UpdateType.UpdateAndBeforeRender)
  170. {
  171. PerformUpdate();
  172. }
  173. }
  174. protected virtual void OnBeforeRender()
  175. {
  176. if (m_UpdateType == UpdateType.BeforeRender ||
  177. m_UpdateType == UpdateType.UpdateAndBeforeRender)
  178. {
  179. PerformUpdate();
  180. }
  181. }
  182. protected virtual void SetLocalTransform(Vector3 newPosition, Quaternion newRotation)
  183. {
  184. if (m_TrackingType == TrackingType.RotationAndPosition ||
  185. m_TrackingType == TrackingType.RotationOnly)
  186. {
  187. transform.localRotation = newRotation;
  188. }
  189. if (m_TrackingType == TrackingType.RotationAndPosition ||
  190. m_TrackingType == TrackingType.PositionOnly)
  191. {
  192. transform.localPosition = newPosition;
  193. }
  194. }
  195. private bool HasStereoCamera()
  196. {
  197. var camera = GetComponent<Camera>();
  198. return camera != null && camera.stereoEnabled;
  199. }
  200. protected virtual void PerformUpdate()
  201. {
  202. SetLocalTransform(m_CurrentPosition, m_CurrentRotation);
  203. }
  204. }
  205. }