summaryrefslogtreecommitdiff
path: root/Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/ClimbTeleportDestinationIndicator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/ClimbTeleportDestinationIndicator.cs')
-rw-r--r--Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/ClimbTeleportDestinationIndicator.cs143
1 files changed, 143 insertions, 0 deletions
diff --git a/Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/ClimbTeleportDestinationIndicator.cs b/Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/ClimbTeleportDestinationIndicator.cs
new file mode 100644
index 0000000..f64d156
--- /dev/null
+++ b/Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/Scripts/ClimbTeleportDestinationIndicator.cs
@@ -0,0 +1,143 @@
+using UnityEngine.XR.Interaction.Toolkit.Locomotion.Climbing;
+using UnityEngine.XR.Interaction.Toolkit.Locomotion.Teleportation;
+using UnityEngine.XR.Interaction.Toolkit.Utilities;
+
+namespace UnityEngine.XR.Interaction.Toolkit.Samples.StarterAssets
+{
+ /// <summary>
+ /// Affordance component used in conjunction with a <see cref="ClimbTeleportInteractor"/> to display an object
+ /// pointing at the target teleport destination while climbing.
+ /// </summary>
+ public class ClimbTeleportDestinationIndicator : MonoBehaviour
+ {
+ [SerializeField]
+ [Tooltip("The interactor that drives the display and placement of the pointer object.")]
+ ClimbTeleportInteractor m_ClimbTeleportInteractor;
+
+ /// <summary>
+ /// The interactor that drives the display and placement of the pointer object.
+ /// </summary>
+ public ClimbTeleportInteractor climbTeleportInteractor
+ {
+ get => m_ClimbTeleportInteractor;
+ set => m_ClimbTeleportInteractor = value;
+ }
+
+ [SerializeField]
+ [Tooltip("The prefab to spawn when a teleport destination is chosen. The instance will spawn next to the " +
+ "destination and point its forward vector at the destination and its up vector at the camera.")]
+ GameObject m_PointerPrefab;
+
+ /// <summary>
+ /// The prefab to spawn when a teleport destination is chosen. The instance will spawn next to the destination
+ /// and point its forward vector at the destination and its up vector at the camera.
+ /// </summary>
+ public GameObject pointerPrefab
+ {
+ get => m_PointerPrefab;
+ set => m_PointerPrefab = value;
+ }
+
+ [SerializeField]
+ [Tooltip("The distance from the destination at which the pointer object spawns.")]
+ float m_PointerDistance = 0.3f;
+
+ /// <summary>
+ /// The distance from the destination at which the pointer object spawns.
+ /// </summary>
+ public float pointerDistance
+ {
+ get => m_PointerDistance;
+ set => m_PointerDistance = value;
+ }
+
+ TeleportationMultiAnchorVolume m_ActiveTeleportVolume;
+ Transform m_PointerInstance;
+
+ /// <summary>
+ /// See <see cref="MonoBehaviour"/>.
+ /// </summary>
+ protected void OnEnable()
+ {
+ if (m_ClimbTeleportInteractor == null)
+ {
+ if (!ComponentLocatorUtility<ClimbTeleportInteractor>.TryFindComponent(out m_ClimbTeleportInteractor))
+ {
+ Debug.LogError($"Could not find {nameof(ClimbTeleportInteractor)} in scene.");
+ enabled = false;
+ return;
+ }
+ }
+
+ m_ClimbTeleportInteractor.hoverEntered.AddListener(OnInteractorHoverEntered);
+ m_ClimbTeleportInteractor.hoverExited.AddListener(OnInteractorHoverExited);
+ }
+
+ /// <summary>
+ /// See <see cref="MonoBehaviour"/>.
+ /// </summary>
+ protected void OnDisable()
+ {
+ HideIndicator();
+
+ if (m_ActiveTeleportVolume != null)
+ {
+ m_ActiveTeleportVolume.destinationAnchorChanged -= OnClimbTeleportDestinationAnchorChanged;
+ m_ActiveTeleportVolume = null;
+ }
+
+ if (m_ClimbTeleportInteractor != null)
+ {
+ m_ClimbTeleportInteractor.hoverEntered.RemoveListener(OnInteractorHoverEntered);
+ m_ClimbTeleportInteractor.hoverExited.RemoveListener(OnInteractorHoverExited);
+ }
+ }
+
+ void OnInteractorHoverEntered(HoverEnterEventArgs args)
+ {
+ if (m_ActiveTeleportVolume != null || !(args.interactableObject is TeleportationMultiAnchorVolume teleportVolume))
+ return;
+
+ m_ActiveTeleportVolume = teleportVolume;
+ if (m_ActiveTeleportVolume.destinationAnchor != null)
+ OnClimbTeleportDestinationAnchorChanged(m_ActiveTeleportVolume);
+
+ m_ActiveTeleportVolume.destinationAnchorChanged += OnClimbTeleportDestinationAnchorChanged;
+ }
+
+ void OnInteractorHoverExited(HoverExitEventArgs args)
+ {
+ if (!(args.interactableObject is TeleportationMultiAnchorVolume teleportVolume) || teleportVolume != m_ActiveTeleportVolume)
+ return;
+
+ HideIndicator();
+ m_ActiveTeleportVolume.destinationAnchorChanged -= OnClimbTeleportDestinationAnchorChanged;
+ m_ActiveTeleportVolume = null;
+ }
+
+ void OnClimbTeleportDestinationAnchorChanged(TeleportationMultiAnchorVolume teleportVolume)
+ {
+ HideIndicator();
+
+ var destinationAnchor = teleportVolume.destinationAnchor;
+ if (destinationAnchor == null)
+ return;
+
+ m_PointerInstance = Instantiate(m_PointerPrefab).transform;
+ var cameraTrans = teleportVolume.teleportationProvider.mediator.xrOrigin.Camera.transform;
+ var cameraPosition = cameraTrans.position;
+ var destinationPosition = destinationAnchor.position;
+ var destinationDirectionInScreenSpace = cameraTrans.InverseTransformDirection(destinationPosition - cameraPosition);
+ destinationDirectionInScreenSpace.z = 0f;
+ var pointerDirection = cameraTrans.TransformDirection(destinationDirectionInScreenSpace).normalized;
+ m_PointerInstance.position = destinationPosition - pointerDirection * m_PointerDistance;
+ m_PointerInstance.rotation = Quaternion.LookRotation(pointerDirection, -cameraTrans.forward);
+ }
+
+ void HideIndicator()
+ {
+ if (m_PointerInstance != null)
+ Destroy(m_PointerInstance.gameObject);
+ }
+ }
+}