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

}

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