using System; using System.Collections; using Unity.XR.CoreUtils.Bindings.Variables; namespace UnityEngine.XR.Interaction.Toolkit.Utilities.Tweenables { /// /// Tweenable variable uses bindable variable and target value to tween over time towards a target value. /// /// BindableVariable type. [Obsolete("The Affordance System namespace and all associated classes have been deprecated. The existing affordance system will be moved, replaced and updated with a new interaction feedback system in a future version of XRI.")] public abstract class TweenableVariableBase : BindableVariable where T : IEquatable { /// /// Threshold to compare tween amount above which the tween is short-circuited to the target value. /// protected const float k_NearlyOne = 0.99999f; AnimationCurve m_AnimationCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); /// /// Animation curve used for sequence animations. /// public AnimationCurve animationCurve { get => m_AnimationCurve; set { m_AnimationCurve = value; OnAnimationCurveChanged(value); } } T m_Target; /// /// Target value used when tweening variable value. /// /// public T target { get => m_Target; set { if (m_Target.Equals(value)) return; m_Target = value; OnTargetChanged(m_Target); } } /// /// Initial value used for certain tween jobs that need to process from the initial state. /// public T initialValue { get; set; } = default; /// /// Tween from current value to target using tween target. /// /// Value between 0-1 used in tween evaluation. public void HandleTween(float tweenTarget) { if (ValueEquals(target)) return; PreprocessTween(); ExecuteTween(Value, target, tweenTarget); } /// /// Tween from current value to target using tween target. /// /// Tween starting value. /// Tween target value. /// Value between 0-1 used in tween evaluation. /// Whether the animation curve should be used in the tween evaluation. /// protected abstract void ExecuteTween(T startValue, T targetValue, float tweenAmount, bool useCurve = false); /// /// Coroutine used to automatically tween every frame. /// /// Multiplier used to scale deltaTime for tweens. /// Returns enumerator used for coroutine. public IEnumerator StartAutoTween(float deltaTimeMultiplier) { while (true) { HandleTween(Time.deltaTime * deltaTimeMultiplier); yield return null; } } /// /// Play sequence to animate value from start to finish over given duration. /// /// Value to start animation at. /// Target Value to end animation at. /// Duration of animation. /// Optional callback when animation completes. /// Returns enumerator used for coroutine. public IEnumerator PlaySequence(T start, T finish, float duration, Action onComplete = null) { var timeElapsed = 0f; while (timeElapsed < duration) { PreprocessTween(); var completionPercent = Mathf.Clamp01(timeElapsed / duration); ExecuteTween(start, finish, completionPercent, useCurve: true); yield return null; timeElapsed += Time.deltaTime; } PreprocessTween(); ExecuteTween(start, finish, 1f); onComplete?.Invoke(); } /// /// Called when the animation curve reference used for sequence animations changed. /// /// The new value of the property. /// protected virtual void OnAnimationCurveChanged(AnimationCurve value) { } /// /// Callback when new tween target value is assigned. /// /// New target value. /// protected virtual void OnTargetChanged(T newTarget) { } /// /// Logic to execute before a tween can be processed. /// protected virtual void PreprocessTween() { } } }