using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; namespace ActionTool { public struct BoxParam { public ColliderData collider; public int frame; } public class ActionPreviewEditor : EditorWindow { Texture m_UITextureStop; Texture m_UITexturePause; Texture m_UITexturePlay; Texture m_UITextureNext; Texture m_UITextureEnd; Texture m_UITexturePrevious; Texture m_UITextureStart; Texture m_UITextureNewHurtBox; Texture m_UITextureNewHitBox; GUIStyle m_StyleBold; const float kToolbarControlMargin = 5; const float kToolbarHeight = 50; const float kToolbarControlSize = kToolbarHeight - kToolbarControlMargin * 2; const float kTimeLineViewXOffset = 30; const float kFrameWidth = 10; const float kFrameHeight = 20; float m_GridY = 0; ActionEditorStyles styles; ActionEditorUI ui; private void OnEnable() { titleContent = new GUIContent("Action Preview"); m_UITextureStop = (Texture)Resources.Load("button_control_stop"); m_UITexturePause = (Texture)Resources.Load("button_control_pause"); m_UITexturePlay = (Texture)Resources.Load("button_control_play"); m_UITextureNext = (Texture)Resources.Load("button_control_next"); m_UITextureEnd = (Texture)Resources.Load("button_control_end"); m_UITexturePrevious = (Texture)Resources.Load("button_control_previous"); m_UITextureStart = (Texture)Resources.Load("button_control_start"); m_UITextureNewHurtBox = (Texture)Resources.Load("hurtbox"); m_UITextureNewHitBox = (Texture)Resources.Load("hitbox"); } void Update() { ActionManager.UpdateFrame(); } private void OnDisable() { ActionManager.PreviewWindow = null; } private void OnGUI() { styles = ActionEditorStyles.Get(); if (ActionManager.CurrentAnimationName == null || ActionManager.CurrentAnimationName == "") { EditorGUILayout.HelpBox("选择动画", MessageType.Warning); return; } if (styles == null) styles = ActionEditorStyles.Get(); if (ui == null) ui = ActionEditorUI.Get(); GUI_Toolbar(); GUI_Detail(); GUI_TimeLineView(); } void GUI_Toolbar() { float x = 0, y = kToolbarControlMargin; GUI_Toolbar_BG(); GUI_Toolbar_Start(ref x, ref y); GUI_Toolbar_Previous(ref x, ref y); GUI_Toolbar_Stop(ref x, ref y); GUI_Toolbar_Pause(ref x, ref y); GUI_Toolbar_Next(ref x, ref y); GUI_Toolbar_End(ref x, ref y); GUI_DrawSeperateLine(x + 10 + kToolbarControlMargin, 0, kToolbarHeight); x += 20; 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); x += 20; GUI.enabled = ActionManager.animationData == null; GUI_Toolbar_NewAnimationData(ref x, ref y); GUI.enabled = true; GUI.enabled = ActionManager.animationData != null; GUI_Toolbar_Save(ref x, ref y); GUI.enabled = true; } void GUI_Toolbar_BG() { GUI.DrawTexture(new Rect(0, 0, position.width, 50), EditorStyles.toolbar.normal.background); } void GUI_Toolbar_Start(ref float x, ref float y) { x += kToolbarControlMargin; Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); if(GUI.Button(rect, m_UITextureStart)) { ActionManager.Start(); } x += kToolbarControlSize; } void GUI_Toolbar_Previous(ref float x, ref float y) { x += kToolbarControlMargin; Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); if (GUI.Button(rect, m_UITexturePrevious)) { ActionManager.Previous(); } x += kToolbarControlSize; } void GUI_Toolbar_Stop(ref float x, ref float y) { x += kToolbarControlMargin; Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); if (GUI.Button(rect, m_UITextureStop)) { ActionManager.Stop(); } x += kToolbarControlSize; } void GUI_Toolbar_Pause(ref float x, ref float y) { x += kToolbarControlMargin; Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); Texture tex = ActionManager.IsPlay ? m_UITexturePlay : m_UITexturePause; if (GUI.Button(rect, tex)) { ActionManager.Pause(); } x += kToolbarControlSize; } void GUI_Toolbar_Next(ref float x, ref float y) { x += kToolbarControlMargin; Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); if (GUI.Button(rect, m_UITextureNext)) { ActionManager.Next(); } x += kToolbarControlSize; } void GUI_Toolbar_End(ref float x, ref float y) { x += kToolbarControlMargin; Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); if (GUI.Button(rect, m_UITextureEnd)) { ActionManager.End(); } x += kToolbarControlSize; } void GUI_Detail() { float y = kToolbarHeight + 5; float x = 5; GUI.Label(new Rect(x, y, 105, 20), "Animation Name:"); x += 105; GUI.Label(new Rect(x, y, 210, 20), ActionManager.CurrentAnimationName, styles.textBold); x += 200; } void GUI_TimeLineView() { if (ActionManager.actionData == null) return; float y = 80; GUI_FrameText(ref y); GUI_Slider(ref y); GUI_Grid(ref y); GUI_Events(); GUI_Boxes(); GUI_FrameLine(); } void GUI_FrameText(ref float y) { ActionData action = ActionManager.actionData; int sampleCount = (int)action.totalFrame + 1; Rect rect = new Rect(0, y, 20, 15); for(int i = 0; i < sampleCount; i++) { rect.x = kTimeLineViewXOffset + i * kFrameWidth - ((i >= 10) ? 7 : 5); if(i % 5 == 0) { Color c = GUI.color; GUI.color = i % 10 == 0 ? Color.yellow : GUI.color; GUI.Label(rect, i.ToString(), styles.textSmall); GUI.color = c; } } y += 11; } void GUI_Slider( ref float y) { ActionData action = ActionManager.actionData; Rect rect = new Rect(kTimeLineViewXOffset - 4, y, action.totalFrame * kFrameWidth + 7, 15); float t = GUI.HorizontalSlider(rect,action.curAnimTimeNormal, 0, 1); if(t != action.curAnimTimeNormal) { if(ActionManager.IsPlay) ActionManager.Pause(); action.curAnimTimeNormal = t; } if(ActionManager.IsPlay) { this.Repaint(); } y += 20; } void GUI_Grid(ref float y) { m_GridY = y; ActionData action = ActionManager.actionData; int sampleCount = (int)action.totalFrame + 1; Rect bgRect = new Rect(kTimeLineViewXOffset, y, action.totalFrame * kFrameWidth, ActionManager.eventAndBoxCount * kFrameHeight); GUI.Box(bgRect, ""); Color lineColor = new Color(0.3f, 0.3f, 0.3f); Color lineColor2 = new Color(0.5f, 0.5f, 0.5f); for (int i = 0; i < ActionManager.eventAndBoxCount + 1; i++) { ui.DrawHorizontalLineFast(y + i * kFrameHeight, kTimeLineViewXOffset, kTimeLineViewXOffset + action.totalFrame * kFrameWidth, lineColor); } for(int i = 0; i <= sampleCount; ++i) { Color c = i % 5 == 0 ? lineColor2 : lineColor; float x = kTimeLineViewXOffset + i * kFrameWidth; x = Mathf.Clamp(x, kTimeLineViewXOffset, kTimeLineViewXOffset + action.totalFrame * kFrameWidth); ui.DrawVerticalLineFast(x, y, y + ActionManager.eventAndBoxCount * kFrameHeight, c); } 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); ui.DrawVerticalLineFast(kTimeLineViewXOffset + bgRect.width * action.curAnimTimeNormal, y, y + ActionManager.eventAndBoxCount * kFrameHeight, Color.red); } 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 DrawBox(int index, ColliderData box, float y, Color c) { ActionData action = ActionManager.actionData; Color prevColor = GUI.backgroundColor; GUI.backgroundColor = c; Rect rect = new Rect(kTimeLineViewXOffset - 17, y - 1, 17, kFrameHeight); bool selected = ActionManager.colliderData == box; bool select = GUI.Toggle(rect, selected, index.ToString(), styles.boxToggle); GUI.backgroundColor = prevColor; prevColor = GUI.color; GUI.color = c; if (select) { ActionManager.OnSelectBox(box); //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); } 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); float animFrame = action.curAnimFrame; Color col = c * 0.4f; //if (ActionManager.IsPlay) //{ bool highlight = action.curAnimFrame >= prevIndex && action.curAnimFrame < frameIndex; col = highlight ? c * 0.6f : c * 0.4f; //} EditorGUI.DrawRect(region, col); } 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 _newFrameMenu = new GenericMenu(); _newFrameMenu.AddItem(new GUIContent("New Frame"), false, ActionManager.AddNewBoxFrame, param); _newFrameMenu.AddItem(new GUIContent("Delete"), false, ActionManager.DeleteBoxFrame, param); _newFrameMenu.ShowAsContext(); } else { Debug.LogError("[ActionTool] 错误的点击"); } } void GUI_DrawSeperateLine(float x, float y, float height) { ui.defaultUIMaterail.SetPass(0); Color lineColor = new Color(0.3f, 0.3f, 0.3f); Color lineColor2 = new Color(0.1f, 0.1f, 0.1f); ui.DrawVerticalLineFast(x, y, y +height, lineColor2); ui.DrawVerticalLineFast(x+1, y, y +height, lineColor); } 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; Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); if (GUI.Button(rect, new GUIContent("New"))) { ActionManager.CreateAnimationData(); } x += kToolbarControlSize; } void GUI_Toolbar_Save(ref float x, ref float y) { x += kToolbarControlMargin; Rect rect = new Rect(x, y, kToolbarControlSize, kToolbarControlSize); if (GUI.Button(rect, new GUIContent("Save"))) { ActionManager.SaveAnimationData(); } x += kToolbarControlSize; } } }