summaryrefslogtreecommitdiff
path: root/Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/DynamicMoveProvider.cs
diff options
context:
space:
mode:
authorpryazha <pryadeiniv@mail.ru>2025-07-02 08:46:23 -0700
committerpryazha <pryadeiniv@mail.ru>2025-07-02 08:46:23 -0700
commit8263edd59284aba390aca011d25b79efecef4c48 (patch)
tree6346e2afaaabd32156601cafaf20d4ee813befaf /Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/DynamicMoveProvider.cs
Diffstat (limited to 'Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/DynamicMoveProvider.cs')
-rw-r--r--Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/DynamicMoveProvider.cs190
1 files changed, 190 insertions, 0 deletions
diff --git a/Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/DynamicMoveProvider.cs b/Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/DynamicMoveProvider.cs
new file mode 100644
index 0000000..033e5d4
--- /dev/null
+++ b/Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/DynamicMoveProvider.cs
@@ -0,0 +1,190 @@
+using Unity.XR.CoreUtils;
+using UnityEngine.Assertions;
+using UnityEngine.XR.Interaction.Toolkit.Locomotion.Movement;
+
+namespace UnityEngine.XR.Interaction.Toolkit.Samples.StarterAssets
+{
+ /// <summary>
+ /// A version of continuous movement that automatically controls the frame of reference that
+ /// determines the forward direction of movement based on user preference for each hand.
+ /// For example, can configure to use head relative movement for the left hand and controller relative movement for the right hand.
+ /// </summary>
+ public class DynamicMoveProvider : ContinuousMoveProvider
+ {
+ /// <summary>
+ /// Defines which transform the XR Origin's movement direction is relative to.
+ /// </summary>
+ /// <seealso cref="leftHandMovementDirection"/>
+ /// <seealso cref="rightHandMovementDirection"/>
+ public enum MovementDirection
+ {
+ /// <summary>
+ /// Use the forward direction of the head (camera) as the forward direction of the XR Origin's movement.
+ /// </summary>
+ HeadRelative,
+
+ /// <summary>
+ /// Use the forward direction of the hand (controller) as the forward direction of the XR Origin's movement.
+ /// </summary>
+ HandRelative,
+ }
+
+ [Space, Header("Movement Direction")]
+ [SerializeField]
+ [Tooltip("Directs the XR Origin's movement when using the head-relative mode. If not set, will automatically find and use the XR Origin Camera.")]
+ Transform m_HeadTransform;
+
+ /// <summary>
+ /// Directs the XR Origin's movement when using the head-relative mode. If not set, will automatically find and use the XR Origin Camera.
+ /// </summary>
+ public Transform headTransform
+ {
+ get => m_HeadTransform;
+ set => m_HeadTransform = value;
+ }
+
+ [SerializeField]
+ [Tooltip("Directs the XR Origin's movement when using the hand-relative mode with the left hand.")]
+ Transform m_LeftControllerTransform;
+
+ /// <summary>
+ /// Directs the XR Origin's movement when using the hand-relative mode with the left hand.
+ /// </summary>
+ public Transform leftControllerTransform
+ {
+ get => m_LeftControllerTransform;
+ set => m_LeftControllerTransform = value;
+ }
+
+ [SerializeField]
+ [Tooltip("Directs the XR Origin's movement when using the hand-relative mode with the right hand.")]
+ Transform m_RightControllerTransform;
+
+ public Transform rightControllerTransform
+ {
+ get => m_RightControllerTransform;
+ set => m_RightControllerTransform = value;
+ }
+
+ [SerializeField]
+ [Tooltip("Whether to use the specified head transform or left controller transform to direct the XR Origin's movement for the left hand.")]
+ MovementDirection m_LeftHandMovementDirection;
+
+ /// <summary>
+ /// Whether to use the specified head transform or controller transform to direct the XR Origin's movement for the left hand.
+ /// </summary>
+ /// <seealso cref="MovementDirection"/>
+ public MovementDirection leftHandMovementDirection
+ {
+ get => m_LeftHandMovementDirection;
+ set => m_LeftHandMovementDirection = value;
+ }
+
+ [SerializeField]
+ [Tooltip("Whether to use the specified head transform or right controller transform to direct the XR Origin's movement for the right hand.")]
+ MovementDirection m_RightHandMovementDirection;
+
+ /// <summary>
+ /// Whether to use the specified head transform or controller transform to direct the XR Origin's movement for the right hand.
+ /// </summary>
+ /// <seealso cref="MovementDirection"/>
+ public MovementDirection rightHandMovementDirection
+ {
+ get => m_RightHandMovementDirection;
+ set => m_RightHandMovementDirection = value;
+ }
+
+ Transform m_CombinedTransform;
+ Pose m_LeftMovementPose = Pose.identity;
+ Pose m_RightMovementPose = Pose.identity;
+
+ /// <inheritdoc />
+ protected override void Awake()
+ {
+ base.Awake();
+
+ m_CombinedTransform = new GameObject("[Dynamic Move Provider] Combined Forward Source").transform;
+ m_CombinedTransform.SetParent(transform, false);
+ m_CombinedTransform.localPosition = Vector3.zero;
+ m_CombinedTransform.localRotation = Quaternion.identity;
+
+ forwardSource = m_CombinedTransform;
+ }
+
+ /// <inheritdoc />
+ protected override Vector3 ComputeDesiredMove(Vector2 input)
+ {
+ // Don't need to do anything if the total input is zero.
+ // This is the same check as the base method.
+ if (input == Vector2.zero)
+ return base.ComputeDesiredMove(input);
+
+ // Initialize the Head Transform if necessary, getting the Camera from XR Origin
+ if (m_HeadTransform == null)
+ {
+ var xrOrigin = mediator.xrOrigin;
+ if (xrOrigin != null)
+ {
+ var xrCamera = xrOrigin.Camera;
+ if (xrCamera != null)
+ m_HeadTransform = xrCamera.transform;
+ }
+ }
+
+ // Get the forward source for the left hand input
+ switch (m_LeftHandMovementDirection)
+ {
+ case MovementDirection.HeadRelative:
+ if (m_HeadTransform != null)
+ m_LeftMovementPose = m_HeadTransform.GetWorldPose();
+
+ break;
+
+ case MovementDirection.HandRelative:
+ if (m_LeftControllerTransform != null)
+ m_LeftMovementPose = m_LeftControllerTransform.GetWorldPose();
+
+ break;
+
+ default:
+ Assert.IsTrue(false, $"Unhandled {nameof(MovementDirection)}={m_LeftHandMovementDirection}");
+ break;
+ }
+
+ // Get the forward source for the right hand input
+ switch (m_RightHandMovementDirection)
+ {
+ case MovementDirection.HeadRelative:
+ if (m_HeadTransform != null)
+ m_RightMovementPose = m_HeadTransform.GetWorldPose();
+
+ break;
+
+ case MovementDirection.HandRelative:
+ if (m_RightControllerTransform != null)
+ m_RightMovementPose = m_RightControllerTransform.GetWorldPose();
+
+ break;
+
+ default:
+ Assert.IsTrue(false, $"Unhandled {nameof(MovementDirection)}={m_RightHandMovementDirection}");
+ break;
+ }
+
+ // Combine the two poses into the forward source based on the magnitude of input
+ var leftHandValue = leftHandMoveInput.ReadValue();
+ var rightHandValue = rightHandMoveInput.ReadValue();
+
+ var totalSqrMagnitude = leftHandValue.sqrMagnitude + rightHandValue.sqrMagnitude;
+ var leftHandBlend = 0.5f;
+ if (totalSqrMagnitude > Mathf.Epsilon)
+ leftHandBlend = leftHandValue.sqrMagnitude / totalSqrMagnitude;
+
+ var combinedPosition = Vector3.Lerp(m_RightMovementPose.position, m_LeftMovementPose.position, leftHandBlend);
+ var combinedRotation = Quaternion.Slerp(m_RightMovementPose.rotation, m_LeftMovementPose.rotation, leftHandBlend);
+ m_CombinedTransform.SetPositionAndRotation(combinedPosition, combinedRotation);
+
+ return base.ComputeDesiredMove(input);
+ }
+ }
+}