From 98f31f197a126850a5878cd6e583ae6dbf64ab3d Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 15 Sep 2021 12:50:26 +0800 Subject: *rename --- Assets/Tools/ActionTool/Editor/ActionData.cs | 390 +++++++++++++++++++++++++++ 1 file changed, 390 insertions(+) create mode 100644 Assets/Tools/ActionTool/Editor/ActionData.cs (limited to 'Assets/Tools/ActionTool/Editor/ActionData.cs') diff --git a/Assets/Tools/ActionTool/Editor/ActionData.cs b/Assets/Tools/ActionTool/Editor/ActionData.cs new file mode 100644 index 00000000..3da31388 --- /dev/null +++ b/Assets/Tools/ActionTool/Editor/ActionData.cs @@ -0,0 +1,390 @@ +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; + + private static List m_Projectiles = new List(); + private static List m_ParticleSystems = new List(); + + #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 int m_PrevAnimEventFrame; // 上次的帧数(整数) + + private bool m_NotApplyCurves; + public bool applyCurves { get { return !m_NotApplyCurves; } set { m_NotApplyCurves = !value; } } // 是否开启curve控制速度 + 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(ActionManager.unitRoot.transform); + m_TimelineEventProxy.isInEditMode = true; + m_TimelineEventProxy.registerProjectile = RegisterProjectile; + m_TimelineEventProxy.registerParticleSystem = RegisterParticleSystem; + } + + 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() + { + float dt = (float)(EditorApplication.timeSinceStartup - m_PrevLocalTime); + + if (ActionManager.IsPlay) + { + float deltaFrame = dt * 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) + { + ActionManager.ResetUnitRootPosAndRot(); + m_PrevNormalTime = 0; + } + m_CurAnimFrame %= m_TotalFrame; + } + + UpdateParticles(dt); + + UpdateProjectiles(dt); + + 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; + + if(applyRootMotion) + { + var animData = ActionManager.animationData; + bool overrideRM = animData != null && animData.overrideRootMotion == true; + + if(!overrideRM && m_RootMotion) + { + // Action Tool这里需要转换一下root motion的轴 + ActionManager.unitRoot.transform.position = RootMotionUtility.ExchangeXZ(m_RootMotion.GetRootMotion(normalizeTime)); + } + else if(overrideRM) + { + if(!ActionRootMotionEditor.IsRecord) + { + ActionManager.unitRoot.transform.position = animData.rootMotionOverrideData.GetPosition(m_CurAnimFrame); + } + else // 只在第一次播到这一帧的时候设置位置,否则场景里没法编辑位置 + { + int curAnimEventFrame = (int)m_CurAnimFrame; + normalizeTime = curAnimEventFrame / m_TotalFrame; + if (curAnimEventFrame != m_PrevAnimEventFrame) + { + ActionManager.unitRoot.transform.position = animData.rootMotionOverrideData.GetPosition(curAnimEventFrame); + } + m_PrevAnimEventFrame = curAnimEventFrame; + } + } + } + + m_Animator.speed = 1; + m_Animator.Play(kStateName, 0, normalizeTime); + m_Animator.Update(0); + m_Animator.speed = 0; + + } + + 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; + } + + public static void RegisterProjectile(Projectile projectile) + { + m_Projectiles.Add(projectile); + } + + public static void RegisterParticleSystem(FxClear vfx) + { + m_ParticleSystems.Add(vfx); + } + + void UpdateProjectiles(float dt) + { + List removed = ListPool.Get(); + // 更新projectile + for (int i = 0; i < m_Projectiles.Count; ++i) + { + if (m_Projectiles[i] == null) + continue; + m_Projectiles[i].Update(dt); + if (m_Projectiles[i] != null) + { + TransformEx.DoRecursively(m_Projectiles[i].transform, (t) => { + ParticleSystem ps = t.GetComponent(); + if (ps != null) + { + ps.Simulate(m_Projectiles[i].time); + } + }, true); + } + else + { + removed.Add(m_Projectiles[i]); + } + } + ListPool.Release(removed); + } + + void UpdateParticles(float dt) + { + List removed = ListPool.Get(); + // 更新粒子系统 + for (int i = 0; i < m_ParticleSystems.Count; ++i) + { + if (m_ParticleSystems[i] == null) + continue; + if (m_ParticleSystems[i] != null) + { + m_ParticleSystems[i].UpdateFunc(dt); + if (m_ParticleSystems[i] != null) + { + TransformEx.DoRecursively(m_ParticleSystems[i].transform, (t) => { + ParticleSystem ps = t.GetComponent(); + if (ps != null) + { + ps.Simulate(m_ParticleSystems[i].time); + } + }, true); + } + else + { + removed.Add(m_ParticleSystems[i]); + } + } + } + ListPool.Release(removed); + } + + } + +} -- cgit v1.1-26-g67d0