diff options
Diffstat (limited to 'Assets/Tools/ActionTool/Editor/ActionManager.cs')
-rw-r--r-- | Assets/Tools/ActionTool/Editor/ActionManager.cs | 548 |
1 files changed, 548 insertions, 0 deletions
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<ActionPreviewEditor>();
+ 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>(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<AnimationData>(animationDataPath);
+ m_SharedAnimationData = asset;
+ if(asset != null)
+ animationData = UnityEngine.Object.Instantiate<AnimationData>(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<Animator>();
+ 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<ActionToolGizmos>();
+ s_Gizmos.Initialize(unitRoot);
+
+ Settings = AssetDatabase.LoadAssetAtPath<ActionToolSettings>(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<AnimationData>(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<ActionColliderEditor>(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<ActionColliderFrameEditor>(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<ActionEventEditor>(true);
+ }
+ }
+
+ public static void DeleteEvent(AnimationEventBase animEvent)
+ {
+ if (animationData == null)
+ return;
+ animationData.DeleteEvent(animEvent);
+ }
+
+ public static void EditRootMotionOverrideData()
+ {
+ RootMotionEditor = EditorWindow.GetWindow<ActionRootMotionEditor>(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 |