79 lines
2.3 KiB
C#
79 lines
2.3 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.Animations;
|
|
using UnityEngine.Assertions;
|
|
using UnityEngine.Playables;
|
|
using Logger = RebootKit.Engine.Foundation.Logger;
|
|
|
|
// @TODO:
|
|
// - avoid boxing values
|
|
// - think about refactoring in order to reduce gc allocs
|
|
namespace RebootKit.Engine.Animations {
|
|
public interface IReAnimatorNode {
|
|
string Name { get; }
|
|
|
|
void Tick(float deltaTime);
|
|
IPlayable Build(PlayableGraph graph);
|
|
|
|
bool TryFindChild(string name, out IReAnimatorNode node);
|
|
}
|
|
|
|
[DefaultExecutionOrder(-100)]
|
|
public class ReAnimator : MonoBehaviour {
|
|
static readonly Logger s_Logger = new Logger(nameof(ReAnimator));
|
|
|
|
[SerializeField] Animator m_Animator;
|
|
[SerializeField] LayerMixerNode m_Root;
|
|
|
|
PlayableGraph m_Graph;
|
|
AnimationPlayableOutput m_Output;
|
|
|
|
void Awake() {
|
|
Assert.IsNotNull(m_Animator, "Animator is not set");
|
|
|
|
m_Animator.runtimeAnimatorController = null;
|
|
|
|
m_Graph = PlayableGraph.Create(name);
|
|
m_Output = AnimationPlayableOutput.Create(m_Graph, "Animation Output", m_Animator);
|
|
|
|
if (m_Root.Build(m_Graph) is AnimationLayerMixerPlayable layerMixer) {
|
|
m_Output.SetSourcePlayable(layerMixer, 0);
|
|
}
|
|
|
|
m_Graph.Play();
|
|
}
|
|
|
|
void OnDestroy() {
|
|
if (m_Graph.IsValid()) {
|
|
m_Graph.Destroy();
|
|
}
|
|
}
|
|
|
|
void Update() {
|
|
m_Root.Tick(Time.deltaTime);
|
|
}
|
|
|
|
public void SetLayerWeight(int layer, float weight) {
|
|
m_Root.SetLayerWeight(layer, weight);
|
|
}
|
|
|
|
public IReAnimatorNode FindNode(string nodeName) {
|
|
if (m_Root.TryFindChild(nodeName, out IReAnimatorNode node)) {
|
|
return node;
|
|
}
|
|
|
|
s_Logger.Error($"Couldn't find node with name: {nodeName}");
|
|
return null;
|
|
}
|
|
|
|
public TNode FindNode<TNode>(string nodeName) where TNode : class, IReAnimatorNode {
|
|
IReAnimatorNode node = FindNode(nodeName);
|
|
if (node is TNode tnode) {
|
|
return tnode;
|
|
}
|
|
|
|
s_Logger.Error($"Couldn't find node with name: {nodeName} of type {typeof(TNode).Name}");
|
|
return null;
|
|
}
|
|
}
|
|
} |