U3D_TobaccoWarehouseISMDTSy.../Assets/Framework/Scripts/Runtime/Engine/Engine.Animation/AnimMixer.cs

196 lines
3.8 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Animations;
namespace MotionFramework.Experimental.Animation
{
public sealed class AnimMixer : AnimNode
{
private const float HIDE_DURATION = 0.25f;
private readonly List<AnimState> _states = new List<AnimState>(10);
private AnimationMixerPlayable _mixer;
private bool _isQuiting = false;
/// <summary>
/// 动画层级
/// </summary>
public int Layer { private set; get; }
public AnimMixer(PlayableGraph graph, int layer) : base(graph)
{
Layer = layer;
_mixer = AnimationMixerPlayable.Create(graph);
SetSourcePlayable(_mixer);
}
public override void Update(float deltaTime)
{
base.Update(deltaTime);
for (int i = 0; i < _states.Count; i++)
{
var state = _states[i];
if (state != null)
state.Update(deltaTime);
}
bool isAllDone = true;
for (int i = 0; i < _states.Count; i++)
{
var state = _states[i];
if (state != null)
{
if (state.IsDone == false)
isAllDone = false;
}
}
// 当子节点都已经完成的时候断开连接
if (isAllDone && _isQuiting == false)
{
_isQuiting = true;
StartWeightFade(0, HIDE_DURATION);
}
if (_isQuiting)
{
if (Mathf.Approximately(Weight, 0f))
DisconnectMixer();
}
}
/// <summary>
/// 播放指定动画
/// </summary>
public void Play(AnimState animState, float fadeDuration)
{
// 重新激活混合器
_isQuiting = false;
StartWeightFade(1f, 0);
if (IsContains(animState) == false)
{
// 优先插入到一个空位
int index = _states.FindIndex(s => s == null);
if (index == -1)
{
// Increase input count
int inputCount = _mixer.GetInputCount();
_mixer.SetInputCount(inputCount + 1);
animState.Connect(_mixer, inputCount);
_states.Add(animState);
}
else
{
animState.Connect(_mixer, index);
_states[index] = animState;
}
}
for (int i = 0; i < _states.Count; i++)
{
var state = _states[i];
if (state == null)
continue;
if (state == animState)
{
state.StartWeightFade(1f, fadeDuration);
state.PlayNode();
}
else
{
state.StartWeightFade(0f, fadeDuration);
state.PauseNode();
}
}
}
/// <summary>
/// 停止指定动画,恢复为初始状态
/// </summary>
public void Stop(string name)
{
AnimState state = FindState(name);
if (state == null)
return;
state.PauseNode();
state.ResetNode();
}
/// <summary>
/// 暂停所有动画
/// </summary>
public void PauseAll()
{
for (int i = 0; i < _states.Count; i++)
{
var state = _states[i];
if (state == null)
continue;
state.PauseNode();
}
}
/// <summary>
/// 是否包含该动画
/// </summary>
public bool IsContains(AnimNode node)
{
foreach (var state in _states)
{
if (state == node)
return true;
}
return false;
}
/// <summary>
/// 移除一个动画
/// </summary>
public void RemoveState(string name)
{
var state = FindState(name);
if (state == null)
return;
_states[state.InputPort] = null;
state.Destroy();
}
/// <summary>
/// 获取指定的动画
/// </summary>
/// <returns>如果没有返回NULL</returns>
private AnimState FindState(string name)
{
foreach (var state in _states)
{
if (state != null && state.Name == name)
return state;
}
MotionLog.Warning($"Animation state doesn't exist : {name}");
return null;
}
private void DisconnectMixer()
{
for (int i = 0; i < _states.Count; i++)
{
var state = _states[i];
if (state == null)
continue;
state.Disconnect();
_states[i] = null;
}
Disconnect();
}
}
}