RotationAxisLockGrabTransformer.cs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. using UnityEngine.XR.Interaction.Toolkit.Interactables;
  2. using UnityEngine.XR.Interaction.Toolkit.Transformers;
  3. namespace UnityEngine.XR.Interaction.Toolkit.Samples.StarterAssets
  4. {
  5. /// <summary>
  6. /// An XR grab transformer that allows for the locking of specific rotation axes. When an object is grabbed and manipulated,
  7. /// this class ensures that rotations are only applied to the specified axes, preserving the initial rotation for the others.
  8. /// </summary>
  9. public class RotationAxisLockGrabTransformer : XRBaseGrabTransformer
  10. {
  11. [SerializeField]
  12. [Tooltip("Defines which rotation axes are allowed when an object is grabbed. Axes not selected will maintain their initial rotation.")]
  13. XRGeneralGrabTransformer.ManipulationAxes m_PermittedRotationAxis = XRGeneralGrabTransformer.ManipulationAxes.All;
  14. /// <inheritdoc />
  15. protected override RegistrationMode registrationMode => RegistrationMode.SingleAndMultiple;
  16. Vector3 m_InitialEulerRotation;
  17. /// <inheritdoc />
  18. public override void OnLink(XRGrabInteractable grabInteractable)
  19. {
  20. base.OnLink(grabInteractable);
  21. m_InitialEulerRotation = grabInteractable.transform.rotation.eulerAngles;
  22. }
  23. /// <inheritdoc />
  24. public override void Process(XRGrabInteractable grabInteractable, XRInteractionUpdateOrder.UpdatePhase updatePhase, ref Pose targetPose, ref Vector3 localScale)
  25. {
  26. Vector3 newRotationEuler = targetPose.rotation.eulerAngles;
  27. if ((m_PermittedRotationAxis & XRGeneralGrabTransformer.ManipulationAxes.X) == 0)
  28. newRotationEuler.x = m_InitialEulerRotation.x;
  29. if ((m_PermittedRotationAxis & XRGeneralGrabTransformer.ManipulationAxes.Y) == 0)
  30. newRotationEuler.y = m_InitialEulerRotation.y;
  31. if ((m_PermittedRotationAxis & XRGeneralGrabTransformer.ManipulationAxes.Z) == 0)
  32. newRotationEuler.z = m_InitialEulerRotation.z;
  33. targetPose.rotation = Quaternion.Euler(newRotationEuler);
  34. }
  35. }
  36. }