using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; namespace ActionTool { public static class ActionManager { public static string s_AnimFolder = "Assets/Art/Animations/"; public static string s_Controller = "Assets/ActionTool/controller_temp.controller"; public static string s_AnimationDataFolder = "Assets/Data/AnimationData/"; static string s_RootMotionDataFolder = "Assets/Data/RootMotionData/"; public static ActionEditor AnimationWindow; public static ActionPreviewEditor PreviewWindow; public static ActionEventEditor EventEditWindow; public static ActionColliderEditor ColliderWindow; //规定timeline上事件的采样频率是30帧 public const int FPS = 30; public static float Speed = 1; public static GameObject CurrentUnit { get { return s_CurrentUnit; } } public static string CurrentAnimationName { get { return s_CurrentAnimationName; } } private static GameObject s_CurrentUnit; private static string s_CurrentAnimationName; private static GameObject s_UnitInstance; private static Animator s_Animator; private static AnimatorOverrideController s_OverrideContorller; private static ActionData s_CurActionData; public static ActionData actionData { get { return s_CurActionData; } } public static Vector3 s_InitPosition = Vector3.zero; public static Quaternion s_InitRotation = Quaternion.identity; private static RootMotionData s_RootMotion; private static AnimationData m_AnimationData; public static AnimationData animationData { get { return m_AnimationData; } set { m_AnimationData = value; if (gizmos) { gizmos.SetAnimationData(value); } } } private static ColliderData s_CurColliderData; public static ColliderData colliderData { get { return s_CurColliderData; } } public static ColliderData.ColliderFrame s_CurEditColliderFrame; public static ColliderData.ColliderFrame editColliderFrame { get { return s_CurEditColliderFrame; } } private static ActionToolGizmos s_Gizmos; public static ActionToolGizmos gizmos { get { return s_Gizmos; } } // 是否在自动播放 private static bool s_IsPlay; public static bool IsPlay { get { return s_IsPlay; } } private static GameObject s_RootActionTool; private const string kRootActionTool = "RootActionTool"; public const int kMaxEventsPerFrame = 10; public static int eventAndBoxCount { get { return kMaxEventsPerFrame + (animationData != null ? animationData.GetBoxesCount() : 0); } } public static void OnSelectObj(GameObject obj) { Release(); s_CurrentUnit = obj; if(s_CurrentUnit != null) { s_UnitInstance = GameObject.Instantiate(obj); InitializeUnitInstance(s_UnitInstance); } } public static void OnSelectAnimation(string animation) { s_CurrentAnimationName = animation; if (PreviewWindow == null) PreviewWindow = EditorWindow.GetWindow(); PreviewWindow.Repaint(); string unitName = s_CurrentUnit.name; string animpath = s_AnimFolder + unitName + "/" + animation + ".anim"; AnimationClip clip = AssetDatabase.LoadAssetAtPath(animpath, typeof(AnimationClip)) as AnimationClip; if (clip) { s_OverrideContorller["EmptyAction"] = clip; } string rootmotionData = s_RootMotionDataFolder + unitName + "/" + animation + ".asset"; s_RootMotion = AssetDatabase.LoadAssetAtPath(rootmotionData); if (s_RootMotion == null) { Debug.LogError("[ActionTool] 没有对应的rootmotion, " + rootmotionData); } if (s_CurActionData == null) s_CurActionData = new ActionData(); s_CurActionData.Initialize(s_Animator, clip, s_RootMotion); string animationDataPath = s_AnimationDataFolder + unitName + "/" + animation + ".asset"; animationData = AssetDatabase.LoadAssetAtPath(animationDataPath); } public static bool HasSelectObj() { return s_CurrentUnit != null; } public static string GetUnitName() { if (s_CurrentUnit == null) return null; return s_CurrentUnit.name; } public static void Release() { if(s_UnitInstance != null) GameObject.DestroyImmediate(s_UnitInstance); s_UnitInstance = null; s_CurrentUnit = null; s_CurrentAnimationName = null; s_Animator = null; s_RootActionTool = GameObject.Find(kRootActionTool); if (s_RootActionTool) GameObject.DestroyImmediate(s_RootActionTool); s_CurActionData = null; s_CurEditColliderFrame = null; s_CurColliderData = null; } private static void InitializeUnitInstance(GameObject unit) { if (unit == null) return; unit.transform.position = s_InitPosition; unit.transform.rotation = s_InitRotation; s_RootActionTool = GameObject.Find(kRootActionTool); if(s_RootActionTool == null) s_RootActionTool = new GameObject(kRootActionTool); unit.transform.SetParent(s_RootActionTool.transform); s_Animator = unit.GetComponentInChildren(); if(s_Animator == null) { Debug.LogError("[ActionTool] 角色prefab下没有animator"); return; } RuntimeAnimatorController controller = AssetDatabase.LoadAssetAtPath(s_Controller, typeof(RuntimeAnimatorController)) as RuntimeAnimatorController; if(controller == null) { Debug.LogError("[ActionTool] 文件丢失" + s_Controller); return; } s_OverrideContorller = new AnimatorOverrideController(controller); s_OverrideContorller.name = "override controller"; s_Animator.runtimeAnimatorController = s_OverrideContorller; s_Animator.applyRootMotion = false; s_Gizmos = unit.AddComponent(); } public static void UpdateFrame() { if (s_CurActionData != null) s_CurActionData.UpdateFrame(); } public static void Pause() { s_IsPlay = !s_IsPlay; if(s_IsPlay && s_CurActionData != null) { s_CurActionData.StartFrame(); } } public static void Start() { if (s_CurActionData != null) s_CurActionData.curAnimTimeNormal = 0; } public static void Stop() { if (s_CurActionData != null) { if (s_IsPlay) Pause(); s_CurActionData.curAnimTimeNormal = 0; } } public static void Previous() { if (s_IsPlay) Pause(); float cur = s_CurActionData.curAnimFrame; float pre = Mathf.Ceil(cur - 1); pre = (int)Mathf.Clamp(pre, 0, s_CurActionData.totalFrame); s_CurActionData.SetCurrentAnimTime(pre); } public static void Next() { if (s_IsPlay) Pause(); float cur = s_CurActionData.curAnimFrame; float next = Mathf.Floor(cur + 1); next = (int)Mathf.Clamp(next, 0, s_CurActionData.totalFrame); s_CurActionData.SetCurrentAnimTime(next); } public static void End() { if (s_CurActionData != null) s_CurActionData.curAnimTimeNormal = 1; } public static void CreateAnimationData() { string unitName = s_CurrentUnit.name; string animation = s_CurrentAnimationName; string animationDataPath = s_AnimationDataFolder + unitName + "/" + animation + ".asset"; string animpath = s_AnimFolder + unitName + "/" + animation + ".anim"; AnimationData animData = new AnimationData(); animData.animationName = s_CurrentAnimationName; animData.animationPath = animpath; AssetDatabase.CreateAsset(animData, animationDataPath); AssetDatabase.Refresh(); animationData = animData; } public static void SaveAnimationData() { if (animationData == null) { Debug.LogError("[ActionTool] 没有animation data数据"); return; } EditorUtility.SetDirty(animationData); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } public static void NewHurtBox() { if (animationData == null) { Debug.LogError("[ActionTool] 没有animation data数据"); return; } ColliderData box = new ColliderData(ColliderBox.EColliderType.HurtBox, ColliderBox.Pivot.MiddleBottom); animationData.AddBox(ref animationData.hurtBoxes, box); } public static void NewHitBox() { if (animationData == null) { Debug.LogError("[ActionTool] 没有animation data数据"); return; } ColliderData box = new ColliderData(ColliderBox.EColliderType.HitBox, ColliderBox.Pivot.MiddleCenter); animationData.AddBox(ref animationData.hitBoxes, box); } public static void DeleteCurBox() { if(animationData != null && s_CurColliderData != null) { animationData.DeleteBox(s_CurColliderData); s_CurColliderData = null; } } public static void OnSelectBox(ColliderData collider) { s_CurColliderData = collider; } public static void AddNewBoxFrame(object param) { BoxParam frame = (BoxParam)param; int frameIndex = frame.frame; var data = frame.collider; if(data != null) { var frameData = data.AddFrame(frameIndex); OnSelectColliderFrame(frameData); } } public static void DeleteBoxFrame(object param) { BoxParam frame = (BoxParam)param; int frameIndex = frame.frame; var data = frame.collider; if (data != null) { data.DeleteFrame(frameIndex); } } public static void DeleteCurFrame() { if (s_CurColliderData == null) return; if (s_CurEditColliderFrame == null) return; s_CurColliderData.DeleteFrame(s_CurEditColliderFrame.frame); s_CurEditColliderFrame = null; } public static void OnSelectColliderFrame(ColliderData.ColliderFrame frame) { s_CurEditColliderFrame = frame; if (frame != null) { ColliderWindow = EditorWindow.GetWindow(true); ActionData action = ActionManager.actionData; float normaltime = frame.frame / action.totalFrame; action.curAnimTimeNormal = normaltime; } } } }