From 172d4723c7405d2e748ed03267ca10be9711212b Mon Sep 17 00:00:00 2001 From: chai Date: Fri, 9 Jul 2021 19:17:38 +0800 Subject: *misc --- Assets/ActionTool/Editor/ActionColliderEditor.cs | 52 ++++++ Assets/ActionTool/Editor/ActionEditorStyles.cs | 12 ++ Assets/ActionTool/Editor/ActionManager.cs | 89 +++++++++ Assets/ActionTool/Editor/ActionPreviewEditor.cs | 219 ++++++++++++++++++++--- Assets/Data/AnimationData/Erika/Take 001.asset | 44 ++++- Assets/Scripts/Unit/AnimationData.cs | 44 +++++ Assets/Scripts/Unit/Collider/ColliderData.cs | 63 ++++++- 7 files changed, 495 insertions(+), 28 deletions(-) (limited to 'Assets') diff --git a/Assets/ActionTool/Editor/ActionColliderEditor.cs b/Assets/ActionTool/Editor/ActionColliderEditor.cs index e28798f1..57c060fa 100644 --- a/Assets/ActionTool/Editor/ActionColliderEditor.cs +++ b/Assets/ActionTool/Editor/ActionColliderEditor.cs @@ -6,7 +6,59 @@ using UnityEditor; namespace ActionTool { + // 编辑collider帧 public class ActionColliderEditor : EditorWindow { + + private void OnEnable() + { + titleContent = new GUIContent("Collider Editor"); + } + + private void OnDisable() + { + ActionManager.OnSelectColliderFrame(null); + } + + private void OnGUI() + { + var frame = ActionManager.editColliderFrame; + if (frame == null) + { + this.Close(); + return; + } + + Rect pos = position; + pos.width = 300; + pos.height = 150; + position = pos; + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("frame: "); + EditorGUILayout.LabelField(frame.frame.ToString()); + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("active: "); + frame.active = EditorGUILayout.Toggle(frame.active); + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.LabelField("position: "); + frame.position = EditorGUILayout.Vector3Field("", frame.position); + + EditorGUILayout.LabelField("size: "); + frame.size = EditorGUILayout.Vector3Field("", frame.size); + + GUILayout.Space(10); + + Color prevColor = GUI.color; + GUI.color = Color.red; + if (GUILayout.Button("Delete")) + { + ActionManager.DeleteCurFrame(); + } + GUI.color = prevColor; + } } } \ No newline at end of file diff --git a/Assets/ActionTool/Editor/ActionEditorStyles.cs b/Assets/ActionTool/Editor/ActionEditorStyles.cs index 664753ef..fbc543ae 100644 --- a/Assets/ActionTool/Editor/ActionEditorStyles.cs +++ b/Assets/ActionTool/Editor/ActionEditorStyles.cs @@ -10,6 +10,8 @@ namespace ActionTool public GUIStyle textBold; public GUIStyle selectObj; public GUIStyle textSmall; + public GUIStyle boxToggle; + public GUIStyle keyFrameButton; Texture2D m_SelectIcon; @@ -42,6 +44,16 @@ namespace ActionTool InitStyle(out textSmall, GUI.skin.label, s => { s.fontSize = 8; }); + InitStyle(out boxToggle, GUI.skin.button, s => { + s.fontSize = 8; + s.normal.textColor = Color.white; + s.normal.background = null; + s.active.textColor = Color.white; + s.active.background = null; + }); + InitStyle(out keyFrameButton, GUI.skin.button, s => { + s.fontSize = 8; + }); } private delegate void Initter(GUIStyle style); diff --git a/Assets/ActionTool/Editor/ActionManager.cs b/Assets/ActionTool/Editor/ActionManager.cs index d147b0d6..08fc8383 100644 --- a/Assets/ActionTool/Editor/ActionManager.cs +++ b/Assets/ActionTool/Editor/ActionManager.cs @@ -56,6 +56,12 @@ namespace ActionTool private static AnimationData s_AnimationData; public static AnimationData animationData { get { return s_AnimationData; } } + 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; } } @@ -141,6 +147,8 @@ namespace ActionTool if (s_RootActionTool) GameObject.DestroyImmediate(s_RootActionTool); s_CurActionData = null; + s_CurEditColliderFrame = null; + s_CurColliderData = null; } private static void InitializeUnitInstance(GameObject unit) @@ -263,5 +271,86 @@ namespace ActionTool AssetDatabase.Refresh(); } + public static void NewHurtBox() + { + if (s_AnimationData == null) + { + Debug.LogError("[ActionTool] 没有animation data数据"); + return; + } + ColliderData box = new ColliderData(ColliderBox.EColliderType.HurtBox, ColliderBox.Pivot.MiddleBottom); + s_AnimationData.AddBox(s_AnimationData.hurtBoxes, box); + } + + public static void NewHitBox() + { + if (s_AnimationData == null) + { + Debug.LogError("[ActionTool] 没有animation data数据"); + return; + } + ColliderData box = new ColliderData(ColliderBox.EColliderType.HitBox, ColliderBox.Pivot.MiddleCenter); + s_AnimationData.AddBox(s_AnimationData.hitBoxes, box); + } + + public static void DeleteCurBox() + { + if(s_AnimationData != null && s_CurColliderData != null) + { + s_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) + { + data.AddFrame(frameIndex); + } + } + + 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; + ColliderWindow = EditorWindow.GetWindow(true); + + if(frame != null) + { + ActionData action = ActionManager.actionData; + float normaltime = frame.frame / action.totalFrame; + action.curAnimTimeNormal = normaltime; + } + } + } } \ No newline at end of file diff --git a/Assets/ActionTool/Editor/ActionPreviewEditor.cs b/Assets/ActionTool/Editor/ActionPreviewEditor.cs index faad376c..858b28e2 100644 --- a/Assets/ActionTool/Editor/ActionPreviewEditor.cs +++ b/Assets/ActionTool/Editor/ActionPreviewEditor.cs @@ -6,6 +6,12 @@ using UnityEditor; namespace ActionTool { + public struct BoxParam + { + public ColliderData collider; + public int frame; + } + public class ActionPreviewEditor : EditorWindow { Texture m_UITextureStop; @@ -27,6 +33,8 @@ namespace ActionTool const float kFrameWidth = 10; const float kFrameHeight = 20; + float m_GridY = 0; + ActionEditorStyles styles; ActionEditorUI ui; @@ -90,6 +98,7 @@ namespace ActionTool GUI.enabled = ActionManager.animationData != null; GUI_Toolbar_NewHurtBox(ref x, ref y); GUI_Toolbar_NewHitBox(ref x, ref y); + GUI_Toolbar_Delete(ref x, ref y); GUI.enabled = true; GUI_DrawSeperateLine(x + 10 + kToolbarControlMargin, 0, kToolbarHeight); @@ -176,28 +185,6 @@ namespace ActionTool x += kToolbarControlSize; } - void GUI_Toolbar_NewHurtBox(ref float x,ref float y) - { - x += kToolbarControlMargin; - Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); - if (GUI.Button(rect, new GUIContent("New", m_UITextureNewHurtBox))) - { - ActionManager.End(); - } - x += kToolbarControlSize; - } - - void GUI_Toolbar_NewHitBox(ref float x, ref float y) - { - x += kToolbarControlMargin; - Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); - if (GUI.Button(rect, new GUIContent("New", m_UITextureNewHitBox))) - { - ActionManager.End(); - } - x += kToolbarControlSize; - } - void GUI_Detail() { float y = kToolbarHeight + 5; @@ -219,7 +206,9 @@ namespace ActionTool GUI_FrameText(ref y); GUI_Slider(ref y); GUI_Grid(ref y); - GUI_Events(ref y); + GUI_Events(); + GUI_Boxes(); + GUI_FrameLine(); } void GUI_FrameText(ref float y) @@ -263,6 +252,8 @@ namespace ActionTool void GUI_Grid(ref float y) { + m_GridY = y; + ActionData action = ActionManager.actionData; int sampleCount = (int)action.totalFrame + 1; @@ -290,18 +281,161 @@ namespace ActionTool x = Mathf.Clamp(x, kTimeLineViewXOffset, kTimeLineViewXOffset + action.totalFrame * kFrameWidth); ui.DrawVerticalLineFast(x, y, y + ActionManager.eventAndBoxCount * kFrameHeight, c); } + GL.PopMatrix(); + GL.End(); + + y += ActionManager.eventAndBoxCount * kFrameHeight; + } + + void GUI_FrameLine() + { + float y = m_GridY; + ActionData action = ActionManager.actionData; + Rect bgRect = new Rect(kTimeLineViewXOffset, y, action.totalFrame * kFrameWidth, ActionManager.eventAndBoxCount * kFrameHeight); + ui.defaultUIMaterail.SetPass(0); + GL.PushMatrix(); + GL.LoadPixelMatrix(); + bool bWin = Application.platform == RuntimePlatform.WindowsEditor; + if (bWin) + GL.Begin(GL.QUADS); + else + GL.Begin(GL.LINES); ui.DrawVerticalLineFast(kTimeLineViewXOffset + bgRect.width * action.curAnimTimeNormal, y, y + ActionManager.eventAndBoxCount * kFrameHeight, Color.red); GL.PopMatrix(); GL.End(); + } - y += ActionManager.eventAndBoxCount * kFrameHeight; + void GUI_Events() + { + + } + + void GUI_Boxes() + { + float y = m_GridY + ActionManager.kMaxEventsPerFrame * kFrameHeight; + AnimationData animData = ActionManager.animationData; + if (animData == null) + return; + DrawBoxList(animData.hurtBoxes, ref y, Color.green); + DrawBoxList(animData.hitBoxes, ref y, Color.red); + DrawBoxFrameMenuItem(); + } + + void DrawBoxList(List boxes, ref float y, Color c) + { + if (boxes == null || boxes.Count == 0) + return; + int count = boxes.Count; + for(int i = 0; i < boxes.Count; ++i) + { + DrawBox(i, boxes[i], y + i * kFrameHeight, c); + } + y += count * kFrameHeight; } - void GUI_Events(ref float y) + void DrawBox(int index, ColliderData box, float y, Color c) { + ActionData action = ActionManager.actionData; + Color prevColor = GUI.color; + GUI.color = c; + Rect rect = new Rect(kTimeLineViewXOffset - 18, y - 1, 17, kFrameHeight); + bool selected = ActionManager.colliderData == box; + bool select = GUI.Toggle(rect, selected, index.ToString(), styles.boxToggle); + if (select) + { + ActionManager.OnSelectBox(box); + + ui.defaultUIMaterail.SetPass(0); + GL.PushMatrix(); + GL.LoadPixelMatrix(); + bool bWin = Application.platform == RuntimePlatform.WindowsEditor; + if (bWin) + GL.Begin(GL.QUADS); + else + GL.Begin(GL.LINES); + float length = action.totalFrame * kFrameWidth; + ui.DrawHorizontalLineFast(y, kTimeLineViewXOffset, kTimeLineViewXOffset + length, c * 0.7f); + ui.DrawHorizontalLineFast(y + kFrameHeight, kTimeLineViewXOffset, kTimeLineViewXOffset + length, c * 0.7f); + ui.DrawVerticalLineFast(kTimeLineViewXOffset + length + 1, y, y + kFrameHeight, c * 0.7f); + GL.PopMatrix(); + GL.End(); + } + else if(selected && !select) + { + ActionManager.OnSelectBox(null); + } + + if(box.frames != null && box.frames.Count > 0) + { + int prevIndex = -1; + for(int i = 0; i < box.frames.Count; ++i) + { + ColliderData.ColliderFrame frame = box.frames[i]; + int frameIndex = frame.frame; + Vector2 pos = new Vector2(kTimeLineViewXOffset + frameIndex * kFrameWidth, y); + Rect frameRect = new Rect(pos.x, pos.y, kFrameWidth, kFrameHeight); + bool frameSelected = frame == ActionManager.editColliderFrame; + bool frameSelect = GUI.Toggle(frameRect, frameSelected, "",styles.keyFrameButton); + if(!frameSelected && frameSelect) + { + ActionManager.OnSelectBox(box); + ActionManager.OnSelectColliderFrame(frame); + } + else if(frameSelect && !frameSelect) + { + ActionManager.OnSelectColliderFrame(null); + } + if(prevIndex != -1) + { + float length = (frameIndex - prevIndex - 1) * kFrameWidth; + Rect region = new Rect(kTimeLineViewXOffset + (prevIndex + 1) * kFrameWidth, y, length, kFrameHeight); + EditorGUI.DrawRect(region, c * 0.4f); + } + if (frame.active) + prevIndex = frameIndex; + else + prevIndex = -1; + } + } + GUI.color = prevColor; + } + + void DrawBoxFrameMenuItem() + { + Event e = Event.current; + if (e.button != 1 || !e.isMouse || e.type != EventType.MouseDown) + return; + ActionData action = ActionManager.actionData; + float y = m_GridY + ActionManager.kMaxEventsPerFrame * kFrameHeight; + Vector2 position = e.mousePosition; + int boxCount = ActionManager.animationData.GetBoxesCount(); + Rect boxRegion = new Rect(kTimeLineViewXOffset, y, action.totalFrame * kFrameWidth, boxCount * kFrameHeight); + if (!boxRegion.Contains(position)) + return; + // 找到对应的box和帧 + Vector2 pos = new Vector2(position.x - boxRegion.x, position.y - boxRegion.y); + int index = (int)(pos.y / kFrameHeight); + int frame = (int)(pos.x / kFrameWidth); + ColliderData box = ActionManager.animationData.GetColliderByIndex(index); + if(box != null) + { + BoxParam param = new BoxParam(); + param.collider = box; + param.frame = frame; + if(ActionManager.colliderData != box) + ActionManager.OnSelectBox(box); + GenericMenu menu = new GenericMenu(); + menu.AddItem(new GUIContent("New Frame"), false, ActionManager.AddNewBoxFrame, param); + menu.AddItem(new GUIContent("Delete"), false, ActionManager.DeleteBoxFrame, param); + menu.ShowAsContext(); + } + else + { + Debug.LogError("[ActionTool] 错误的点击"); + } } void GUI_DrawSeperateLine(float x, float y, float height) @@ -322,6 +456,41 @@ namespace ActionTool GL.End(); } + void GUI_Toolbar_NewHurtBox(ref float x, ref float y) + { + x += kToolbarControlMargin; + Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); + if (GUI.Button(rect, new GUIContent("New", m_UITextureNewHurtBox))) + { + ActionManager.NewHurtBox(); + } + x += kToolbarControlSize; + } + + void GUI_Toolbar_NewHitBox(ref float x, ref float y) + { + x += kToolbarControlMargin; + Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); + if (GUI.Button(rect, new GUIContent("New", m_UITextureNewHitBox))) + { + ActionManager.NewHitBox(); + } + x += kToolbarControlSize; + } + + void GUI_Toolbar_Delete(ref float x, ref float y) + { + x += kToolbarControlMargin; + Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); + GUI.enabled = ActionManager.colliderData != null; + if (GUI.Button(rect, "Delete")) + { + ActionManager.DeleteCurBox(); + } + GUI.enabled = true; + x += kToolbarControlSize; + } + void GUI_Toolbar_NewAnimationData(ref float x, ref float y) { x += kToolbarControlMargin; diff --git a/Assets/Data/AnimationData/Erika/Take 001.asset b/Assets/Data/AnimationData/Erika/Take 001.asset index 14ff1a35..44378329 100644 --- a/Assets/Data/AnimationData/Erika/Take 001.asset +++ b/Assets/Data/AnimationData/Erika/Take 001.asset @@ -15,8 +15,48 @@ MonoBehaviour: animationName: Take 001 animationPath: Assets/Art/Animations/Erika/Take 001.anim animationEvents: [] - hurtBoxes: [] - hitBoxes: [] + hurtBoxes: + - type: 1 + pivot: 0 + frames: + - frame: 0 + active: 1 + position: {x: 0, y: 0, z: 0} + size: {x: 1, y: 1, z: 1} + - frame: 82 + active: 1 + position: {x: 0, y: 0, z: 0} + size: {x: 1, y: 1, z: 1} + hitBoxes: + - type: 0 + pivot: 1 + frames: + - frame: 23 + active: 1 + position: {x: 0, y: 0, z: 0} + size: {x: 1, y: 1, z: 1} + - type: 0 + pivot: 1 + frames: + - frame: 24 + active: 1 + position: {x: 0, y: 0, z: 0} + size: {x: 1, y: 1, z: 1} + - frame: 37 + active: 1 + position: {x: 0, y: 0, z: 0} + size: {x: 1, y: 1, z: 1} + - type: 0 + pivot: 1 + frames: + - frame: 32 + active: 1 + position: {x: 0, y: 0, z: 0} + size: {x: 1, y: 1, z: 1} + - frame: 37 + active: 1 + position: {x: 0, y: 0, z: 0} + size: {x: 1, y: 1, z: 1} throwBoxes: [] blockBoxes: [] defendBoxes: [] diff --git a/Assets/Scripts/Unit/AnimationData.cs b/Assets/Scripts/Unit/AnimationData.cs index 4ee79cf9..8717cf87 100644 --- a/Assets/Scripts/Unit/AnimationData.cs +++ b/Assets/Scripts/Unit/AnimationData.cs @@ -27,4 +27,48 @@ public class AnimationData : ScriptableObject return hurt + hit + thro + block + defend; } + public void AddBox(List boxList, ColliderData box) + { + if (boxList == null) + { + boxList = new List(); + return; + } + boxList.Add(box); + } + + public void DeleteBox(ColliderData box) + { + if (hurtBoxes != null) hurtBoxes.Remove(box); + if (hitBoxes != null) hitBoxes.Remove(box); + if (throwBoxes != null) throwBoxes.Remove(box); + if (blockBoxes != null) blockBoxes.Remove(box); + if (defendBoxes != null) defendBoxes.Remove(box); + } + + public ColliderData GetColliderByIndex(int index) + { + if (hurtBoxes != null && hurtBoxes.Count > index) + return hurtBoxes[index]; + else + index -= hurtBoxes.Count; + if (hitBoxes != null && hitBoxes.Count > index) + return hitBoxes[index]; + else + index -= hitBoxes.Count; + if (throwBoxes != null && throwBoxes.Count > index) + return throwBoxes[index]; + else + index -= throwBoxes.Count; + if (blockBoxes != null && blockBoxes.Count > index) + return blockBoxes[index]; + else + index -= blockBoxes.Count; + if (defendBoxes != null && defendBoxes.Count > index) + return defendBoxes[index]; + else + index -= defendBoxes.Count; + return null; + } + } diff --git a/Assets/Scripts/Unit/Collider/ColliderData.cs b/Assets/Scripts/Unit/Collider/ColliderData.cs index 744e6a45..b4ae17c5 100644 --- a/Assets/Scripts/Unit/Collider/ColliderData.cs +++ b/Assets/Scripts/Unit/Collider/ColliderData.cs @@ -3,13 +3,20 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; +public struct ColliderInfo +{ + public bool active; + public Vector3 position; + public Vector3 size; +} + [Serializable] public class ColliderData { [Serializable] public class ColliderFrame { - public int frameIndex; + public int frame; public bool active; public Vector3 position; public Vector3 size; @@ -20,4 +27,58 @@ public class ColliderData public ColliderBox.Pivot pivot; public List frames; + + public ColliderData(ColliderBox.EColliderType type, ColliderBox.Pivot pivot) + { + this.type = type; + this.pivot = pivot; + this.frames = new List(); + } + + public ColliderInfo GetColliderInfo() + { + ColliderInfo info = new ColliderInfo(); + + return info; + } + + public void AddFrame(int frameIndex) + { + if (frames == null) + frames = new List(); + ColliderFrame frame = new ColliderFrame(); + frame.frame = frameIndex; + frame.active = true; + frame.position = Vector3.zero; + frame.size = Vector3.one; + frames.Add(frame); + frames.Sort((a, b) => { + if (a == null) + return 1; + if (b == null) + return -1; + if (a.frame < b.frame) + return -1; + if (a.frame > b.frame) + return 1; + return 0; + }); + } + + public void DeleteFrame(int frameIndex) + { + if (frames == null) + return; + ColliderFrame frame = null; + foreach(var f in frames) + { + if (f.frame == frameIndex) + frame = f; + } + if(frame != null) + { + frames.Remove(frame); + } + } + } -- cgit v1.1-26-g67d0