diff options
author | pryazha <pryadeiniv@mail.ru> | 2025-07-02 08:46:23 -0700 |
---|---|---|
committer | pryazha <pryadeiniv@mail.ru> | 2025-07-02 08:46:23 -0700 |
commit | 8263edd59284aba390aca011d25b79efecef4c48 (patch) | |
tree | 6346e2afaaabd32156601cafaf20d4ee813befaf /Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/DemoSceneAssets/Scripts/MultiAnchorTeleportReticle.cs |
Diffstat (limited to 'Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/DemoSceneAssets/Scripts/MultiAnchorTeleportReticle.cs')
-rw-r--r-- | Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/DemoSceneAssets/Scripts/MultiAnchorTeleportReticle.cs | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/DemoSceneAssets/Scripts/MultiAnchorTeleportReticle.cs b/Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/DemoSceneAssets/Scripts/MultiAnchorTeleportReticle.cs new file mode 100644 index 0000000..86643c7 --- /dev/null +++ b/Assets/Samples/XR Interaction Toolkit/3.1.2/Starter Assets/DemoSceneAssets/Scripts/MultiAnchorTeleportReticle.cs @@ -0,0 +1,164 @@ +using UnityEngine.UI; +using UnityEngine.XR.Interaction.Toolkit.Interactables; +using UnityEngine.XR.Interaction.Toolkit.Interactables.Visuals; +using UnityEngine.XR.Interaction.Toolkit.Interactors.Visuals; +using UnityEngine.XR.Interaction.Toolkit.Locomotion.Teleportation; + +namespace UnityEngine.XR.Interaction.Toolkit.Samples.StarterAssets +{ + /// <summary> + /// A custom reticle for a <see cref="TeleportationMultiAnchorVolume"/> that displays its progress towards evaluating + /// a destination anchor and an indicator pointing in the direction of the destination anchor. + /// </summary> + public class MultiAnchorTeleportReticle : MonoBehaviour, IXRInteractableCustomReticle + { + [SerializeField] + [Tooltip("Filled image that displays the progress towards evaluating a destination anchor.")] + Image m_TimerProgressFilledImage; + + /// <summary> + /// <see cref="Image.Type.Filled"/> image that displays the progress towards evaluating a destination anchor. + /// </summary> + public Image timerProgressFilledImage + { + get => m_TimerProgressFilledImage; + set => m_TimerProgressFilledImage = value; + } + + [SerializeField] + [Tooltip("Object that is rotated about its Z axis to point at the destination anchor.")] + GameObject m_DestinationIndicator; + + /// <summary> + /// Object that is rotated about its Z axis to point at the destination anchor. + /// </summary> + public GameObject destinationIndicator + { + get => m_DestinationIndicator; + set => m_DestinationIndicator = value; + } + + [SerializeField] + [Tooltip("Object that is rotated about its Z axis to point at the potential destination while still evaluating.")] + GameObject m_PotentialDestinationIndicator; + + /// <summary> + /// Object that is rotated about its Z axis to point at the potential destination while still evaluating. + /// </summary> + public GameObject potentialDestinationIndicator + { + get => m_PotentialDestinationIndicator; + set => m_PotentialDestinationIndicator = value; + } + + [SerializeField] + [Tooltip("The amount of time, in seconds, between updates to the indicator pointing at the potential destination.")] + float m_PotentialIndicatorUpdateFrequency = 0.1f; + + /// <summary> + /// The amount of time, in seconds, between updates to the indicator pointing at the potential destination. + /// </summary> + public float potentialIndicatorUpdateFrequency + { + get => m_PotentialIndicatorUpdateFrequency; + set => m_PotentialIndicatorUpdateFrequency = value; + } + + TeleportationMultiAnchorVolume m_AnchorVolume; + float m_LastPotentialIndicatorUpdateTime; + + /// <inheritdoc/> + public void OnReticleAttached(XRBaseInteractable interactable, IXRCustomReticleProvider reticleProvider) + { + m_AnchorVolume = interactable as TeleportationMultiAnchorVolume; + m_PotentialDestinationIndicator.SetActive(false); + m_DestinationIndicator.SetActive(false); + m_TimerProgressFilledImage.type = Image.Type.Filled; + m_TimerProgressFilledImage.fillAmount = 0f; + if (m_AnchorVolume == null) + return; + + m_AnchorVolume.destinationAnchorChanged += OnDestinationAnchorChanged; + } + + /// <inheritdoc/> + public void OnReticleDetaching() + { + if (m_AnchorVolume == null) + return; + + m_AnchorVolume.destinationAnchorChanged -= OnDestinationAnchorChanged; + m_AnchorVolume = null; + } + + /// <summary> + /// See <see cref="MonoBehaviour"/>. + /// </summary> + protected void Update() + { + if (m_AnchorVolume == null) + return; + + var destinationAnchor = m_AnchorVolume.destinationAnchor; + if (destinationAnchor != null) + { + PointAtTarget(m_DestinationIndicator.transform, destinationAnchor.position); + return; + } + + m_TimerProgressFilledImage.fillAmount = m_AnchorVolume.destinationEvaluationProgress; + if (Time.time - m_LastPotentialIndicatorUpdateTime >= m_PotentialIndicatorUpdateFrequency) + UpdatePotentialDestinationIndicator(); + } + + void UpdatePotentialDestinationIndicator() + { + m_LastPotentialIndicatorUpdateTime = Time.time; + if (!m_AnchorVolume.destinationEvaluationSettings.Value.pollForDestinationChange) + { + m_PotentialDestinationIndicator.SetActive(false); + return; + } + + var potentialDestinationIndex = m_AnchorVolume.destinationEvaluationFilter.GetDestinationAnchorIndex(m_AnchorVolume); + var anchors = m_AnchorVolume.anchorTransforms; + if (potentialDestinationIndex < 0 || potentialDestinationIndex >= anchors.Count) + { + m_PotentialDestinationIndicator.SetActive(false); + return; + } + + var potentialDestination = anchors[potentialDestinationIndex]; + if (potentialDestination == null) + { + m_PotentialDestinationIndicator.SetActive(false); + return; + } + + m_PotentialDestinationIndicator.SetActive(true); + PointAtTarget(m_PotentialDestinationIndicator.transform, potentialDestination.position); + } + + void OnDestinationAnchorChanged(TeleportationMultiAnchorVolume anchorVolume) + { + var destinationAnchor = anchorVolume.destinationAnchor; + if (destinationAnchor != null) + { + m_TimerProgressFilledImage.fillAmount = 1f; + m_PotentialDestinationIndicator.SetActive(false); + m_DestinationIndicator.SetActive(true); + PointAtTarget(m_DestinationIndicator.transform, destinationAnchor.position); + } + else + { + m_TimerProgressFilledImage.fillAmount = 0f; + m_DestinationIndicator.SetActive(false); + } + } + + static void PointAtTarget(Transform indicatorTransform, Vector3 targetPosition) + { + indicatorTransform.rotation = Quaternion.LookRotation(indicatorTransform.forward, targetPosition - indicatorTransform.position); + } + } +} |