using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using MotionFramework.Utility; namespace MotionFramework.Console { /// /// 控制台 /// public static class DeveloperConsole { private class WindowWrapper : IComparer, IComparable { public Type ClassType; public string Title; public int Priority; public IConsoleWindow Instance; public int CompareTo(WindowWrapper other) { return Compare(this, other); } public int Compare(WindowWrapper a, WindowWrapper b) { return a.Priority.CompareTo(b.Priority); } } /// /// 控制台节点列表 /// private readonly static List _wrappers = new List(); // FPS相关 private static FPSCounter _fpsCounter = null; private static int _lastFrame = 0; // GUI相关 private static bool _visible = false; private static int _showIndex = 0; private static Texture _bgTexture; private static string[] _toolbarTitles; /// /// 初始化控制台 /// /// 扩展的控制台窗口所在的程序集 public static void Initialize(bool showFPS = true, string assemblyName = AssemblyUtility.UnityDefaultAssemblyName) { if (showFPS) { _fpsCounter = new FPSCounter(); } // 加载背景纹理 string textureName = "console_background"; _bgTexture = Resources.Load(textureName); if (_bgTexture == null) UnityEngine.Debug.LogWarning($"Not found {textureName} texture in Resources folder."); // 获取所有控制台窗口类 List types = AssemblyUtility.GetAssignableAttributeTypes(AssemblyUtility.MotionFrameworkAssemblyName, typeof(IConsoleWindow), typeof(ConsoleAttribute)); List temps = AssemblyUtility.GetAssignableAttributeTypes(assemblyName, typeof(IConsoleWindow), typeof(ConsoleAttribute)); types.AddRange(temps); for (int i = 0; i < types.Count; i++) { ConsoleAttribute attribute = (ConsoleAttribute)Attribute.GetCustomAttribute(types[i], typeof(ConsoleAttribute)); WindowWrapper wrapper = new WindowWrapper() { ClassType = types[i], Title = attribute.Title, Priority = attribute.Order, }; _wrappers.Add(wrapper); } // 根据优先级排序 _wrappers.Sort(); // 创建实例类 for (int i = 0; i < _wrappers.Count; i++) { WindowWrapper wrapper = _wrappers[i]; wrapper.Instance = (IConsoleWindow)Activator.CreateInstance(wrapper.ClassType); } // 标题列表 List titles = new List(); for (int i = 0; i < _wrappers.Count; i++) { titles.Add(_wrappers[i].Title); } _toolbarTitles = titles.ToArray(); } /// /// 绘制控制台 /// 注意:该接口必须在OnGUI函数内调用 /// public static void Draw() { if (_fpsCounter != null) { if (_lastFrame != Time.frameCount) { _lastFrame = Time.frameCount; _fpsCounter.Update(); } } // 注意:GUI接口只能在OnGUI内部使用 ConsoleGUI.InitGlobalStyle(); float posX = Screen.safeArea.x; float posY = Screen.height - Screen.safeArea.height - Screen.safeArea.y; if (_visible == false) { float wdith = ConsoleGUI.XStyle.fixedWidth; float height = ConsoleGUI.XStyle.fixedHeight; // 显示按钮 if (GUI.Button(new Rect(posX + 10, posY + 10, wdith, height), "X", ConsoleGUI.XStyle)) _visible = true; // FPS if (_fpsCounter != null) { int fps = _fpsCounter.GetFPS(); string text = $"{fps}"; GUI.Label(new Rect(posX + wdith * 1.5f, posY + 5, wdith * 2, height * 2), text, ConsoleGUI.RichLabelStyle); } } else { Rect windowRect = new Rect(posX, posY, Screen.safeArea.width, Screen.safeArea.height); GUI.Window(0, windowRect, DrawWindow, string.Empty); } } private static void DrawWindow(int windowID) { // 绘制背景 if (_visible && _bgTexture != null) GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), _bgTexture, ScaleMode.StretchToFill, true); GUILayout.BeginHorizontal(); { // 隐藏按钮 if (GUILayout.Button("X", ConsoleGUI.ButtonStyle, GUILayout.Width(ConsoleGUI.ButtonStyle.fixedHeight))) _visible = false; // 绘制按钮栏 _showIndex = GUILayout.Toolbar(_showIndex, _toolbarTitles, ConsoleGUI.ToolbarStyle); } GUILayout.EndHorizontal(); // 绘制选中窗口 for (int i = 0; i < _wrappers.Count; i++) { if (_showIndex != i) continue; WindowWrapper wrapper = _wrappers[i]; wrapper.Instance.OnGUI(); } } } }