unity3d 用GUI来显示log日志,移动端查看日志,模拟控制台输出打印

 

为了方便在安卓和苹果手机上查看打印,就用GUI仿照unity的Colsole做了一个显示在屏幕上的Colsole,第一次用GUI做的比较简陋,实际项目不要这样做,log多了会卡,或者优化一下。

 

using System.Collections.Generic;
using UnityEngine;

//     ┌────────────────┐
//     │┌┐  ┌┐  ┌┐                      │
//     │└┘  └┘  └┘                      │
//     │┌──────────────┐│
//     ││                                    ││     
//     ││       ScrollView            ││
//     ││                                    ││
//     │└──────────────┘│
//     │┌──────────────┐│
//     │└──────────────┘│
//     └────────────────┘
public class ConsoleLogOutput : MonoBehaviour
{
    /// <summary>
    /// log信息
    /// </summary>
    struct LogMsg
    {
        public string condition;
        public string stackTrace;
        public LogType type;
        public LogMsg(string condition, string stackTrace, LogType type)
        {
            //因为GUIButton字符串长度有限制(button宽度限制),对显示的log信息长度做截取
            if (condition.Length > 100)
                this.condition = condition.Substring(0, 100);
            else
                this.condition = condition;
            this.stackTrace = condition + "\n" + stackTrace;
            this.type = type;
        }
    }
    /// <summary>
    /// 控制台是否是打开的
    /// </summary>
    bool isDrawGui = false;
    /// <summary>
    /// 全部log信息列表
    /// </summary>
    List<LogMsg> _logAllMsg;
    List<LogMsg> logAllMsg
    {
        get
        {
            if (_logAllMsg == null)
            {
                _logAllMsg = new List<LogMsg>();
            }
            return _logAllMsg;
        }
    }
    /// <summary>
    /// log信息列表
    /// </summary>
    List<LogMsg> _logMsg;
    List<LogMsg> logMsg
    {
        get
        {
            if (_logMsg == null)
            {
                _logMsg = new List<LogMsg>();
            }
            return _logMsg;
        }
    }
    /// <summary>
    /// 报错log信息列表
    /// </summary>
    List<LogMsg> _logErrMsg;
    List<LogMsg> logErrMsg
    {
        get
        {
            if (_logErrMsg == null)
            {
                _logErrMsg = new List<LogMsg>();
            }
            return _logErrMsg;
        }
    }
    /// <summary>
    /// 当前显示的log信息列表
    /// </summary>
    List<LogMsg> _logShowMsg;
    List<LogMsg> logShowMsg
    {
        set { _logShowMsg = value; }
        get
        {
            if (_logShowMsg == null)
            {
                _logShowMsg = new List<LogMsg>();
            }
            return _logShowMsg;
        }
    }


    #region 窗体区域
    //窗体区域座标
    static Vector2 windowPos = new Vector2(Screen.width * 0.3f, 0);
    //窗体区域大小
    static Vector2 windowSize = new Vector2(Screen.width * 0.7f, Screen.height * 0.8f);
    //窗体
    Rect WindowBackgroundRect = new Rect(windowPos.x, windowPos.y, windowSize.x, windowSize.y);
    string WindowBackgroundName = "控制台";
    #endregion

    #region 按钮区域
    //按钮区域座标
    static Vector2 btnPos = new Vector2(10, 25);
    //按钮区域大小
    static Vector2 btnSize = new Vector2(100, 20);
    //按钮排列座标偏差值
    static Vector2 btnPosValue = new Vector2(110, 0);
    //按钮清理Log
    Rect clearBtnRect = new Rect(btnPos.x, btnPos.y, btnSize.x, btnSize.y);
    string clearBtnName = "清理Log";
    //按钮全部Log
    Rect allLogBtnRect = new Rect(btnPos.x + btnPosValue.x, btnPos.y + btnPosValue.y, btnSize.x, btnSize.y);
    string allLogBtnName = "全部Log";
    //按钮打印Log
    Rect logBtnRect = new Rect(btnPos.x + (btnPosValue.x * 2), btnPos.y + (btnPosValue.y * 2), btnSize.x, btnSize.y);
    string logBtnName = "打印Log";
    //按钮报错Log
    Rect logErrBtnRect = new Rect(btnPos.x + (btnPosValue.x * 3), btnPos.y + (btnPosValue.y * 3), btnSize.x, btnSize.y);
    string logErrBtnName = "报错Log";
    #endregion

    #region 日志列表区域
    //日志按钮座标
    static Vector2 logListBtnPos = new Vector2(0, 30);
    //日志按钮大小
    static Vector2 logListBtnSize = new Vector2(windowSize.x - 60, 30);

    //日志
    private Vector2 logScrollPosition;
    //日志列表区域座标
    static Vector2 logListPos = new Vector2(10, 60);
    //日志列表区域大小
    static Vector2 logListSize = new Vector2(windowSize.x - 13, Screen.height * 0.5f);
    //日志列表
    Rect logListRect = new Rect(logListPos.x, logListPos.y, logListSize.x, logListSize.y);

    //日志列表显示座标
    static Vector2 logListViewPos = new Vector2(0, 0);
    //日志列表显示大小
    static Vector2 logListViewSize = new Vector2(windowSize.x - 30, 40);
    //日志列表显示
    Rect logListViewRect = new Rect(logListViewPos.x, logListViewPos.y, logListViewSize.x, logListViewSize.y);
    #endregion

