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()
{
}
}
}