2025-05-09 15:40:34 +08:00

79 lines
2.9 KiB
C#

// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
using System;
using System.Collections.Generic;
namespace Animancer
{
/// <summary>
/// Fades the child weights of a <see cref="MixerState{TParameter}"/> to a new parameter value
/// instead of fading the actual parameter.
/// </summary>
///
/// <remarks>
/// <para></para>
/// <strong>Documentation:</strong>
/// <see href="https://kybernetik.com.au/animancer/docs/manual/blending/mixers/smoothing">
/// Smoothing</see>
/// <para></para>
/// <strong>Example:</strong>
/// Imagine a Linear Mixer with thresholds 0, 1, 2 and child states A, B, C.
/// If you fade its Parameter from 0 to 1 the states would go from A to B to C.
/// But if you use this system instead, the states would go directly from A to C.
/// <h2>Usage</h2>
/// <code>
/// [SerializeField] private AnimancerComponent _Animancer;
/// [SerializeField] private LinearMixerTransition _Mixer;
///
/// public void FadeMixerTo(float parameter, float fadeDuration)
/// {
/// _Mixer.State.FadeChildWeights(parameter, fadeDuration);
/// }
/// </code></remarks>
///
/// https://kybernetik.com.au/animancer/api/Animancer/MixerChildFade
///
public static class MixerChildFade
{
/************************************************************************************************************************/
private static readonly List<float>
ChildWeights = new();
/************************************************************************************************************************/
/// <summary>
/// Fades the child weights of a <see cref="MixerState{TParameter}"/> to a new parameter value instead of fading
/// the actual parameter.
/// </summary>
/// <remarks>See <see cref="MixerChildFade"/> for a usage example.</remarks>
public static void FadeChildWeights<TParameter>(
this MixerState<TParameter> mixer,
TParameter parameter,
float fadeDuration)
{
ChildWeights.Clear();
var childCount = mixer.ChildCount;
for (int i = 0; i < childCount; i++)
ChildWeights.Add(mixer.GetChild(i).Weight);
mixer.Parameter = parameter;
if (!mixer.RecalculateWeights())
return;
var mixerPlayable = mixer.Playable;
for (int i = 0; i < childCount; i++)
{
var child = mixer.GetChild(i);
mixerPlayable.SetChildWeight(child, ChildWeights[i]);
child.StartFade(Math.Max(child.TargetWeight, float.Epsilon), fadeDuration);
}
}
/************************************************************************************************************************/
}
}