MixerParameterTween.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2022 Kybernetik //
  2. using UnityEngine;
  3. namespace Animancer
  4. {
  5. /// <summary>A <see cref="MixerParameterTween{TParameter}"/> which uses <see cref="Mathf.LerpUnclamped"/>.</summary>
  6. /// <remarks>
  7. /// Documentation: <see href="https://kybernetik.com.au/animancer/docs/manual/blending/mixers#smoothing">Smoothing</see>
  8. /// </remarks>
  9. /// <example><code>
  10. /// [SerializeField] private AnimancerComponent _Animancer;
  11. /// [SerializeField] private LinearMixerTransition _Mixer;
  12. ///
  13. /// private MixerParameterTweenFloat _MixerTween;
  14. ///
  15. /// private void Awake()
  16. /// {
  17. /// // Play creates the LinearMixerState from the transition.
  18. /// _Animancer.Play(_Mixer);
  19. ///
  20. /// // Now that the state exists, we can create a tween for it.
  21. /// _MixerTween = new MixerParameterTweenFloat(_Mixer.State);
  22. ///
  23. /// // Start tweening the parameter towards 0.5 over a period of 0.25 seconds.
  24. /// _MixerTween.Start(0.5f, 0.25f);
  25. /// }
  26. /// </code></example>
  27. /// https://kybernetik.com.au/animancer/api/Animancer/MixerParameterTweenFloat
  28. ///
  29. public class MixerParameterTweenFloat : MixerParameterTween<float>
  30. {
  31. public MixerParameterTweenFloat() { }
  32. public MixerParameterTweenFloat(MixerState<float> mixer) : base(mixer) { }
  33. protected override float CalculateCurrentValue() => Mathf.LerpUnclamped(StartValue, EndValue, Progress);
  34. }
  35. /************************************************************************************************************************/
  36. /// <summary>A <see cref="MixerParameterTween{TParameter}"/> which uses <see cref="Vector2.LerpUnclamped"/>.</summary>
  37. /// <example>See <see cref="MixerParameterTweenFloat"/>.</example>
  38. /// https://kybernetik.com.au/animancer/api/Animancer/MixerParameterTweenVector2
  39. ///
  40. public class MixerParameterTweenVector2 : MixerParameterTween<Vector2>
  41. {
  42. public MixerParameterTweenVector2() { }
  43. public MixerParameterTweenVector2(MixerState<Vector2> mixer) : base(mixer) { }
  44. protected override Vector2 CalculateCurrentValue() => Vector2.LerpUnclamped(StartValue, EndValue, Progress);
  45. }
  46. /************************************************************************************************************************/
  47. /// <summary>A system which interpolates a <see cref="MixerState{TParameter}.Parameter"/> over time.</summary>
  48. /// <example>See <see cref="MixerParameterTweenFloat"/>.</example>
  49. /// https://kybernetik.com.au/animancer/api/Animancer/MixerParameterTween_1
  50. ///
  51. public abstract class MixerParameterTween<TParameter> : Key, IUpdatable
  52. {
  53. /************************************************************************************************************************/
  54. /// <summary>The target <see cref="MixerState{TParameter}"/>.</summary>
  55. public MixerState<TParameter> Mixer { get; set; }
  56. /************************************************************************************************************************/
  57. /// <summary>The value of the <see cref="MixerState{TParameter}.Parameter"/> when this tween started.</summary>
  58. public TParameter StartValue { get; set; }
  59. /// <summary>The target value this tween is moving the <see cref="MixerState{TParameter}.Parameter"/> towards.</summary>
  60. public TParameter EndValue { get; set; }
  61. /************************************************************************************************************************/
  62. /// <summary>The amount of time this tween will take (in seconds).</summary>
  63. public float Duration { get; set; }
  64. /// <summary>The amount of time that has passed since the <see cref="Start"/> (in seconds).</summary>
  65. public float Time { get; set; }
  66. /// <summary>The normalized progress (0 to 1) of this tween towards its goal.</summary>
  67. public float Progress
  68. {
  69. get => Time / Duration;
  70. set => Time = value * Duration;
  71. }
  72. /************************************************************************************************************************/
  73. /// <summary>Creates a new <see cref="MixerParameterTween{TParameter}"/>.</summary>
  74. public MixerParameterTween() { }
  75. /// <summary>Creates a new <see cref="MixerParameterTween{TParameter}"/> and sets the <see cref="Mixer"/>.</summary>
  76. public MixerParameterTween(MixerState<TParameter> mixer) => Mixer = mixer;
  77. /************************************************************************************************************************/
  78. /// <summary>
  79. /// Sets the details of this tween and registers it to be updated so that it can apply its effects every frame.
  80. /// </summary>
  81. public void Start(TParameter endValue, float duration)
  82. {
  83. #if UNITY_ASSERTIONS
  84. AnimancerUtilities.Assert(Mixer != null, nameof(Mixer) + " is null.");
  85. AnimancerUtilities.Assert(Mixer.Root != null, $"{nameof(Mixer)}.{nameof(Mixer.Root)} is null.");
  86. #endif
  87. StartValue = Mixer.Parameter;
  88. EndValue = endValue;
  89. Duration = duration;
  90. Time = 0;
  91. Mixer.Root.RequirePreUpdate(this);
  92. }
  93. /************************************************************************************************************************/
  94. /// <summary>Stops this tween from updating.</summary>
  95. public void Stop() => Mixer?.Root?.CancelPreUpdate(this);
  96. /************************************************************************************************************************/
  97. /// <summary>Is this tween currently being updated?</summary>
  98. public bool IsActive => IsInList(this);
  99. /************************************************************************************************************************/
  100. /// <summary>
  101. /// Called every update while this tween is active to calculate the what value to set the
  102. /// <see cref="MixerState{TParameter}.Parameter"/> to. Usually based on the <see cref="StartValue"/>,
  103. /// <see cref="EndValue"/>, and <see cref="Progress"/>.
  104. /// </summary>
  105. protected abstract TParameter CalculateCurrentValue();
  106. /************************************************************************************************************************/
  107. void IUpdatable.Update()
  108. {
  109. Time += AnimancerPlayable.DeltaTime;
  110. if (Time < Duration)// Tween.
  111. {
  112. Mixer.Parameter = CalculateCurrentValue();
  113. }
  114. else// End.
  115. {
  116. Time = Duration;
  117. Mixer.Parameter = EndValue;
  118. Stop();
  119. }
  120. }
  121. /************************************************************************************************************************/
  122. }
  123. }