79 lines
2.9 KiB
C#
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;
|
|
}
|
|
}
|
|
} |