From c86b0e95bdc3bb5b40f60fe9b2571a1b55b0402c Mon Sep 17 00:00:00 2001 From: Adam Mollis <36461279+AMollis@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:32:54 -0700 Subject: [PATCH] [MRKT3] Making custom reticles a bit easier in MRTK3. (#11758) ## Overview The intent of this change is to make attaching a custom reticle easier in MRTK3. The custom reticle is now attached to the base reticle's root transform, removing the need for the custom reticle to position itself. Also, reverting changes made to `RecticleMagnetism`. With this change, `RecticleMagnetisms` once again uses an interface for setting progress, instead of requiring a `RingReticle` component. Also, instead of using the old `IVariableReticle`, `RecticleMagnetisms` is now using `IVariableProgressReticle` to better indicate the propose of the interface. I also rename the newer `IVariableReticle` to `IRecticleVisual` to better indicate its purpose. This change is in response to https://github.com/microsoft/MixedRealityToolkit-Unity/discussions/11751 ## Changes - Fixes: https://github.com/microsoft/MixedRealityToolkit-Unity/discussions/11751 --- ...{IVariableReticle.cs => IReticleVisual.cs} | 21 +++-- .../Interactors/IReticleVisual.cs.meta | 11 +++ .../Interactors/IVariableProgressReticle.cs | 42 +++++++++ ....meta => IVariableProgressReticle.cs.meta} | 0 .../Interactors/IVariableSelectInteractor.cs | 4 +- .../Prefabs/MRTK LeftHand Controller.prefab | 7 +- .../SpatialMouseInteractorCursorVisual.cs | 10 +- .../InteractorVisuals/BaseReticleVisual.cs | 94 +++++++++++++------ .../MRTKPokeReticleVisual.cs | 11 ++- .../InteractorVisuals/MRTKRayReticleVisual.cs | 30 +++--- .../InteractorVisuals/ReticleMagnetism.cs | 10 +- .../InteractorVisuals/RingReticle.cs | 52 ++++++---- .../Visuals/SpatialManipulationReticle.cs | 4 +- 13 files changed, 209 insertions(+), 87 deletions(-) rename com.microsoft.mrtk.core/Interactors/{IVariableReticle.cs => IReticleVisual.cs} (55%) create mode 100644 com.microsoft.mrtk.core/Interactors/IReticleVisual.cs.meta create mode 100644 com.microsoft.mrtk.core/Interactors/IVariableProgressReticle.cs rename com.microsoft.mrtk.core/Interactors/{IVariableReticle.cs.meta => IVariableProgressReticle.cs.meta} (100%) diff --git a/com.microsoft.mrtk.core/Interactors/IVariableReticle.cs b/com.microsoft.mrtk.core/Interactors/IReticleVisual.cs similarity index 55% rename from com.microsoft.mrtk.core/Interactors/IVariableReticle.cs rename to com.microsoft.mrtk.core/Interactors/IReticleVisual.cs index df0fdfdf14b..2f48dce7fb1 100644 --- a/com.microsoft.mrtk.core/Interactors/IVariableReticle.cs +++ b/com.microsoft.mrtk.core/Interactors/IReticleVisual.cs @@ -7,21 +7,26 @@ namespace Microsoft.MixedReality.Toolkit { /// - /// A reticle that implements some visual effect controllable by a single float value. + /// A customizable visual component of a reticle. /// - public interface IVariableReticle + /// + /// Implementations of can receive updates to the base reticle's + /// position and normal every frame, if the base reticle is shown. For more information on how + /// set a custom reticle, see . + /// c + public interface IReticleVisual { /// - /// Updates visuals as needed for the variable reticle. + /// Updates the visual parts of the reticle. /// - public void UpdateVisuals(VariableReticleUpdateArgs args); + public void UpdateVisual(ReticleVisualUpdateArgs args); } /// - /// A struct to store the arguments passed to UpdateVisuals + /// A struct to store the arguments passed to /// including the interactor associated with the reticle, and reticle position and normal. /// - public struct VariableReticleUpdateArgs + public struct ReticleVisualUpdateArgs { /// /// XRRayInteractor that the reticle serves as a visual for. @@ -39,9 +44,9 @@ public struct VariableReticleUpdateArgs public Vector3 ReticleNormal; /// - /// Initializes a struct. + /// Initializes a struct. /// - public VariableReticleUpdateArgs(IXRInteractor interactor, Vector3 reticlePosition, Vector3 reticleNormal) + public ReticleVisualUpdateArgs(IXRInteractor interactor, Vector3 reticlePosition, Vector3 reticleNormal) { Interactor = interactor; ReticlePosition = reticlePosition; diff --git a/com.microsoft.mrtk.core/Interactors/IReticleVisual.cs.meta b/com.microsoft.mrtk.core/Interactors/IReticleVisual.cs.meta new file mode 100644 index 00000000000..519b914151a --- /dev/null +++ b/com.microsoft.mrtk.core/Interactors/IReticleVisual.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 137841acaf4307541a62bdeeb10baa8f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.microsoft.mrtk.core/Interactors/IVariableProgressReticle.cs b/com.microsoft.mrtk.core/Interactors/IVariableProgressReticle.cs new file mode 100644 index 00000000000..7c97f18510c --- /dev/null +++ b/com.microsoft.mrtk.core/Interactors/IVariableProgressReticle.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.MixedReality.Toolkit +{ + /// + /// A reticle that is capable of displaying interaction progress. + /// + /// + /// This may be used to show selection progress and touch proximity. + /// + /// + public interface IVariableProgressReticle + { + /// + /// Update the progress of the visual. + /// + public void UpdateProgress(VariableProgressReticleUpdateArgs args); + } + + /// + /// A struct to store the arguments passed to . + /// + public struct VariableProgressReticleUpdateArgs + { + /// + /// A value from 0 to 1 indicating interaction progress of an. + /// + /// + /// This may be used to show selection progress and touch proximity. + /// + public float Progress; + + /// + /// Initializes a struct. + /// + public VariableProgressReticleUpdateArgs(float progress) + { + Progress = progress; + } + } +} diff --git a/com.microsoft.mrtk.core/Interactors/IVariableReticle.cs.meta b/com.microsoft.mrtk.core/Interactors/IVariableProgressReticle.cs.meta similarity index 100% rename from com.microsoft.mrtk.core/Interactors/IVariableReticle.cs.meta rename to com.microsoft.mrtk.core/Interactors/IVariableProgressReticle.cs.meta diff --git a/com.microsoft.mrtk.core/Interactors/IVariableSelectInteractor.cs b/com.microsoft.mrtk.core/Interactors/IVariableSelectInteractor.cs index 47cf1180cec..64d0784bf9e 100644 --- a/com.microsoft.mrtk.core/Interactors/IVariableSelectInteractor.cs +++ b/com.microsoft.mrtk.core/Interactors/IVariableSelectInteractor.cs @@ -16,8 +16,8 @@ public interface IVariableSelectInteractor : IXRSelectInteractor, IXRHoverIntera /// amount of "selection" that this interactor is performing. /// /// - /// For gaze-pinch interactors, this is the pinch progress; - /// for motion controllers, this is the analog trigger press amount. + /// For gaze-pinch interactors, this is the pinch progress. + /// For motion controllers, this is the analog trigger press amount. /// float SelectProgress { get; } } diff --git a/com.microsoft.mrtk.input/Assets/Prefabs/MRTK LeftHand Controller.prefab b/com.microsoft.mrtk.input/Assets/Prefabs/MRTK LeftHand Controller.prefab index 34ec31e2b0b..51b87e5a704 100644 --- a/com.microsoft.mrtk.input/Assets/Prefabs/MRTK LeftHand Controller.prefab +++ b/com.microsoft.mrtk.input/Assets/Prefabs/MRTK LeftHand Controller.prefab @@ -312,8 +312,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 70ec73306ca3ef44a95bbb45b96f0538, type: 3} m_Name: m_EditorClassIdentifier: - baseReticle: {fileID: 8992338914735331379} reticleRoot: {fileID: 3988544559415115452} + baseReticle: {fileID: 8992338914735331379} rayInteractor: {fileID: 2940030942784507886} proximityLight: {fileID: 4448665028262160152} visibilitySettings: 0 @@ -1100,6 +1100,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 518e5c0e6d2c664478d85d0ceae60c36, type: 3} m_Name: m_EditorClassIdentifier: + reticleRoot: {fileID: 0} baseReticle: {fileID: 8086910922498750391} pokeInteractor: {fileID: 1948193616346090107} proximityLight: {fileID: 3552666654439622812} @@ -1846,6 +1847,10 @@ PrefabInstance: propertyPath: fadeEnabled value: 1 objectReference: {fileID: 0} + - target: {fileID: 7949002557058872435, guid: fddee8b412d753e40a02681891de4a7b, type: 3} + propertyPath: displaySelectionProgress + value: 0 + objectReference: {fileID: 0} - target: {fileID: 9095796513279534737, guid: fddee8b412d753e40a02681891de4a7b, type: 3} propertyPath: m_IsActive value: 1 diff --git a/com.microsoft.mrtk.input/Experimental/SpatialMouse/Interactor/SpatialMouseInteractorCursorVisual.cs b/com.microsoft.mrtk.input/Experimental/SpatialMouse/Interactor/SpatialMouseInteractorCursorVisual.cs index 5e2908439d4..572f23a9213 100644 --- a/com.microsoft.mrtk.input/Experimental/SpatialMouse/Interactor/SpatialMouseInteractorCursorVisual.cs +++ b/com.microsoft.mrtk.input/Experimental/SpatialMouse/Interactor/SpatialMouseInteractorCursorVisual.cs @@ -35,8 +35,10 @@ public class SpatialMouseInteractorCursorVisual : BaseReticleVisual /// /// A Unity event function that is called when the script component has been enabled. /// - protected virtual void OnEnable() + protected override void OnEnable() { + base.OnEnable(); + mouseInteractor.selectEntered.AddListener(LocateTargetHitPoint); Application.onBeforeRender += OnBeforeRenderCursor; @@ -121,10 +123,10 @@ private void OnBeforeRenderCursor() Reticle.transform.position = reticlePosition; Reticle.transform.forward = reticleNormal; - // If the reticle is an IVariableSelectReticle, have the reticle update based on selectedness - if (VariableReticle != null) + // If the reticle is an IReticleVisual, have the reticle update based on selectedness + if (Visual != null) { - VariableReticle.UpdateVisuals(new VariableReticleUpdateArgs(mouseInteractor, reticlePosition, reticleNormal)); + Visual.UpdateVisual(new ReticleVisualUpdateArgs(mouseInteractor, reticlePosition, reticleNormal)); } if (Reticle.activeSelf == false) diff --git a/com.microsoft.mrtk.input/Interactors/InteractorVisuals/BaseReticleVisual.cs b/com.microsoft.mrtk.input/Interactors/InteractorVisuals/BaseReticleVisual.cs index 42bf93da352..fb3e80c39dc 100644 --- a/com.microsoft.mrtk.input/Interactors/InteractorVisuals/BaseReticleVisual.cs +++ b/com.microsoft.mrtk.input/Interactors/InteractorVisuals/BaseReticleVisual.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using System; using UnityEngine; using UnityEngine.XR.Interaction.Toolkit; @@ -16,48 +17,86 @@ namespace Microsoft.MixedReality.Toolkit.Input [DisallowMultipleComponent] public class BaseReticleVisual : MonoBehaviour, IXRCustomReticleProvider { + [SerializeField] + [Tooltip("The root of the reticle visuals")] + private Transform reticleRoot; + + /// + /// The root of the reticle visuals. + /// + /// + /// This transform hold both the base and custom reticle. + /// + protected Transform ReticleRoot => reticleRoot; + [SerializeField] [Tooltip("The reticle model to use when the interactable doesn't specify a custom one.")] private GameObject baseReticle; + /// + /// The reticle model to use when the interactable doesn't specify a custom one. + /// + protected GameObject BaseReticle => baseReticle; + /// /// Staging area for custom reticles that interactors can attach to show unique visuals. /// - protected GameObject customReticle; + protected GameObject CustomReticle + { + get; + private set; + } /// /// Is there a custom reticle currently attached to this interactor? /// - protected bool customReticleAttached; + protected bool CustomReticleAttached + { + get; + private set; + } /// /// The current reticle that the interactor is using. /// - public GameObject Reticle => customReticleAttached ? customReticle : baseReticle; + public GameObject Reticle => CustomReticleAttached ? CustomReticle : baseReticle; - private IVariableReticle variableReticle; + private IReticleVisual visual; /// - /// Cached variable reticle reference. + /// Cached reference to the component on . /// - protected IVariableReticle VariableReticle + protected IReticleVisual Visual { get { - if (variableReticle == null) + if (visual == null) { - variableReticle = Reticle.GetComponent(); + visual = Reticle.GetComponent(); } - return variableReticle; + return visual; + } + } + + /// + /// A Unity event function that is called when the script component has been enabled. + /// + protected virtual void OnEnable() + { + // If no reticle root is specified, use the interactor's transform. + if (reticleRoot == null) + { + reticleRoot = transform; } } + #region IXRCustomReticleProvider /// public bool AttachCustomReticle(GameObject reticleInstance) { - if (!customReticleAttached) + if (!CustomReticleAttached) { if (baseReticle != null) { @@ -66,27 +105,27 @@ public bool AttachCustomReticle(GameObject reticleInstance) } else { - if (customReticle != null) + if (CustomReticle != null) { - customReticle.SetActive(false); + CustomReticle.SetActive(false); } } - customReticle = reticleInstance; - if (customReticle != null) + CustomReticle = reticleInstance; + if (CustomReticle != null) { - customReticle.SetActive(true); + CustomReticle.SetActive(true); - // Ensure the custom reticle is parented under this gameobject - customReticle.transform.parent = transform; - customReticle.transform.localPosition = Vector3.zero; - customReticle.transform.localRotation = Quaternion.identity; + // Ensure the custom reticle is parented under this game object + CustomReticle.transform.parent = reticleRoot; + CustomReticle.transform.localPosition = Vector3.zero; + CustomReticle.transform.localRotation = Quaternion.identity; } - customReticleAttached = true; + CustomReticleAttached = true; - // Make sure that the variable reticle now refers to the correct reticle - variableReticle = Reticle.GetComponent(); + // Clear old references to the old Reticle components. + visual = null; return true; } @@ -94,9 +133,9 @@ public bool AttachCustomReticle(GameObject reticleInstance) /// public bool RemoveCustomReticle() { - if (customReticle != null) + if (CustomReticle != null) { - customReticle.SetActive(false); + CustomReticle.SetActive(false); } // If we have a standard reticle, re-enable that one. @@ -105,9 +144,10 @@ public bool RemoveCustomReticle() baseReticle.SetActive(true); } - customReticle = null; - customReticleAttached = false; - variableReticle = null; + CustomReticle = null; + CustomReticleAttached = false; + visual = null; + return false; } diff --git a/com.microsoft.mrtk.input/Interactors/InteractorVisuals/MRTKPokeReticleVisual.cs b/com.microsoft.mrtk.input/Interactors/InteractorVisuals/MRTKPokeReticleVisual.cs index e6fdb2e8bf0..e6b9084162c 100644 --- a/com.microsoft.mrtk.input/Interactors/InteractorVisuals/MRTKPokeReticleVisual.cs +++ b/com.microsoft.mrtk.input/Interactors/InteractorVisuals/MRTKPokeReticleVisual.cs @@ -24,15 +24,16 @@ public class MRTKPokeReticleVisual : BaseReticleVisual /// /// A Unity event function that is called when the script component has been enabled. /// - protected void OnEnable() + protected override void OnEnable() { + base.OnEnable(); Application.onBeforeRender += UpdateReticle; } /// /// A Unity event function that is called when the script component has been disabled. /// - protected void OnDisable() + protected virtual void OnDisable() { UpdateReticle(); Application.onBeforeRender -= UpdateReticle; @@ -62,6 +63,12 @@ private void UpdateReticle() proximityLight.SetActive(Reticle.activeSelf); } } + + // If the reticle is an IReticleVisual, have the reticle update based on selectedness + if (Visual != null) + { + Visual.UpdateVisual(new ReticleVisualUpdateArgs(pokeInteractor, Reticle.transform.position, Reticle.transform.forward)); + } } } } diff --git a/com.microsoft.mrtk.input/Interactors/InteractorVisuals/MRTKRayReticleVisual.cs b/com.microsoft.mrtk.input/Interactors/InteractorVisuals/MRTKRayReticleVisual.cs index a9eab2a6f70..ffe3cc39c27 100644 --- a/com.microsoft.mrtk.input/Interactors/InteractorVisuals/MRTKRayReticleVisual.cs +++ b/com.microsoft.mrtk.input/Interactors/InteractorVisuals/MRTKRayReticleVisual.cs @@ -16,10 +16,6 @@ namespace Microsoft.MixedReality.Toolkit.Input [DefaultExecutionOrder(XRInteractionUpdateOrder.k_BeforeRenderLineVisual)] public class MRTKRayReticleVisual : BaseReticleVisual { - [SerializeField] - [Tooltip("The root of the reticle visuals")] - private Transform reticleRoot; - [SerializeField] [Tooltip("The interactor which this visual represents.")] private XRRayInteractor rayInteractor; @@ -48,23 +44,19 @@ public ReticleVisibilitySettings VisibilitySettings /// /// A Unity event function that is called when the script component has been enabled. /// - private void OnEnable() + protected override void OnEnable() { + base.OnEnable(); + rayInteractor.selectEntered.AddListener(LocateTargetHitPoint); Application.onBeforeRender += UpdateReticle; - - // If no custom reticle root is specified, just use the interactor's transform. - if (reticleRoot == null) - { - reticleRoot = transform; - } UpdateReticle(); } /// /// A Unity event function that is called when the script component has been disabled. /// - private void OnDisable() + protected virtual void OnDisable() { rayInteractor.selectEntered.RemoveListener(LocateTargetHitPoint); Application.onBeforeRender -= UpdateReticle; @@ -75,7 +67,7 @@ private void OnDisable() /// /// A Unity event function that is called every frame, if this object is enabled. /// - private void LateUpdate() + protected virtual void LateUpdate() { // if running in batch mode the onBeforeRender event doesn't fire so // we need to update the reticle here @@ -112,22 +104,22 @@ private void UpdateReticle() } // If we have a reticle, set its position and rotation. - if (reticleRoot != null) + if (ReticleRoot != null) { if (reticleNormal != Vector3.zero) { - reticleRoot.transform.SetPositionAndRotation(reticlePosition, Quaternion.LookRotation(reticleNormal, Vector3.up)); + ReticleRoot.transform.SetPositionAndRotation(reticlePosition, Quaternion.LookRotation(reticleNormal, Vector3.up)); } else { - reticleRoot.transform.position = reticlePosition; + ReticleRoot.transform.position = reticlePosition; } } - // If the reticle is an IVariableSelectReticle, have the reticle update based on selectedness - if (VariableReticle != null) + // If the reticle is an IReticleVisual, have the reticle update based on selectedness + if (Visual != null) { - VariableReticle.UpdateVisuals(new VariableReticleUpdateArgs(rayInteractor, reticlePosition, reticleNormal)); + Visual.UpdateVisual(new ReticleVisualUpdateArgs(rayInteractor, reticlePosition, reticleNormal)); } } else diff --git a/com.microsoft.mrtk.input/Interactors/InteractorVisuals/ReticleMagnetism.cs b/com.microsoft.mrtk.input/Interactors/InteractorVisuals/ReticleMagnetism.cs index de9f3835ace..af812b8b164 100644 --- a/com.microsoft.mrtk.input/Interactors/InteractorVisuals/ReticleMagnetism.cs +++ b/com.microsoft.mrtk.input/Interactors/InteractorVisuals/ReticleMagnetism.cs @@ -94,7 +94,7 @@ public ProximityDetector Detector public float RotationSmoothing { get => rotationSmoothing; set => rotationSmoothing = value; } // Reference to the variable visuals. - private IVariableReticle variableReticleVisuals; + private IVariableProgressReticle variableProgressVisual; // The smoothed magnetization point, usually the nearest point on the nearest collider. // Not necessarily the same as the current reticle rotation! @@ -126,7 +126,7 @@ public ProximityDetector Detector private void Awake() { // Optional. - variableReticleVisuals = GetComponentInChildren(includeInactive: true); + variableProgressVisual = GetComponentInChildren(includeInactive: true); pokeInteractor = gameObject.GetComponentInParent(includeInactive: true); } @@ -243,10 +243,10 @@ private void Update() } } - // If we're using variable reticle visuals, update the visuals with the progress/proximity. - if (variableReticleVisuals != null && variableReticleVisuals is RingReticle ringReticleVisuals) + // If we're using variable progress visuals, update the visuals with the progress/proximity. + if (variableProgressVisual != null) { - ringReticleVisuals.UpdateVisuals(1.0f - progressFraction); + variableProgressVisual.UpdateProgress(new VariableProgressReticleUpdateArgs(1.0f - progressFraction)); } } diff --git a/com.microsoft.mrtk.input/Interactors/InteractorVisuals/RingReticle.cs b/com.microsoft.mrtk.input/Interactors/InteractorVisuals/RingReticle.cs index bc1fb57a524..6455fe67a1d 100644 --- a/com.microsoft.mrtk.input/Interactors/InteractorVisuals/RingReticle.cs +++ b/com.microsoft.mrtk.input/Interactors/InteractorVisuals/RingReticle.cs @@ -10,14 +10,14 @@ namespace Microsoft.MixedReality.Toolkit.Input /// A ring-like reticle that expands/contracts. /// [AddComponentMenu("MRTK/Input/Ring Reticle")] - internal class RingReticle : MonoBehaviour, IVariableReticle + internal class RingReticle : MonoBehaviour, IReticleVisual, IVariableProgressReticle { [SerializeField] - [Tooltip("The amount of smoothing to apply to the reticle's grow/shrink effect.")] + [Tooltip("The amount of smoothing to apply to the reticle's grow and shrink effect.")] private float animationSmoothing = 0.000001f; /// - /// The amount of smoothing to apply to the reticle's grow/shrink effect. + /// The amount of smoothing to apply to the reticle's grow and shrink effect. /// public float AnimationSmoothing { @@ -26,11 +26,11 @@ public float AnimationSmoothing } [SerializeField] - [Tooltip("Should the ring fade when the value is small?")] + [Tooltip("Turn on or off the ring fade when the value is small.")] private bool fadeEnabled = false; /// - /// Should the ring fade when the value is small? + /// Turn on or off the ring fade when the value is small. /// public bool FadeEnabled { @@ -42,6 +42,19 @@ public bool FadeEnabled } } + [SerializeField] + [Tooltip("Turn on or off the handling of selection progress.")] + private bool displaySelectionProgress = true; + + /// + /// Turn on or off the handling of selection progress. + /// + public bool DisplaySelectionProgress + { + get => displaySelectionProgress; + set => displaySelectionProgress = value; + } + private MaterialPropertyBlock propertyBlock; private float smoothedValue = 0.0f; @@ -77,30 +90,35 @@ protected void OnEnable() } /// - public void UpdateVisuals(float value) + public void UpdateProgress(VariableProgressReticleUpdateArgs args) { - if (reticleRenderer == null || Mathf.Approximately(value, smoothedValue)) { return; } - - smoothedValue = Smoothing.SmoothTo(smoothedValue, value, animationSmoothing, Time.deltaTime); - SetReticleShrink(smoothedValue); + UpdateReticleProgressVisual(args.Progress); } - /// Extracts values from VariableReticleArgs to call UpdateVisuals - public void UpdateVisuals(VariableReticleUpdateArgs args) + /// + public void UpdateVisual(ReticleVisualUpdateArgs args) { - if (args.Interactor is XRRayInteractor rayInteractor) + if (displaySelectionProgress) { - if (rayInteractor is IVariableSelectInteractor variableSelectInteractor) + if (args.Interactor is IVariableSelectInteractor variableSelectInteractor) { - UpdateVisuals(variableSelectInteractor.SelectProgress); + UpdateReticleProgressVisual(variableSelectInteractor.SelectProgress); } - else + else if (args.Interactor is IXRSelectInteractor selectInteractor) { - UpdateVisuals(rayInteractor.isSelectActive ? 1 : 0); + UpdateReticleProgressVisual(selectInteractor.isSelectActive ? 1 : 0); } } } + private void UpdateReticleProgressVisual(float progress) + { + if (reticleRenderer == null || Mathf.Approximately(progress, smoothedValue)) { return; } + + smoothedValue = Smoothing.SmoothTo(smoothedValue, progress, animationSmoothing, Time.deltaTime); + SetReticleShrink(smoothedValue); + } + private void SetReticleShrink(float value) { reticleRenderer.GetPropertyBlock(propertyBlock); diff --git a/com.microsoft.mrtk.spatialmanipulation/BoundsControl/Visuals/SpatialManipulationReticle.cs b/com.microsoft.mrtk.spatialmanipulation/BoundsControl/Visuals/SpatialManipulationReticle.cs index 343b4ff3ed7..cdc387117e3 100644 --- a/com.microsoft.mrtk.spatialmanipulation/BoundsControl/Visuals/SpatialManipulationReticle.cs +++ b/com.microsoft.mrtk.spatialmanipulation/BoundsControl/Visuals/SpatialManipulationReticle.cs @@ -11,7 +11,7 @@ namespace Microsoft.MixedReality.Toolkit.SpatialManipulation /// A reticle used to visualize spatial manipulation capabilities when hovering over a bounding box handle. /// The reticle is oriented in relation to the bounding box, to indicate the direction for rotation or scaling. /// - public class SpatialManipulationReticle : MonoBehaviour, IVariableReticle + public class SpatialManipulationReticle : MonoBehaviour, IReticleVisual { /// /// The type of the reticle visuals. Scale or Rotate. @@ -28,7 +28,7 @@ public class SpatialManipulationReticle : MonoBehaviour, IVariableReticle /// /// Rotates the cursor reticle based on the hovered or selected handle's position relative to the box visuals. /// - public void UpdateVisuals(VariableReticleUpdateArgs args) + public void UpdateVisual(ReticleVisualUpdateArgs args) { if (args.Interactor is XRRayInteractor rayInteractor) {