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();
}
}
}
}