爲了方便在安卓和蘋果手機上查看打印,就用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;
}
}
}