    #region 详细日志区域
    //详细日志
    private Vector2 logContentScrollPosition;
    //详细日志区域座标
    static Vector2 logContentPos = new Vector2(10, logListPos.y + logListSize.y + 20);
    //详细日志区域大小
    static Vector2 logContentSize = new Vector2(windowSize.x - 13, windowSize.y - windowPos.y - logContentPos.y);
    //详细日志
    Rect logContentRect = new Rect(logContentPos.x, logContentPos.y, logContentSize.x, logContentSize.y);

    //详细日志显示座标
    static Vector2 logContentViewPos = new Vector2(0, 0);
    //详细日志显示大小
    static Vector2 logContentViewSize = new Vector2(logContentSize.x, logContentSize.y - 10);
    //详细日志显示
    Rect logContentViewRect = new Rect(logContentViewPos.x, logContentViewPos.y, logContentViewSize.x, logContentViewSize.y);

    //文本座标
    static Vector2 logTextPos = new Vector2(0, 0);
    //文本大小
    static Vector2 logTextSize = new Vector2(logContentViewSize.x, logContentViewSize.y);
    //文本
    Rect logTextRect = new Rect(logTextPos.x, logTextPos.y, logTextSize.x, logTextSize.y);
    //日志详细内容
    string logText = "";
    #endregion


    void Start()
    {
        Application.logMessageReceived += DrawLog;
        logShowMsg = logAllMsg;
    }

    /// <summary>
    /// 控制台输出回调
    /// </summary>
    /// <param name="condition">控制台输出信息</param>
    /// <param name="stackTrace">控制台输出详细信息</param>
    /// <param name="type">控制台输出类型</param>
    void DrawLog(string condition, string stackTrace, LogType type)
    {
        switch (type)
        {
            case LogType.Error:
                logAllMsg.Add(new LogMsg(condition, stackTrace, type));
                logErrMsg.Add(new LogMsg(condition, stackTrace, type));
                break;
            case LogType.Assert:
                break;
            case LogType.Warning:
                break;
            case LogType.Log:
                logAllMsg.Add(new LogMsg(condition, stackTrace, type));
                logMsg.Add(new LogMsg(condition, stackTrace, type));
                break;
            case LogType.Exception:
                break;
            default:
                break;
        }
    }


    void OnGUI()
    {
        if (Event.current.isMouse && Event.current.type == EventType.MouseDown && Event.current.clickCount == 2)
        {
            if (isDrawGui)
            {
                isDrawGui = false;
            }
            else
            {
                isDrawGui = true;
            }
        }

        if (isDrawGui)
        {
            DrawConsole();
        }

    }


    /// <summary>
    /// 绘制控制台
    /// </summary>
    void DrawConsole()
    {
        GUI.Window(0, WindowBackgroundRect, WindowFunction, WindowBackgroundName);

    }
    /// <summary>
    /// 窗体
    /// </summary>
    /// <param name="id"></param>
    void WindowFunction(int id)
    {
        if (GUI.Button(clearBtnRect, clearBtnName))
        {
            //清理控制台输出
            ClearLogMsgList();
        }
        if (GUI.Button(allLogBtnRect, allLogBtnName))
        {
            //显示全部控制台输出
            logShowMsg = logAllMsg;
        }
        if (GUI.Button(logBtnRect, logBtnName))
        {
            //只显示控制台输出打印
            logShowMsg = logMsg;
        }
        if (GUI.Button(logErrBtnRect, logErrBtnName))
        {
            //只显示控制台输出报错
            logShowMsg = logErrMsg;
        }
        //定义窗体可以活动的范围
        logListViewRect.height = logShowMsg.Count * logListBtnSize.y + logListViewSize.y;
        logScrollPosition = GUI.BeginScrollView(logListRect, logScrollPosition, logListViewRect, false, false);
        for (int i = logShowMsg.Count - 1; i >= 0; i--)
        {
            GUI.color = LogCloor(logShowMsg[i].type);
            if (GUI.Button(new Rect(logListBtnPos.x, i * logListBtnPos.y, logListBtnSize.x, logListBtnSize.y), logShowMsg[i].condition))
            {
                logText = logShowMsg[i].stackTrace;
            }
            GUI.color = LogCloor(LogType.Log);
        }
        GUI.EndScrollView();
        logContentScrollPosition = GUI.BeginScrollView(logContentRect, logContentScrollPosition, logContentViewRect, false, false);
        GUI.TextArea(logTextRect, logText);
        GUI.EndScrollView();
    }

    /// <summary>
    /// 清理log列表
    /// </summary>
    void ClearLogMsgList()
    {
        logAllMsg.Clear();
        logMsg.Clear();
        logErrMsg.Clear();
        logShowMsg.Clear();
        logText = "";
    }
    /// <summary>
    /// 返回log颜色
    /// </summary>
    /// <param name="logType">日志类型</param>
    /// <returns></returns>
    Color LogCloor(LogType logType)
    {
        switch (logType)
        {
            case LogType.Error:
                return Color.red;
            case LogType.Assert:
                return Color.white;
            case LogType.Warning:
                return Color.white;
            case LogType.Log:
                return Color.white;
            case LogType.Exception:
                return Color.white;
            default:
                return Color.white;
        }
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章