Files
RebootKit/Runtime/Engine/Code/Animations/MixerNode.cs
2025-08-31 20:46:27 +02:00

79 lines
2.9 KiB
C#

using System;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;
namespace RebootKit.Engine.Animations {
[Serializable]
public class MixerNode : IReAnimatorNode {
[Serializable]
struct InputState {
[SerializeReference] public IReAnimatorNode node;
[Range(0.0f, 1.0f)] public float targetWeight;
[NonSerialized] public float CurrentWeight;
}
[field: SerializeField] public string Name { get; private set; }
AnimationMixerPlayable m_Mixer;
[SerializeField] float m_TransitionSpeed = 5.0f;
[SerializeField] InputState[] m_Inputs;
public void Tick(float deltaTime) {
for (int i = 0; i < m_Inputs.Length; ++i){
if (m_TransitionSpeed > 0.0f) {
m_Inputs[i].CurrentWeight = Mathf.MoveTowards(m_Inputs[i].CurrentWeight,
m_Inputs[i].targetWeight,
m_TransitionSpeed * deltaTime);
} else {
m_Inputs[i].CurrentWeight = m_Inputs[i].targetWeight;
}
m_Mixer.SetInputWeight(i, m_Inputs[i].CurrentWeight);
m_Inputs[i].node.Tick(deltaTime);
}
}
public IPlayable Build(PlayableGraph graph) {
m_Mixer = AnimationMixerPlayable.Create(graph, m_Inputs.Length);
for (int i = 0; i < m_Inputs.Length; ++i) {
IPlayable playable = m_Inputs[i].node.Build(graph);
if (playable is AnimationMixerPlayable mixerPlayable) {
m_Mixer.ConnectInput(i, mixerPlayable, 0, m_Inputs[i].targetWeight);
} else if (playable is AnimationClipPlayable clipPlayable) {
m_Mixer.ConnectInput(i, clipPlayable, 0, m_Inputs[i].targetWeight);
} else if (playable is AnimationLayerMixerPlayable layerMixerPlayable) {
m_Mixer.ConnectInput(i, layerMixerPlayable, 0, m_Inputs[i].targetWeight);
}
}
return m_Mixer;
}
public bool TryFindChild(string name, out IReAnimatorNode node) {
for (int i = 0; i < m_Inputs.Length; i++) {
if (m_Inputs[i].node.Name.Equals(name, StringComparison.Ordinal)) {
node = m_Inputs[i].node;
return true;
}
if (m_Inputs[i].node.TryFindChild(name, out IReAnimatorNode childNode)) {
node = childNode;
return true;
}
}
node = null;
return false;
}
public void SetInputWeight(int index, float weight) {
m_Inputs[index].targetWeight = weight;
}
}
}