using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Linq; using UnityEngine; using UnityEditor; namespace ActionTool { // 正在编辑的动画 public class ActionData { private Animator m_Animator; private AnimationClip m_Clip; private AnimationData m_AnimData; // asset private List m_EventList { get { return m_AnimData != null ? m_AnimData.animationEvents : null; } } private AnimationEventBase m_CurEventInfo; // 当前正在编辑的event private TimelineEventProxy m_TimelineEventProxy; #region metadata private float m_TotalFrame; //timeline采样的总帧数 public float totalFrame { get { return m_TotalFrame; } } private float m_SampleRate; // 每次采样的时间间隔 public float sampleRate { get { return m_SampleRate; } } #endregion public float curAnimFrame { get { return m_CurAnimFrame; } } public float curAnimTimeNormal { get { return m_CurAnimFrame / m_TotalFrame; } set { float v = value % m_TotalFrame; m_CurAnimFrame = v * m_TotalFrame; } } private int m_PrevFrame; private float m_CurAnimFrame; private double m_PrevLocalTime; private float m_PrevNormalTime; private bool m_NotApplyCurve; public bool applyCurve { get { return !m_NotApplyCurve; } set { m_NotApplyCurve = !value; } } // 是否开启curve控制速度 private bool m_NotApplyRM; public bool applyRootMotion { get { return !m_NotApplyRM; } set { m_NotApplyRM = !value; } } private const string kStateName = "Action"; public RootMotionData rootMotion { get{ return m_RootMotion; } } private RootMotionData m_RootMotion; public string rootMotionPath { get { return AssetDatabase.GetAssetPath(m_RootMotion); } } public void Initialize(Animator animator, AnimationClip clip, RootMotionData rootmotion) { m_Animator = animator; m_Clip = clip; if(m_Clip != null) { m_TotalFrame = m_Clip.length * ActionManager.FPS; m_SampleRate = m_Clip.length / m_TotalFrame; } m_PrevFrame = -1; m_CurAnimFrame = 0; m_PrevLocalTime = 0; m_Animator.Play(kStateName, 0, 0); m_RootMotion = rootmotion; m_TimelineEventProxy = new TimelineEventProxy(animator.gameObject.transform); } public void SetCurrentAnimTime(float time) { m_CurAnimFrame = time; } public void SetCurrentEvent(int index) { if(index < 0) { m_CurEventInfo = null; } else if(m_EventList != null) { m_CurEventInfo = m_EventList[index]; } else { m_CurEventInfo = null; } } public AnimationEventBase GetEvent(int index) { if(m_EventList != null && index >= 0 && index < m_EventList.Count) { return m_EventList[index]; } else { return null; } } public int GetEventCount() { if (m_EventList != null) return m_EventList.Count; return 0; } public void RemoveCurrentEvent() { if(m_EventList != null) { m_EventList.Remove(m_CurEventInfo); m_CurEventInfo = null; } } public void RemoveAllEvent() { if(m_EventList != null) { m_EventList.Clear(); m_CurEventInfo = null; } } public void StartFrame() { m_PrevFrame = -1; m_PrevLocalTime = EditorApplication.timeSinceStartup; } public void UpdateFrame() { if (ActionManager.IsPlay) { float deltaFrame = (float)(EditorApplication.timeSinceStartup - m_PrevLocalTime) * (ActionManager.FPS * ActionManager.Speed); if (applyCurve) { float normalizeTime = m_CurAnimFrame / m_TotalFrame; AnimationData animData = ActionManager.animationData; if (animData) { AnimationCurve curve = animData.speedCurve; deltaFrame *= curve.Evaluate(normalizeTime); } } m_CurAnimFrame += deltaFrame; if (m_CurAnimFrame > m_TotalFrame) { m_Animator.transform.position = ActionManager.s_InitPosition; m_Animator.transform.rotation = ActionManager.s_InitRotation; m_PrevNormalTime = 0; } m_CurAnimFrame %= m_TotalFrame; } ActionManager.gizmos.SetCurAnimFrame(m_CurAnimFrame); SampleFrame(); RunEvent(); m_PrevLocalTime = EditorApplication.timeSinceStartup; } // 播放当前帧 public void SampleFrame() { if (m_Animator == null) return; float normalizeTime = m_CurAnimFrame / m_TotalFrame; m_Animator.speed = 1; m_Animator.Play(kStateName, 0, normalizeTime); m_Animator.Update(0); m_Animator.speed = 0; if(applyRootMotion && m_RootMotion) { #if true m_Animator.transform.position = m_RootMotion.GetRootMotion(normalizeTime); #else Vector3 dis = m_RootMotion.GetRootMotionDistance(m_PrevNormalTime, normalizeTime); m_Animator.transform.position += dis; m_PrevNormalTime = normalizeTime; #endif } } public int GetCurrentFrame() { float animTime = sampleRate * m_CurAnimFrame; int curFrame = Mathf.RoundToInt(animTime * ActionManager.FPS); return curFrame; } public void RunEvent() { if (m_TimelineEventProxy != null) m_TimelineEventProxy.ExecuteAnimationEvents(ActionManager.animationData, m_CurAnimFrame); } public void CreateEvent(TimelineEventProxy.EEventType eventtype, int startFrame) { var classes = Assembly .GetAssembly(typeof(AnimationEventBase)) .GetTypes() .Where(t => t.IsSubclassOf(typeof(AnimationEventBase))); Type type = null; foreach (var itor in classes) { string name = itor.Name; if(itor.Name == eventtype.ToString()) { type = itor; break; } } if(type != null) { var e = Activator.CreateInstance(type) as AnimationEventBase; //e.type = eventtype; e.startFrame = startFrame; AddEvent(e); } else { Debug.LogError("[ActionTool] 没有对应类型的event" + eventtype.ToString()); } } public void AddEvent(AnimationEventBase evnt) { if (m_AnimData == null || m_EventList == null) { Debug.LogError("[ActionTool] 没有对应的action数据,是否在" + ActionManager.unitAnimationDataFolder + "创建"); return; } m_EventList.Add(evnt); } public void SaveActionData() { if (m_AnimData == null) return; EditorUtility.SetDirty(m_AnimData); AssetDatabase.SaveAssets(); } public void Clear() { m_Animator = null; m_Clip = null; m_AnimData = null; m_CurEventInfo = null; m_TotalFrame = 0; m_CurAnimFrame = 0; m_PrevFrame = 0; m_PrevLocalTime = 0; m_SampleRate = 0; } } }