From 654d95efad67a00cb4cffc300419092e9a5093e5 Mon Sep 17 00:00:00 2001 From: chai Date: Thu, 27 May 2021 18:11:57 +0800 Subject: *tween animation --- .../Tween/Editor/TweenAnimationInspector.cs | 226 ++++++++++++++++++++- .../Tween/Editor/TweenAnimationInspector_Alpha.cs | 6 +- .../Tween/Editor/TweenAnimationInspector_Color.cs | 4 + .../Animation/Tween/Editor/TweenModuleGUIStyles.cs | 95 ++++++++- .../Animation/Tween/Editor/TweenModuleUI.cs | 181 ++++++++++++++++- 5 files changed, 496 insertions(+), 16 deletions(-) (limited to 'Assets/UI_Extension/Scripts/Animation/Tween/Editor') diff --git a/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector.cs b/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector.cs index e0f2b9a..e79c90d 100644 --- a/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector.cs +++ b/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector.cs @@ -1,6 +1,8 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; +using System.Reflection; using UnityEngine; using UnityEditor; @@ -9,7 +11,7 @@ namespace TweenAnimation [CustomEditor(typeof(TweenAnimation), false)] public partial class TweenAnimationInspector : Editor { - private TweenModuleGUIStyles styles + TweenModuleGUIStyles styles { get { @@ -17,17 +19,229 @@ namespace TweenAnimation } } - public void Awake() + TweenModuleUI ui { + get + { + return TweenModuleUI.Get(); + } } + float value = 20; + + TweenAnimation animation; + bool m_ShowAnimationTab = true; + + static Dictionary s_TweenModuleClasses; + static string[] s_TweenModuleClassNames; + static Dictionary s_TweenModuleGUI; + + public void OnEnable() + { + m_ShowAnimationTab = true; + s_TweenModuleGUI = new Dictionary(); + } + public override void OnInspectorGUI() { - TweenAnimation tween = target as TweenAnimation; + animation = target as TweenAnimation; + if (animation == null) + return; + + EditorGUILayout.Space(); + + AnimationTab(); + AddNewModule(); + AnimationModules(); + + EditorGUILayout.Space(); + } + + void AnimationTab() + { + Rect rect = ui.GetControlRect(40); + + Rect headerRect = rect; + headerRect.x -= 2; + headerRect.width += 8; + if (GUI.Button(headerRect, "", styles.headerBg)) + { + m_ShowAnimationTab = !m_ShowAnimationTab; + } + + 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); + // 播放风格 + animation.playbackStyle = (TweenAnimation.PlaybackStyle) ui.GUIEnum("Playback Style", animation.playbackStyle); + + if(animation.playbackStyle != TweenAnimation.PlaybackStyle.Once) + { + // 播放次数限制 + string fmt = animation.playbackLimit <= 0 ? "Unlimited" : ""; + float limit = ui.GUIFloat("Playback Limit", animation.playbackLimit, fmt); + limit = Mathf.Clamp(limit, 0, Int32.MaxValue); + animation.playbackLimit = animation.playbackLimit > limit ? (int)Mathf.Floor(limit) : (int)Mathf.Ceil(limit); + } + + // 事件触发方向 + animation.eventTriggeredDirection = (TweenAnimation.EventTriggeredDirection)ui.GUIEnumMask("Event Direction", animation.eventTriggeredDirection); + } + DrawBgWire(rect, (m_ShowAnimationTab ? 4 : -2)); + if(!m_ShowAnimationTab) + GUILayout.Space(-4); + else + GUILayout.Space(2); + } + + void AddNewModule() + { + Rect rect = ui.GetControlRect(20); - GUILayout.Label("content", styles.editableLabel); - GUILayout.Label("content", styles.editableLabel); + Rect labelRect = rect; + labelRect.y += 2; + GUI.Label(labelRect, "Modules ", styles.text); + + rect.x = rect.x + rect.width - 15; + rect.width = 20; + rect.height = 20; + //if (GUI.Button(rect, "", styles.plus)) + { + if(s_TweenModuleClasses == null) + { + s_TweenModuleClasses = new Dictionary(); + // 获得TweenModule的派生类 + var classes = Assembly + .GetAssembly(typeof(TweenModule)) + .GetTypes() + .Where(t => t.IsSubclassOf(typeof(TweenModule))); + foreach(var itor in classes) + { + string name = itor.Name; + Type type = itor; + s_TweenModuleClasses.Add(name, type); + } + s_TweenModuleClassNames = null; + } + if(s_TweenModuleClassNames == null) + { + s_TweenModuleClassNames = new string[s_TweenModuleClasses.Count]; + int i = 0; + var itor = s_TweenModuleClasses.GetEnumerator(); + while(itor.MoveNext()) + { + s_TweenModuleClassNames[i++] = itor.Current.Key; + } + } + int selected = EditorGUI.Popup(rect, -1, s_TweenModuleClassNames, styles.plus); + if(selected >= 0 && selected < s_TweenModuleClassNames.Length) + { + string name = s_TweenModuleClassNames[selected]; + Type type = s_TweenModuleClasses[name]; + var module = Activator.CreateInstance(type); + animation.AddModule(module as TweenModule); + } + } + GUILayout.Space(-4); + } + + void AnimationModules() + { + if (animation.modules == null) + return; + for(int i = 0; i < animation.modules.Count; ++i) + { + TweenModule module = animation.modules[i]; + AnimaitonModule(module, i == animation.modules.Count - 1); + } + } + + void AnimaitonModule(TweenModule module, bool isLast) + { + string name = module.name; + string description = module.description; + 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; + module.enabled = GUI.Toggle(checkRect, enabled, "", styles.checkmark); + Rect headerRect = rect; + headerRect.x -= 2; + headerRect.width += 8; + if (GUI.Button(headerRect, "", styles.headerBg)) + module.unfold = !module.unfold; + } + 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); + } + + Vector2 size = styles.text.CalcSize(new GUIContent(name)); + GUI.Label(new Rect(rect.x + 15, rect.y + 2, size.x, 20), name, styles.text); + + // content + if (module.unfold) + { + MethodInfo method; + string classname = module.GetType().Name; + if (!s_TweenModuleGUI.TryGetValue(classname, out method)) + { + Type type = this.GetType(); + method = type.GetMethod("OnInspector_" + classname); + s_TweenModuleGUI.Add(classname, method); + } + if (method != null) + { + object[] parameter = new object[]{ module}; + method.Invoke(this, parameter); + } + else + { + Debug.LogError("没有对应的绘制函数" + "OnInspector_" + classname); + } + } + + // wire + DrawBgWire(rect, module.unfold ? 4 : -2); + + if (!module.unfold) + GUILayout.Space(-4); + else + GUILayout.Space(2); + + if (!isLast) + GUILayout.Space(-1); + } + + void DrawBgWire(Rect firstRect, int hOff) + { + Rect bgRect = ui.GetLastControlRect(); + bgRect.height = bgRect.y + bgRect.height - firstRect.y + hOff/*(m_ShowAnimationTab ? 4 : -2)*/; + bgRect.x = firstRect.x - 3; + bgRect.y = firstRect.y - 1; + bgRect.width = firstRect.width + 5; + GUI.Label(bgRect, "", styles.bgSmall); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector_Alpha.cs b/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector_Alpha.cs index 0ccbe70..6585ded 100644 --- a/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector_Alpha.cs +++ b/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector_Alpha.cs @@ -7,10 +7,10 @@ namespace TweenAnimation public partial class TweenAnimationInspector : Editor { - public void foo(TweenModule module) + public void OnInspector_TweenAlpha(TweenModule module) { - - + TweenAlpha tween = module as TweenAlpha; + value = ui.GUIFloat("Float value", value, "f2"); } } } \ No newline at end of file diff --git a/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector_Color.cs b/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector_Color.cs index f051b61..c129b4a 100644 --- a/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector_Color.cs +++ b/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenAnimationInspector_Color.cs @@ -7,7 +7,11 @@ namespace TweenAnimation public partial class TweenAnimationInspector : Editor { + public void OnInspector_TweenColor(TweenModule module) + { + value = ui.GUIFloat("Float value", value, "f2"); + } } } \ No newline at end of file diff --git a/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenModuleGUIStyles.cs b/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenModuleGUIStyles.cs index ad9d09a..2e90cb8 100644 --- a/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenModuleGUIStyles.cs +++ b/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenModuleGUIStyles.cs @@ -12,11 +12,25 @@ namespace TweenAnimation private delegate bool GetBoldDefaultFontFunc(); private static GetBoldDefaultFontFunc GetBoldDefaultFont; + static Texture2D m_BgTexture; + static Texture2D m_BgTextureActive; + static Texture2D m_BgTextureWire; + static Texture2D m_BgTextureWireSmall; + + static Texture2D LoadTexture(string path) + { + return AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D)) as Texture2D; + } + static TweenModuleGUIStyles() { Type editorGUIUtility = typeof(EditorGUIUtility); + GetBoldDefaultFont = (GetBoldDefaultFontFunc)GetMethod(typeof(GetBoldDefaultFontFunc), typeof(EditorGUIUtility), "GetBoldDefaultFont", BindingFlags.Static | BindingFlags.NonPublic); - GetBoldDefaultFont = (GetBoldDefaultFontFunc) GetMethod(typeof(GetBoldDefaultFontFunc), typeof(EditorGUIUtility), "GetBoldDefaultFont", BindingFlags.Static | BindingFlags.NonPublic); + m_BgTexture = LoadTexture(TweenAnimationSetup.root + "Icons/Background.png"); + m_BgTextureActive = LoadTexture(TweenAnimationSetup.root + "Icons/BackgroundActive.png"); + m_BgTextureWire = LoadTexture(TweenAnimationSetup.root + "Icons/BackgroundWire.png"); + m_BgTextureWireSmall = LoadTexture(TweenAnimationSetup.root + "Icons/BackgroundWireSmall.png"); } private static Delegate GetMethod(Type del, Type type, string name, BindingFlags flag) @@ -194,6 +208,22 @@ namespace TweenAnimation } } + public GUIStyle floatfiled + { + get + { + return m_FloatField; + } + } + + public GUIStyle headerBg + { + get + { + return m_HeaderBg; + } + } + private GUIStyle m_Label; private GUIStyle m_LabelBold; @@ -246,10 +276,29 @@ namespace TweenAnimation private GUIStyle m_CustomDataWindow; + private GUIStyle m_FloatField; + private Texture2D m_WarningIcon; private static TweenModuleGUIStyles s_TweenModuleGUIStyles; + private GUIStyle m_HeaderBg; + + private GUIStyle m_HeaderTitle; + public GUIStyle headerTitle { get { return m_HeaderTitle; } } + + private GUIStyle m_Bg; + public GUIStyle bg { get { return m_Bg; } } + + private GUIStyle m_BgSmall; + public GUIStyle bgSmall { get { return m_BgSmall; } } + + private GUIStyle m_AddNewModule; + public GUIStyle addNewModule { get { return m_AddNewModule; } } + + private GUIStyle m_Text; + public GUIStyle text { get { return m_Text; } } + public static TweenModuleGUIStyles Get() { bool flag = s_TweenModuleGUIStyles == null; @@ -285,18 +334,58 @@ namespace TweenAnimation this.m_CustomDataWindow.font = EditorStyles.miniFont; this.m_EmitterHeaderStyle.clipping = TextClipping.Clip; this.m_EmitterHeaderStyle.padding.right = 45; - //this.m_WarningIcon = EditorGUIUtility.LoadIcon("console.infoicon.sml"); this.m_ToolbarButtonLeftAlignText = new GUIStyle(this.m_ToolbarButtonLeftAlignText); this.m_ToolbarButtonLeftAlignText.alignment = TextAnchor.MiddleLeft; this.m_ModulePadding = new GUIStyle(); this.m_ModulePadding.padding = new RectOffset(3, 3, 4, 2); - } + InitStyle(out m_FloatField, EditorStyles.numberField, s => s.fontSize = 9); + InitStyle(out m_HeaderBg, s => { + s.border = new RectOffset(11, 15, 10, 15); + s.normal.background = m_BgTexture; + s.active.background = m_BgTextureActive; + s.hover.background = m_BgTexture; + }); + InitStyle(out m_HeaderTitle, s => { + s.fontStyle = FontStyle.Bold; + s.fontSize = 9; + }); + InitStyle(out m_Bg, s => { + s.border = new RectOffset(5, 5, 5, 5); + s.normal.background = m_BgTextureWire; + }); + InitStyle(out m_BgSmall, s => { + s.border = new RectOffset(3, 3, 3, 3); + s.normal.background = m_BgTextureWireSmall; + }); + InitStyle(out m_AddNewModule,EditorStyles.miniButtonMid , s => { + s.fontSize = 9; + }); + + InitStyle(out m_Text, EditorStyles.label, s => { + s.fontSize = 9; + }); + } + private static void InitStyle(out GUIStyle normal, string name) { normal = FindStyle(name); } + private delegate void Initter(GUIStyle style); + + private static void InitStyle(out GUIStyle normal, GUIStyle other, Initter initter) + { + normal = new GUIStyle(other); + initter(normal); + } + + private static void InitStyle(out GUIStyle normal, Initter initter) + { + normal = new GUIStyle(); + initter(normal); + } + private static void InitStyle(out GUIStyle normal, out GUIStyle bold, string name) { InitStyle(out normal, name); diff --git a/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenModuleUI.cs b/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenModuleUI.cs index 9819014..aeb4e8b 100644 --- a/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenModuleUI.cs +++ b/Assets/UI_Extension/Scripts/Animation/Tween/Editor/TweenModuleUI.cs @@ -1,13 +1,186 @@ -using System.Collections; +using System; +using System.Reflection; +using System.Collections; using System.Collections.Generic; using UnityEngine; +using UnityEditor; -public static class TweenModuleUI +namespace TweenAnimation { - public static float GUIFloat(GUIContent guiContent, float floatValue, string formatString, params GUILayoutOption[] layoutOptions) + + public class TweenModuleUI { + static TweenModuleUI m_instance; + public static TweenModuleUI Get() + { + if (m_instance == null) + m_instance = new TweenModuleUI(); + return m_instance; + } + + private TweenModuleGUIStyles styles + { + get + { + return TweenModuleGUIStyles.Get(); + } + } + + private readonly GUIStyle s_ControlRectStyle = new GUIStyle + { + margin = new RectOffset(0, 0, 2, 2) + }; + + private float labelWidth + { + get + { + return EditorGUIUtility.labelWidth; + } + } + + #region Editor internals + MethodInfo EditorGUI_DoFloatField; // EditorGUI.DoFloatField internal float DoFloatField(EditorGUI.RecycledTextEditor editor, Rect position, Rect dragHotZone, int id, float value, string formatString, GUIStyle style, bool draggable) + FieldInfo EditorGUI_RecycledEditor; // EditorGUI.s_RecycleEditor + + int EditorGUI_FloatFieldHash = "EditorTextField".GetHashCode(); + + #endregion + + TweenModuleUI() + { + Type editorGUIType = typeof(EditorGUI); + Type recycledTextEditorType = Assembly.GetAssembly(editorGUIType).GetType("UnityEditor.EditorGUI+RecycledTextEditor"); + + // DoFloatField + { + Type[] argumentTypes = new Type[] { recycledTextEditorType, typeof(Rect), typeof(Rect), typeof(int), typeof(float), typeof(string), typeof(GUIStyle), typeof(bool) }; + EditorGUI_DoFloatField = editorGUIType.GetMethod("DoFloatField", BindingFlags.NonPublic | BindingFlags.Static, null, argumentTypes, null); + EditorGUI_RecycledEditor = editorGUIType.GetField("s_RecycledEditor", BindingFlags.NonPublic | BindingFlags.Static); + } + } + + private object Invoke(MethodInfo method, object caller, params object[] param) + { + return method.Invoke(caller, param); + } + + public Rect GetControlRect(int height) + { + return GetControlRect(height, null); + } + + public float GUIFloat(string guiContent, float floatValue, string formatString = null, params GUILayoutOption[] layoutOptions) + { + return GUIFloat(new GUIContent(guiContent), floatValue, formatString, layoutOptions); + } + + public float GUIFloat(GUIContent guiContent, float floatValue, string formatString, params GUILayoutOption[] layoutOptions) + { + Rect controlRect = GetControlRect(13, layoutOptions); + PrefixLabel(controlRect, guiContent); + return FloatDraggable(controlRect, floatValue, 1f, EditorGUIUtility.labelWidth, formatString); + } + + public float FloatDraggable(Rect rect, float floatValue, float remap, float dragWidth, string formatString) + { + int controlID = GUIUtility.GetControlID(EditorGUI_FloatFieldHash, FocusType.Keyboard, rect); + Rect dragHotZone = rect; + dragHotZone.width = dragWidth; + Rect position = rect; + position.xMin += dragWidth; + float v = (float)Invoke(EditorGUI_DoFloatField, null, EditorGUI_RecycledEditor.GetValue(null), position, dragHotZone, controlID, floatValue * remap, formatString, styles.floatfiled, true); + return v / remap; + } + + public string GUIText(string label, string content, params GUILayoutOption[] layoutOptions) + { + return GUIText(new GUIContent(label), content, layoutOptions); + } + + public string GUIText(GUIContent guiContent, string content, params GUILayoutOption[] layoutOptions) + { + Rect controlRect = GetControlRect(13, layoutOptions); + PrefixLabel(controlRect, guiContent); + Rect position = controlRect; + position.xMin += EditorGUIUtility.labelWidth; + content = GUI.TextField(position, content); + return content; + } + + public Enum GUIEnumMask(string label, Enum enumValue, params GUILayoutOption[] layoutOptions) + { + return GUIEnumMask(new GUIContent(label), enumValue, layoutOptions); + } + + public Enum GUIEnumMask(GUIContent label, Enum enumValue, params GUILayoutOption[] layoutOptions) + { + Rect rect = GetControlRect(13, layoutOptions); + rect = PrefixLabel(rect, label); + return EditorGUI.EnumFlagsField(rect, enumValue, styles.popup); + } + + public Enum GUIEnum(string label, Enum enumValue, params GUILayoutOption[] layoutOptions) + { + return GUIEnum(new GUIContent(label), enumValue, layoutOptions); + } + + public Enum GUIEnum(GUIContent label, Enum enumValue, params GUILayoutOption[] layoutOptions) + { + Rect rect = GetControlRect(13, layoutOptions); + rect = PrefixLabel(rect, label); + return EditorGUI.EnumPopup(rect, enumValue, styles.popup); + } + + private Rect PrefixLabel(Rect totalPosition, GUIContent label) + { + bool flag = !EditorGUI_LabelHasContent(label); + Rect result; + if (flag) + { + result = EditorGUI.IndentedRect(totalPosition); + } + else + { + Rect labelPosition; + Rect rect = FieldPosition(totalPosition, out labelPosition); + EditorGUI.HandlePrefixLabel(totalPosition, labelPosition, label, 0, styles.label); + result = rect; + } + return result; + } + + private Rect FieldPosition(Rect totalPosition, out Rect labelPosition) + { + labelPosition = new Rect(totalPosition.x + EditorGUI_indent, totalPosition.y, EditorGUIUtility.labelWidth - EditorGUI_indent, 13f); + return new Rect(totalPosition.x + EditorGUIUtility.labelWidth, totalPosition.y, totalPosition.width - EditorGUIUtility.labelWidth, totalPosition.height); + } + + private Rect GetControlRect(int height, params GUILayoutOption[] layoutOptions) + { + return GUILayoutUtility.GetRect(0f, (float)height, s_ControlRectStyle, layoutOptions); + } + + private bool EditorGUI_LabelHasContent(GUIContent label) + { + bool flag = label == null; + return flag || label.text != string.Empty || label.image != null; + } + + // EditorGUI.indent + private float EditorGUI_indent + { + get + { + return (float)EditorGUI.indentLevel * 15f; + } + } + + public Rect GetLastControlRect() + { + return GUILayoutUtility.GetLastRect(); + } - return floatValue; } } -- cgit v1.1-26-g67d0