using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; using UnityEditor; namespace TweenAnimation { [CustomEditor(typeof(TweenAnimation), false)] public partial class TweenAnimationInspector : Editor { TweenModuleGUIStyles styles { get { return TweenModuleGUIStyles.Get(); } } 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() { 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); 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); } } }