From 26e4dc3a35d9c778684388de1af8b3f288fe627d Mon Sep 17 00:00:00 2001 From: chai Date: Fri, 28 May 2021 20:00:48 +0800 Subject: *Tween --- .../Tween/Editor/TweenAnimationInspector.cs | 421 +++++++++++++++++++-- 1 file changed, 396 insertions(+), 25 deletions(-) (limited to 'Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector.cs') diff --git a/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector.cs b/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector.cs index c4267b9..cc57055 100644 --- a/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector.cs +++ b/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector.cs @@ -36,10 +36,35 @@ namespace TweenAnimation static string[] s_TweenModuleClassNames; static Dictionary s_TweenModuleGUI; + static int s_ModuleTabHash = "TweenModuleTab".GetHashCode(); + static int s_ModuleEnabledHash = "TweenModuleEnabled".GetHashCode(); + + // 是否在时间轴上显示 + bool m_ShowEvents; + bool m_ShowModules; + + bool m_Play; + bool m_Pause; + bool m_Stop; + + HashSet m_EventTimeSet; + float m_SelectedEventTime; + public void OnEnable() { + if(s_TweenModuleGUI == null) + s_TweenModuleGUI = new Dictionary(); + m_ShowAnimationTab = true; - s_TweenModuleGUI = new Dictionary(); + + m_ShowEvents = true; + m_ShowModules = true; + + if (m_EventTimeSet == null) + m_EventTimeSet = new HashSet(); + m_EventTimeSet.Clear(); + + m_SelectedEventTime = -1; } public override void OnInspectorGUI() @@ -48,6 +73,8 @@ namespace TweenAnimation if (animation == null) return; + this.serializedObject.Update(); + EditorGUILayout.Space(); AnimationTab(); @@ -55,6 +82,8 @@ namespace TweenAnimation AnimationModules(); EditorGUILayout.Space(); + + serializedObject.ApplyModifiedProperties(); } void AnimationTab() @@ -72,7 +101,7 @@ namespace TweenAnimation GUI.Label(new Rect(rect.x + 10, rect.y + 3, 100, 20), "Tween Animation", styles.headerTitle); Vector2 size = styles.text.CalcSize(new GUIContent(animation.description)); GUI.Label(new Rect(rect.x + rect.width - size.x - 10, rect.y + 3, 100, 20), animation.description, styles.text); - + if (m_ShowAnimationTab) { animation.description = ui.GUIText("Description", animation.description); @@ -94,7 +123,21 @@ namespace TweenAnimation // 事件触发方向 animation.eventTriggeredDirection = (TweenAnimation.EventTriggeredDirection)ui.GUIEnumMask("Event Direction", animation.eventTriggeredDirection); + + // 是否只触发一次 + animation.triggerOnce = ui.GUIToggle("Trigger Once", animation.triggerOnce); + + // ITweenEventHandler + animation.scriptHandler = ui.GUIToggle("Event Handler", animation.scriptHandler); + + GUILayout.Space(5); + + // 时间轴 + DrawRuler(1f, true); + + EventList(); } + DrawBgWire(rect, (m_ShowAnimationTab ? 4 : -2)); if(!m_ShowAnimationTab) GUILayout.Space(-4); @@ -107,8 +150,8 @@ namespace TweenAnimation Rect rect = ui.GetControlRect(20); Rect labelRect = rect; - labelRect.y += 2; - GUI.Label(labelRect, "Modules ", styles.text); + labelRect.y += 1; + GUI.Label(labelRect, "Modules ", styles.textBold); rect.x = rect.x + rect.width - 15; rect.width = 20; @@ -173,33 +216,31 @@ namespace TweenAnimation bool enabled = module.enabled; // header Rect rect = ui.GetControlRect(20); - - if (Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseUp) + Rect checkRect = rect; + checkRect.x += 1; + checkRect.y += 1; + checkRect.width = 20; + checkRect.height = 20; + Rect headerRect = rect; + headerRect.x -= 2; + headerRect.width += 8; + Rect deleteRect = rect; + deleteRect.x = rect.x + rect.width - 18; + deleteRect.width = 20; + deleteRect.height = 20; + if (Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseUp || Event.current.type == EventType.Layout) { - Rect checkRect = rect; - checkRect.x += 1; - checkRect.y += 1; - checkRect.width = 20; - checkRect.height = 20; - module.enabled = GUI.Toggle(checkRect, enabled, "", styles.checkmark); - Rect headerRect = rect; - headerRect.x -= 2; - headerRect.width += 8; + module.enabled = GUI.Toggle(checkRect, module.enabled, "", styles.checkmark); + if (GUI.Button(deleteRect, "-", styles.textBoldBig)) + animation.RemoveModule(module); if (GUI.Button(headerRect, "", styles.headerBg)) module.unfold = !module.unfold; } - else if(Event.current.type == EventType.Repaint || Event.current.type == EventType.Layout) + else if (Event.current.type == EventType.Repaint /*|| Event.current.type == EventType.Layout*/) { - Rect headerRect = rect; - headerRect.x -= 2; - headerRect.width += 8; GUI.Button(headerRect, "", styles.headerBg); - Rect checkRect = rect; - checkRect.x += 1; - checkRect.y += 1; - checkRect.width = 20; - checkRect.height = 20; GUI.Toggle(checkRect, enabled, "", styles.checkmark); + GUI.Button(deleteRect, "-", styles.textBoldBig); } Vector2 size = styles.text.CalcSize(new GUIContent(name)); @@ -208,6 +249,7 @@ namespace TweenAnimation // content if (module.unfold) { + GUILayout.Space(-3); MethodInfo method; string classname = module.GetType().Name; if (!s_TweenModuleGUI.TryGetValue(classname, out method)) @@ -250,9 +292,338 @@ namespace TweenAnimation } // 绘制时间轴 - void DrawRuler() + void DrawRuler(float alpha, bool bLabels) + { + if (animation.duration <= 0) + return; + + float duration = animation.duration; + Rect timelineRect = ui.GetControlRect(110); + + bool bRepaint = Event.current.type == EventType.Repaint; + + GUI.BeginGroup(timelineRect); + + // draw ruler + Rect rulerRect = new Rect(5, 5, timelineRect.width - 10, 60); + + Rect bgRect = rulerRect; + EditorGUI.DrawRect(bgRect, new Color(1, 1, 1, 1f) * 0.7f); + + int rulerWidth = (int)rulerRect.width; + styles.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(rulerRect.x, 0, rulerRect.height, Color.red); + //ui.DrawVerticalLineFast(rulerRect.x + rulerRect.width, 0, rulerRect.height, Color.red); + //ui.DrawHorizontalLineFast(rulerRect.y, rulerRect.x, rulerRect.x + rulerRect.width, Color.blue); + //ui.DrawHorizontalLineFast(rulerRect.y + rulerRect.height, rulerRect.x, rulerRect.x + rulerRect.width, Color.blue); + + int yOffBase = (int)rulerRect.height + (int)rulerRect.y; + if (bRepaint) + ui.DrawHorizontalLineFast(yOffBase, rulerRect.x, rulerRect.x + rulerRect.width, Color.gray); + + int log = (int)Mathf.Floor(Mathf.Log10(duration)) ; + float stepCount; + int stepSlice = 5; // 每个stepBig分为几个小step + do + { + float stepBig = Mathf.Pow(10, log); + float stepSmall = stepBig / stepSlice; + stepCount = duration / stepSmall; + log--; + stepSlice *= 2; + } while (stepCount < 20); + log++; + stepSlice /= 2; + + int j = 1; + while (stepCount > 30) + { + float stepBig = Mathf.Pow(10, log) * j * 2; + float stepSmall = stepBig / stepSlice; + stepCount = duration / stepSmall; + ++j; + //Debug.Log("stepBig=" + stepBig + ",stepSmall=" + stepSmall); + } + + float stepPixelWidth = rulerWidth / stepCount; + float timePerStep = duration / stepCount; + + if(bRepaint) + { + for (int i = 0; i <= stepCount; ++i) + { + int len = 15; + if (i % stepSlice == 0) + len = 30; + ui.DrawVerticalLineFast(rulerRect.x + i * stepPixelWidth, yOffBase, yOffBase - len, Color.gray); + } + } + + // 绘制事件的竖线 + //if (bRepaint && m_ShowEvents && animation.eventList != null) + //{ + // m_EventTimeSet.Clear(); + // for (int i = 0; i < animation.eventList.Count; ++i) + // { + // TweenEvent e = animation.eventList[i]; + // if (e != null) + // { + // if (!m_EventTimeSet.Contains(e.time)) + // m_EventTimeSet.Add(e.time); + // } + // } + // float y = rulerRect.y + 3; + // Rect eventRect = new Rect(0, y, 15, 15); + // foreach (float time in m_EventTimeSet) + // { + // float x = time / duration * rulerWidth; + // eventRect.x = x + 5; + // ui.DrawVerticalLineFast(eventRect.x, yOffBase, yOffBase - 50, Color.gray); + // } + //} + + // 绘制module时间 + if(m_ShowModules && bRepaint) + { + int xStart = 5; + int yStart = 25; + for(int i = 0; i < animation.modules.Count; ++i) + { + TweenModule module = animation.modules[i]; + if(module.unfold) + { + float left = module.timeOffset / duration * rulerRect.width; + float right = (module.timeOffset + module.duration) / duration * rulerRect.width; + left = Mathf.Clamp(left, 0, rulerRect.width) + xStart; + right = Mathf.Clamp(right, 0, rulerRect.width) + xStart; + ui.DrawHorizontalLineFast(yStart + (rulerRect.height - 20) / animation.modules.Count * i, left, right, Color.white); + } + } + } + + GL.PopMatrix(); + GL.End(); + + // draw labels + if(bLabels) + { + for (int i = 0; i <= stepCount; ++i) + { + if (i % stepSlice == 0 || stepSlice == 10 && i % (stepSlice / 2) == 0) + { + float time = i * timePerStep; // sec + Vector2 size = styles.text.CalcSize(new GUIContent(time.ToString("f2"))); + GUI.Label(new Rect(rulerRect.x + i * stepPixelWidth - size.x / 2, yOffBase + 2, 50, 15), time.ToString("f2"), styles.text ); + } + } + } + + // draw events + if(m_ShowEvents && animation.eventList != null) + { + m_EventTimeSet.Clear(); + for (int i = 0; i < animation.eventList.Count; ++i) + { + TweenEvent e = animation.eventList[i]; + if(e != null) + { + if(!m_EventTimeSet.Contains(e.time)) + m_EventTimeSet.Add(e.time); + } + } + float y = rulerRect.y - 1; + Rect eventRect = new Rect(0, y, 15, 15); + foreach (float time in m_EventTimeSet) + { + float x = time / duration * rulerWidth - 15 / 4; + eventRect.x = x; + if (GUI.Button(eventRect, TweenModuleGUIStyles.eventIcon, styles.text)) + { + m_SelectedEventTime = time; + } + ui.DrawVerticalLineFast(eventRect.x, yOffBase, yOffBase - eventRect.y, Color.gray); + } + } + + // buttons + + // 控制时间轴显示 + { + Rect buttonRect = new Rect(5 + rulerRect.width - 20 * 2, yOffBase + 20, 20, 20); + Color pressedColor = Color.gray; + + Rect eventRect = buttonRect; + Color col = GUI.color; + if (m_ShowEvents) + GUI.color = pressedColor; + if (GUI.Button(eventRect, TweenModuleGUIStyles.eventIcon, EditorStyles.miniButtonLeft)) + { + m_ShowEvents = !m_ShowEvents; + if (!m_ShowEvents) + m_SelectedEventTime = -1; + } + GUI.color = col; + + Rect moduleRect = buttonRect; + moduleRect.x += 20; + col = GUI.color; + if (m_ShowModules) + GUI.color = pressedColor; + if (GUI.Button(moduleRect, TweenModuleGUIStyles.moduleIcon, EditorStyles.miniButtonRight)) + m_ShowModules = !m_ShowModules; + GUI.color = col; + } + + // 播放、暂停等 + { + Rect buttonRect = new Rect(5 , yOffBase + 20, 30, 20); + Rect eventRect = buttonRect; + Color pressedColor = Color.gray; + + Rect playRect = buttonRect; + Color col = GUI.color; + if (m_Play) + GUI.color = pressedColor; + if (GUI.Button(eventRect, "Play", styles.miniLeft)) + { + m_Play = !m_Play; + if(m_Play) + { + m_Pause = m_Stop = false; + EditorPlay(); + } + } + GUI.color = col; + + Rect pauseRect = buttonRect; + pauseRect.x += buttonRect.width; + col = GUI.color; + if (m_Pause) + GUI.color = pressedColor; + if (GUI.Button(pauseRect, "Pause", styles.miniMid)) + { + m_Pause = !m_Pause; + if (m_Pause) + m_Play = m_Stop = false; + } + GUI.color = col; + + Rect stopRect = buttonRect; + stopRect.x += 2 * buttonRect.width; + if (GUI.Button(stopRect, "Stop", styles.miniRight)) + { + EditorStop(); + m_Pause = m_Play = false; + } + } + + GUI.EndGroup(); + } + + void EventList() + { + Rect evetRect = ui.GetControlRect(15); + + Rect labelRect = evetRect; + labelRect.x += 2; + GUI.Label(labelRect, "Events", styles.textBold); + + Rect addButton = evetRect; + addButton.x = evetRect.x + evetRect.width - 20; + if(GUI.Button(addButton, "+", styles.textBoldBig)) + { + animation.AddEvent(new TweenEvent()); + } + + if (animation.eventList == null || animation.eventList.Count == 0) + return; + + for(int i = 0; i < animation.eventList.Count; ++i) + { + DrawEvent(animation.eventList[i], i); + } + } + + void DrawEvent (TweenEvent e, int index) { + Rect rect = ui.GetControlRect(15); + + // delete button + Rect deleteButton = rect; + deleteButton.x += 5; + deleteButton.width = 10; + deleteButton.y -= 2; + if (GUI.Button(deleteButton, "-", styles.textBoldBig)) + { + animation.RemoveEvent(e); + return; + } + + // event time + Rect timeLabelRect = rect; + timeLabelRect.x += 25; + timeLabelRect.width = 30; + timeLabelRect.height = 13; + GUI.Label(timeLabelRect, "time:", e.time == m_SelectedEventTime ? styles.textBold : styles.text); + Rect timeRect = timeLabelRect; + timeRect.x += 25; + float time = EditorGUI.FloatField(timeRect, e.time, styles.floatfiled); + time = Mathf.Clamp(time, 0, float.MaxValue); + e.time = time; + // event name + Rect nameLabelRect = rect; + nameLabelRect.x += 150; + nameLabelRect.width = 100; + nameLabelRect.height = 13; + GUI.Label(nameLabelRect, "name:", styles.text); + Rect nameRect = nameLabelRect; + nameRect.x += 32; + e.name = EditorGUI.TextField(nameRect, e.name, styles.textField); + + // 折叠 + Rect unfoldRect = rect; + unfoldRect.x = rect.x + rect.width - 19; + unfoldRect.width = 13; + unfoldRect.height = 13; + e.unfold = GUI.Button(unfoldRect, (e.unfold ? "▲" : "▼"), styles.textSmall) ? !e.unfold : e.unfold; + if(e.unfold) + { + SerializedProperty eventHandler = null; + SerializedProperty list = serializedObject.FindProperty("eventList"); + for (int i = 0; i < list.arraySize; ++i) + { + if (i != index) + continue; + SerializedProperty ent = list.GetArrayElementAtIndex(i); + if (ent != null) + { + foreach(var property in ent) + { + SerializedProperty prop = property as SerializedProperty; + if(prop != null && prop.name == "eventHandler") + { + eventHandler = prop; + break; + } + } + } + break; + } + + if(eventHandler != null) + { + EditorGUILayout.PropertyField(eventHandler); + } + } } } -- cgit v1.1-26-g67d0