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/ActionManager.cs | 548 ++++++++++++++++++++++++ 1 file changed, 548 insertions(+) create mode 100644 Assets/Tools/ActionTool/Editor/ActionManager.cs (limited to 'Assets/Tools/ActionTool/Editor/ActionManager.cs') diff --git a/Assets/Tools/ActionTool/Editor/ActionManager.cs b/Assets/Tools/ActionTool/Editor/ActionManager.cs new file mode 100644 index 00000000..d9279745 --- /dev/null +++ b/Assets/Tools/ActionTool/Editor/ActionManager.cs @@ -0,0 +1,548 @@ +using System; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + +namespace ActionTool +{ + // ActionTool callback delegates + public delegate void CallbackHandler(params object[] objs); + + public static class ActionManager + { + public enum UnitType + { + PC, + NPC, + } + + public static string s_Controller = "Assets/ActionTool/controller_temp.controller"; + static string s_SettingPath = "Assets/ActionTool/ActionTool Settings.asset"; + public static string scenePath { get { return "Assets/ActionTool/ActionToolScene.unity"; } } + + //public static string s_AnimFolder = "Assets/Art/Animations/"; + //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 ActionColliderFrameEditor ColliderFrameWindow; + public static ActionColliderEditor ColliderWindow; + public static ActionRootMotionEditor RootMotionEditor; + + public static ActionToolSettings Settings; + + //规定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; + public static GameObject unitInstance { get { return s_UnitInstance; } } + public static GameObject unitRoot { get; private set; } + 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_SharedAnimationData; // 资源 + public static AnimationData sharedAnimationData { get { return m_SharedAnimationData; } } + private static AnimationData m_AnimationData; + public static AnimationData animationData + { + get + { + return m_AnimationData; + } + set + { + m_AnimationData = value; + if (gizmos) + { + gizmos.SetAnimationData(value); + } + } + } + public static AnimationClip curClip; + + public static string AnimationDataPath + { + get + { + return AssetDatabase.GetAssetPath(sharedAnimationData); + } + } + + private static AnimationEventBase m_CurAnimationEvent; + public static AnimationEventBase animationEvent { get { return m_CurAnimationEvent; } } + + private static ColliderData s_CurColliderData; + public static ColliderData colliderData { get { return s_CurColliderData; } set { s_CurColliderData = value; } } + + public static ColliderData.ColliderFrame s_CurEditColliderFrame; + public static ColliderData.ColliderFrame editColliderFrame { get { return s_CurEditColliderFrame; } } + public static ColliderData s_CurEditFrameCollider; + + 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"; + private const string kUnitRoot = "UnitRoot"; + + private static AnimationEventBase copiedAnimationEvent; + + public static int MaxEventsPerFrame // 所有帧里面事件最多有几个 + { + get + { + if (animationData == null) + return 0; + return animationData.GetMaxAnimationEventsCount(); + } + } + + public static int GridRowCount + { + get + { + bool hasRM = animationData != null && animationData.overrideRootMotion == true; + return (MaxEventsPerFrame + 1) + (animationData != null ? animationData.GetBoxesCount() : 0) + (hasRM ? 1 : 0); + } + } + + public static string unitFolder; + public static string unitAnimationDataFolder { get { return unitFolder + "AnimationData/"; } } + public static string unitRootMotionFolder { get { return unitFolder + "RootMotion/"; } } + public static string unitAnimationClipFolder { get { return unitFolder + "AnimationClip/"; } } + public static string unitDataFolder { get { return unitFolder + "UnitData/"; } } + + public static int colliderIndex; + + public static CallbackHandler onSelectObj; + + public static void OnSelectObj(GameObject obj) + { + Release(); + s_CurrentUnit = obj; + if(s_CurrentUnit != null) + { + string path = AssetDatabase.GetAssetPath(obj); + string folder = Path.GetDirectoryName(path).Replace('\\', '/'); + folder = folder.Substring(0, folder.LastIndexOf('/')); + unitFolder = folder + "/"; + s_UnitInstance = GameObject.Instantiate(obj); + InitializeUnitInstance(s_UnitInstance); + } + onSelectObj?.Invoke(obj); + } + + public static void OnSelectAnimation(string animation) + { + s_CurrentAnimationName = animation; + if (PreviewWindow == null) + PreviewWindow = EditorWindow.GetWindow(); + PreviewWindow.Repaint(); + + string animpath = unitAnimationClipFolder + animation + ".anim"; + AnimationClip clip = AssetDatabase.LoadAssetAtPath(animpath, typeof(AnimationClip)) as AnimationClip; + curClip = clip; + if (clip) + { + s_OverrideContorller["EmptyAction"] = clip; + } + + string rootmotionData = unitRootMotionFolder + 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 = unitAnimationDataFolder + animation + ".asset"; + AnimationData asset = AssetDatabase.LoadAssetAtPath(animationDataPath); + m_SharedAnimationData = asset; + if(asset != null) + animationData = UnityEngine.Object.Instantiate(asset); + else + animationData = null; + + OnSelectAnimationEvent(null); + OnSelectColliderFrame(null, null); + OnSelectBox(null); + if (EventEditWindow) EventEditWindow.Close(); + if (ColliderFrameWindow) ColliderFrameWindow.Close(); + + } + + public static bool HasSelectObj() + { + return s_CurrentUnit != null; + } + + 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; + s_CurrentAnimationName = null; + } + + private static void InitializeUnitInstance(GameObject unit) + { + if (unit == null) + return; + + unit.transform.position = Vector3.zero; + unit.transform.rotation = Quaternion.Euler(0, 90, 0); + + var tempUnitRoot = GameObject.Find(kUnitRoot); + if (tempUnitRoot) + GameObject.DestroyImmediate(tempUnitRoot); + unitRoot = new GameObject(kUnitRoot); + unitRoot.transform.localScale = Vector3.one; + unitRoot.transform.rotation = s_InitRotation; + unitRoot.transform.position = s_InitPosition; + unit.transform.SetParent(unitRoot.transform); + + s_RootActionTool = GameObject.Find(kRootActionTool); + if(s_RootActionTool == null) + s_RootActionTool = new GameObject(kRootActionTool); + + unitRoot.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 = s_RootActionTool.AddComponent(); + s_Gizmos.Initialize(unitRoot); + + Settings = AssetDatabase.LoadAssetAtPath(s_SettingPath); + } + + 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 animation = s_CurrentAnimationName; + string animationDataPath = unitAnimationDataFolder + animation + ".asset"; + string animpath = unitAnimationClipFolder + animation + ".anim"; + AnimationData animData = new AnimationData(); + animData.animationName = s_CurrentAnimationName; + animData.animationPath = animpath; + AssetDatabase.CreateAsset(animData, animationDataPath); + AssetDatabase.Refresh(); + m_SharedAnimationData = animData; + animationData = UnityEngine.Object.Instantiate(animData); + } + + public static void SaveAnimationData() + { + if (animationData == null) + { + Debug.LogError("[ActionTool] 没有animation data数据"); + return; + } + string animation = s_CurrentAnimationName; + string animationDataPath = unitAnimationClipFolder + animation + ".asset"; + EditorUtility.CopySerialized(animationData, m_SharedAnimationData); + m_SharedAnimationData.OnSaveToDisk(); + EditorUtility.SetDirty(m_SharedAnimationData); + 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 EditCollider() + { + if (s_CurColliderData == null) + return; + if(ColliderWindow == null) + ColliderWindow = EditorWindow.GetWindow(true); + } + + public static void OnSelectBox(ColliderData collider, int index = 0) + { + s_CurColliderData = collider; + if (ColliderWindow != null) + ColliderWindow.Repaint(); + colliderIndex = index; + EditCollider(); + } + + 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, data); + } + } + + 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_CurEditFrameCollider == null) + return; + if (s_CurEditColliderFrame == null) + return; + s_CurEditFrameCollider.DeleteFrame(s_CurEditColliderFrame.frame); + + s_CurEditColliderFrame = null; + } + + public static void OnSelectColliderFrame(ColliderData.ColliderFrame frame, ColliderData collider = null) + { + s_CurEditColliderFrame = frame; + s_CurEditFrameCollider = collider; + + if (frame != null) + { + ColliderFrameWindow = EditorWindow.GetWindow(true); + + ActionData action = ActionManager.actionData; + float normaltime = frame.frame / action.totalFrame; + action.curAnimTimeNormal = normaltime; + } + } + + public static void AddNewEvent(object param) + { + EventParam eventParam = (EventParam )param; + string eventName = eventParam.eventName; // TimelineEventProxy.EEventType + int frame = eventParam.frame; + Debug.Log("[ActionTool] Add new event " + eventName); + if (animationData == null) + { + Debug.LogError("[ActionTool] 没有animation data数据"); + return; + } + Type type = TimelineEventProxy.GetTypeByName(eventName); + if(type == null) + { + Debug.LogError("[ActionTool] 没有创建对应的类, " + eventName); + return; + } + AnimationEventBase animEvent = Activator.CreateInstance(type) as AnimationEventBase; + if(animEvent) + { + animEvent.name = animEvent.type.ToString(); + animEvent.startFrame = frame; + animationData.AddEvent(animEvent); + OnSelectAnimationEvent(animEvent); + } + else + { + Debug.LogError("[ActionTool] 实例化失败, " + eventName); + return; + } + } + + public static void PasteEvent(object param) + { + if (copiedAnimationEvent == null) + return; + int frame = (int)param; + AnimationEventBase animEvent = UnityEngine.Object.Instantiate(copiedAnimationEvent); + if(animEvent != null) + { + animEvent.name = animEvent.type.ToString(); + animEvent.startFrame = frame; + animationData.AddEvent(animEvent); + OnSelectAnimationEvent(animEvent); + } + } + + public static void OnSelectAnimationEvent(AnimationEventBase animEvent) + { + m_CurAnimationEvent = animEvent; + if(animEvent != null) + { + EventEditWindow = EditorWindow.GetWindow(true); + } + } + + public static void DeleteEvent(AnimationEventBase animEvent) + { + if (animationData == null) + return; + animationData.DeleteEvent(animEvent); + } + + public static void EditRootMotionOverrideData() + { + RootMotionEditor = EditorWindow.GetWindow(true); + } + + public static void CopyAnimationEvent(AnimationEventBase animEvent) + { + copiedAnimationEvent = UnityEngine.Object.Instantiate(animEvent); + } + + public static void ResetUnitRootPosAndRot() + { + unitRoot.transform.position = s_InitPosition; + unitRoot.transform.rotation = s_InitRotation; + } + + } +} \ No newline at end of file -- cgit v1.1-26-g67d0