730 lines
24 KiB
C#
730 lines
24 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using TMPro;
|
||
|
||
namespace MeowmentDebugTool
|
||
{
|
||
/// <summary>
|
||
/// 控制台模块 - 显示Unity日志(基于UGUI实现)
|
||
/// </summary>
|
||
public class ConsoleModule : IDebugModule
|
||
{
|
||
#region 字段
|
||
private GameObject consolePage;
|
||
|
||
// UI组件
|
||
private ScrollRect logScrollRect;
|
||
private RectTransform logContent;
|
||
private ScrollRect detailScrollRect;
|
||
private TMP_Text detailText;
|
||
|
||
// 按钮
|
||
private Button clearButton;
|
||
private Toggle lockScrollToggle;
|
||
private Toggle infoFilterToggle;
|
||
private Toggle warningFilterToggle;
|
||
private Toggle errorFilterToggle;
|
||
private Toggle fatalFilterToggle;
|
||
|
||
// 文字筛选
|
||
private TMP_InputField textFilterInputField;
|
||
private string textFilter = "";
|
||
private TMP_Text infoFilterLabel;
|
||
private TMP_Text warningFilterLabel;
|
||
private TMP_Text errorFilterLabel;
|
||
private TMP_Text fatalFilterLabel;
|
||
|
||
// 日志项预制件
|
||
private GameObject logItemPrefab;
|
||
|
||
// 日志数据 - 分离的缓存池
|
||
private Queue<LogNode> infoLogNodes = new Queue<LogNode>();
|
||
private Queue<LogNode> warningLogNodes = new Queue<LogNode>();
|
||
private Queue<LogNode> errorLogNodes = new Queue<LogNode>();
|
||
private Queue<LogNode> fatalLogNodes = new Queue<LogNode>();
|
||
private LogNode selectedNode = null;
|
||
|
||
// 日志计数
|
||
private int infoCount = 0;
|
||
private int warningCount = 0;
|
||
private int errorCount = 0;
|
||
private int fatalCount = 0;
|
||
|
||
// 设置
|
||
private bool lockScroll = true;
|
||
private int maxInfoLines = 50;
|
||
private int maxWarningLines = 50;
|
||
private int maxErrorLines = 50;
|
||
private int maxFatalLines = 50;
|
||
private bool infoFilter = false; // 默认不显示Info
|
||
private bool warningFilter = false; // 默认不显示Warning
|
||
private bool errorFilter = true;
|
||
private bool fatalFilter = true;
|
||
|
||
// 颜色设置
|
||
private Color32 infoColor = Color.white;
|
||
private Color32 warningColor = Color.yellow;
|
||
private Color32 errorColor = Color.red;
|
||
private Color32 fatalColor = new Color(0.7f, 0.2f, 0.2f);
|
||
|
||
// UI对象池
|
||
private List<GameObject> logItemPool = new List<GameObject>();
|
||
private List<GameObject> activeLogItems = new List<GameObject>();
|
||
|
||
// 保存的字体
|
||
private TMP_FontAsset savedFontAsset = null;
|
||
|
||
// 延迟刷新标记
|
||
private bool needRefresh = false;
|
||
private int lastRefreshFrame = -1;
|
||
private bool hasRegisteredLogCallback = false;
|
||
private bool uiInitialized = false;
|
||
private int lastDisplayedInfoCount = -1;
|
||
private int lastDisplayedWarningCount = -1;
|
||
private int lastDisplayedErrorCount = -1;
|
||
private int lastDisplayedFatalCount = -1;
|
||
#endregion
|
||
|
||
#region 构造函数
|
||
public ConsoleModule(GameObject page, ScrollRect logScroll, RectTransform logContentTransform,
|
||
ScrollRect detailScroll, TMP_Text detail,
|
||
Button clearBtn, Toggle lockToggle, Toggle infoToggle, Toggle warningToggle,
|
||
Toggle errorToggle, Toggle fatalToggle, TMP_InputField textFilterInput, GameObject logItemPrefabObj)
|
||
{
|
||
consolePage = page;
|
||
logScrollRect = logScroll;
|
||
logContent = logContentTransform;
|
||
detailScrollRect = detailScroll;
|
||
detailText = detail;
|
||
clearButton = clearBtn;
|
||
lockScrollToggle = lockToggle;
|
||
infoFilterToggle = infoToggle;
|
||
warningFilterToggle = warningToggle;
|
||
errorFilterToggle = errorToggle;
|
||
fatalFilterToggle = fatalToggle;
|
||
textFilterInputField = textFilterInput;
|
||
logItemPrefab = logItemPrefabObj;
|
||
}
|
||
#endregion
|
||
|
||
#region IDebugModule 实现
|
||
public void Initialize()
|
||
{
|
||
Debug.Log("[ConsoleModule] 初始化控制台模块...");
|
||
EnsureLogCaptureRegistered();
|
||
|
||
Debug.Log("[ConsoleModule] 控制台模块初始化完成");
|
||
}
|
||
|
||
public GameObject GetPage()
|
||
{
|
||
return consolePage;
|
||
}
|
||
|
||
public string GetModuleName()
|
||
{
|
||
return "控制台";
|
||
}
|
||
#endregion
|
||
|
||
#region 公共方法
|
||
/// <summary>
|
||
/// 设置SDF字体
|
||
/// </summary>
|
||
public void SetSDFFont(TMP_FontAsset fontAsset)
|
||
{
|
||
savedFontAsset = fontAsset;
|
||
|
||
// 应用到详情文本
|
||
if (detailText != null && fontAsset != null)
|
||
{
|
||
detailText.font = fontAsset;
|
||
}
|
||
|
||
// 刷新已有日志项
|
||
if (uiInitialized)
|
||
{
|
||
RefreshLogDisplay();
|
||
}
|
||
}
|
||
|
||
public void EnsurePageViewInitialized()
|
||
{
|
||
EnsureLogCaptureRegistered();
|
||
|
||
if (uiInitialized)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 检查必要的组件
|
||
if (consolePage == null)
|
||
Debug.LogError("[ConsoleModule] consolePage is null!");
|
||
if (logScrollRect == null)
|
||
Debug.LogError("[ConsoleModule] logScrollRect is null!");
|
||
if (logContent == null)
|
||
Debug.LogError("[ConsoleModule] logContent is null!");
|
||
if (detailScrollRect == null)
|
||
Debug.LogError("[ConsoleModule] detailScrollRect is null!");
|
||
if (detailText == null)
|
||
Debug.LogError("[ConsoleModule] detailText is null!");
|
||
if (clearButton == null)
|
||
Debug.LogError("[ConsoleModule] clearButton is null!");
|
||
if (logItemPrefab == null)
|
||
Debug.LogError("[ConsoleModule] logItemPrefab is null!");
|
||
|
||
if (clearButton != null)
|
||
{
|
||
clearButton.onClick.RemoveListener(ClearAllLogs);
|
||
clearButton.onClick.AddListener(ClearAllLogs);
|
||
}
|
||
|
||
if (lockScrollToggle != null)
|
||
{
|
||
lockScrollToggle.onValueChanged.RemoveListener(OnLockScrollChanged);
|
||
lockScrollToggle.isOn = lockScroll;
|
||
lockScrollToggle.onValueChanged.AddListener(OnLockScrollChanged);
|
||
}
|
||
|
||
if (infoFilterToggle != null)
|
||
{
|
||
infoFilterToggle.onValueChanged.RemoveListener(OnInfoFilterChanged);
|
||
infoFilterToggle.isOn = infoFilter;
|
||
infoFilterToggle.onValueChanged.AddListener(OnInfoFilterChanged);
|
||
infoFilterLabel = infoFilterToggle.GetComponentInChildren<TMP_Text>(true);
|
||
}
|
||
|
||
if (warningFilterToggle != null)
|
||
{
|
||
warningFilterToggle.onValueChanged.RemoveListener(OnWarningFilterChanged);
|
||
warningFilterToggle.isOn = warningFilter;
|
||
warningFilterToggle.onValueChanged.AddListener(OnWarningFilterChanged);
|
||
warningFilterLabel = warningFilterToggle.GetComponentInChildren<TMP_Text>(true);
|
||
}
|
||
|
||
if (errorFilterToggle != null)
|
||
{
|
||
errorFilterToggle.onValueChanged.RemoveListener(OnErrorFilterChanged);
|
||
errorFilterToggle.isOn = errorFilter;
|
||
errorFilterToggle.onValueChanged.AddListener(OnErrorFilterChanged);
|
||
errorFilterLabel = errorFilterToggle.GetComponentInChildren<TMP_Text>(true);
|
||
}
|
||
|
||
if (fatalFilterToggle != null)
|
||
{
|
||
fatalFilterToggle.onValueChanged.RemoveListener(OnFatalFilterChanged);
|
||
fatalFilterToggle.isOn = fatalFilter;
|
||
fatalFilterToggle.onValueChanged.AddListener(OnFatalFilterChanged);
|
||
fatalFilterLabel = fatalFilterToggle.GetComponentInChildren<TMP_Text>(true);
|
||
}
|
||
|
||
if (textFilterInputField != null)
|
||
{
|
||
textFilterInputField.onValueChanged.RemoveListener(OnTextFilterChanged);
|
||
textFilterInputField.text = textFilter;
|
||
textFilterInputField.onValueChanged.AddListener(OnTextFilterChanged);
|
||
}
|
||
|
||
if (detailText != null)
|
||
detailText.text = "点击日志查看详细信息...";
|
||
|
||
uiInitialized = true;
|
||
needRefresh = true;
|
||
RefreshLogDisplay();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取日志统计信息
|
||
/// </summary>
|
||
public void GetLogCount(out int info, out int warning, out int error, out int fatal)
|
||
{
|
||
RefreshCount();
|
||
info = infoCount;
|
||
warning = warningCount;
|
||
error = errorCount;
|
||
fatal = fatalCount;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置各类型日志的最大缓存数量
|
||
/// </summary>
|
||
public void SetMaxLogLines(int maxInfo, int maxWarning, int maxError, int maxFatal)
|
||
{
|
||
maxInfoLines = Mathf.Max(1, maxInfo);
|
||
maxWarningLines = Mathf.Max(1, maxWarning);
|
||
maxErrorLines = Mathf.Max(1, maxError);
|
||
maxFatalLines = Mathf.Max(1, maxFatal);
|
||
Debug.Log($"[ConsoleModule] 设置缓存池大小 - Info:{maxInfoLines}, Warning:{maxWarningLines}, Error:{maxErrorLines}, Fatal:{maxFatalLines}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取各类型日志的最大缓存数量
|
||
/// </summary>
|
||
public void GetMaxLogLines(out int maxInfo, out int maxWarning, out int maxError, out int maxFatal)
|
||
{
|
||
maxInfo = maxInfoLines;
|
||
maxWarning = maxWarningLines;
|
||
maxError = maxErrorLines;
|
||
maxFatal = maxFatalLines;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新(每帧调用)
|
||
/// </summary>
|
||
public void Update()
|
||
{
|
||
if (!uiInitialized)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 如果页面未激活,跳过更新
|
||
if (consolePage == null || !consolePage.activeSelf)
|
||
{
|
||
return;
|
||
}
|
||
|
||
// 先处理延迟刷新
|
||
if (needRefresh)
|
||
{
|
||
needRefresh = false;
|
||
lastRefreshFrame = Time.frameCount;
|
||
RefreshLogDisplay();
|
||
}
|
||
|
||
// 如果锁定滚动,自动滚动到底部
|
||
// 只在刷新后的下一帧设置,避免rebuild loop
|
||
if (lockScroll && logScrollRect != null && Time.frameCount > lastRefreshFrame + 1)
|
||
{
|
||
logScrollRect.verticalNormalizedPosition = 0f;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 销毁
|
||
/// </summary>
|
||
public void Shutdown()
|
||
{
|
||
if (hasRegisteredLogCallback)
|
||
{
|
||
Application.logMessageReceived -= OnLogMessageReceived;
|
||
hasRegisteredLogCallback = false;
|
||
}
|
||
|
||
ClearAllLogs();
|
||
}
|
||
#endregion
|
||
|
||
#region 私有方法
|
||
private void EnsureLogCaptureRegistered()
|
||
{
|
||
if (hasRegisteredLogCallback)
|
||
{
|
||
return;
|
||
}
|
||
|
||
Application.logMessageReceived += OnLogMessageReceived;
|
||
hasRegisteredLogCallback = true;
|
||
}
|
||
|
||
private void OnLogMessageReceived(string logMessage, string stackTrace, LogType logType)
|
||
{
|
||
// 将Assert转换为Error
|
||
if (logType == LogType.Assert)
|
||
{
|
||
logType = LogType.Error;
|
||
}
|
||
|
||
// 创建日志节点
|
||
LogNode logNode = LogNode.Create(logType, logMessage, stackTrace);
|
||
|
||
// 根据类型添加到对应的缓存池
|
||
Queue<LogNode> targetQueue = null;
|
||
int maxLines = 0;
|
||
|
||
switch (logType)
|
||
{
|
||
case LogType.Log:
|
||
targetQueue = infoLogNodes;
|
||
maxLines = maxInfoLines;
|
||
break;
|
||
case LogType.Warning:
|
||
targetQueue = warningLogNodes;
|
||
maxLines = maxWarningLines;
|
||
break;
|
||
case LogType.Error:
|
||
targetQueue = errorLogNodes;
|
||
maxLines = maxErrorLines;
|
||
break;
|
||
case LogType.Exception:
|
||
targetQueue = fatalLogNodes;
|
||
maxLines = maxFatalLines;
|
||
break;
|
||
}
|
||
|
||
if (targetQueue != null)
|
||
{
|
||
targetQueue.Enqueue(logNode);
|
||
|
||
// 限制该类型的最大行数
|
||
while (targetQueue.Count > maxLines)
|
||
{
|
||
targetQueue.Dequeue();
|
||
}
|
||
}
|
||
|
||
// 标记需要刷新,而不是立即刷新(避免rebuild loop)
|
||
needRefresh = true;
|
||
}
|
||
|
||
private void RefreshLogDisplay()
|
||
{
|
||
if (!uiInitialized)
|
||
{
|
||
needRefresh = true;
|
||
return;
|
||
}
|
||
|
||
// 如果页面未激活,延迟刷新到下次页面激活时
|
||
if (consolePage == null || !consolePage.activeSelf)
|
||
{
|
||
needRefresh = true;
|
||
return;
|
||
}
|
||
|
||
if (logContent == null)
|
||
{
|
||
Debug.LogError("[ConsoleModule] logContent is null!");
|
||
return;
|
||
}
|
||
|
||
if (logItemPrefab == null)
|
||
{
|
||
Debug.LogError("[ConsoleModule] logItemPrefab is null!");
|
||
return;
|
||
}
|
||
|
||
// 回收所有激活的日志项
|
||
foreach (var item in activeLogItems)
|
||
{
|
||
if (item != null)
|
||
{
|
||
item.SetActive(false);
|
||
if (!logItemPool.Contains(item))
|
||
{
|
||
logItemPool.Add(item);
|
||
}
|
||
}
|
||
}
|
||
activeLogItems.Clear();
|
||
|
||
// 遍历日志节点并创建UI(性能优化:只为需要显示的日志创建LogItem)
|
||
int index = 0;
|
||
int displayCount = 0;
|
||
|
||
// 合并所有缓存池的日志,按时间排序
|
||
List<LogNode> allLogs = new List<LogNode>();
|
||
allLogs.AddRange(infoLogNodes);
|
||
allLogs.AddRange(warningLogNodes);
|
||
allLogs.AddRange(errorLogNodes);
|
||
allLogs.AddRange(fatalLogNodes);
|
||
allLogs.Sort((a, b) => a.LogTime.CompareTo(b.LogTime));
|
||
|
||
foreach (LogNode logNode in allLogs)
|
||
{
|
||
// 根据过滤器判断是否显示,如果不显示则跳过创建LogItem
|
||
if (!ShouldShowLog(logNode))
|
||
continue;
|
||
|
||
// 从对象池获取或创建日志项
|
||
GameObject logItem = GetLogItemFromPool();
|
||
if (logItem == null)
|
||
{
|
||
Debug.LogError("[ConsoleModule] Failed to get log item from pool!");
|
||
continue;
|
||
}
|
||
|
||
logItem.transform.SetParent(logContent, false);
|
||
logItem.SetActive(true);
|
||
activeLogItems.Add(logItem);
|
||
|
||
// 调试:确认对象状态
|
||
if (!logItem.activeSelf)
|
||
{
|
||
Debug.LogWarning($"[ConsoleModule] LogItem {logItem.name} is not active after SetActive(true)!");
|
||
}
|
||
|
||
// 设置日志项内容
|
||
SetupLogItem(logItem, logNode, index);
|
||
|
||
index++;
|
||
displayCount++;
|
||
}
|
||
|
||
UpdateFilterToggleText();
|
||
}
|
||
|
||
private bool ShouldShowLog(LogNode logNode)
|
||
{
|
||
// 首先检查类型筛选
|
||
bool typeMatch = false;
|
||
switch (logNode.LogType)
|
||
{
|
||
case LogType.Log:
|
||
typeMatch = infoFilter;
|
||
break;
|
||
case LogType.Warning:
|
||
typeMatch = warningFilter;
|
||
break;
|
||
case LogType.Error:
|
||
typeMatch = errorFilter;
|
||
break;
|
||
case LogType.Exception:
|
||
typeMatch = fatalFilter;
|
||
break;
|
||
default:
|
||
typeMatch = true;
|
||
break;
|
||
}
|
||
|
||
if (!typeMatch)
|
||
return false;
|
||
|
||
// 然后检查文字筛选
|
||
if (!string.IsNullOrEmpty(textFilter))
|
||
{
|
||
// 如果日志消息不包含筛选文字,则不显示
|
||
if (!logNode.LogMessage.Contains(textFilter))
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
private GameObject GetLogItemFromPool()
|
||
{
|
||
if (logItemPool.Count > 0)
|
||
{
|
||
GameObject item = logItemPool[0];
|
||
logItemPool.RemoveAt(0);
|
||
return item;
|
||
}
|
||
else
|
||
{
|
||
if (logItemPrefab == null)
|
||
{
|
||
Debug.LogError("[ConsoleModule] logItemPrefab is null!");
|
||
return null;
|
||
}
|
||
|
||
// 创建新的日志项
|
||
GameObject newItem = UnityEngine.Object.Instantiate(logItemPrefab);
|
||
newItem.name = "LogItem_" + activeLogItems.Count;
|
||
return newItem;
|
||
}
|
||
}
|
||
|
||
private void SetupLogItem(GameObject logItem, LogNode logNode, int index)
|
||
{
|
||
if (logItem == null)
|
||
{
|
||
Debug.LogError("[ConsoleModule] logItem is null in SetupLogItem!");
|
||
return;
|
||
}
|
||
|
||
// 获取日志项的Toggle和Text组件
|
||
Toggle toggle = logItem.GetComponent<Toggle>();
|
||
TMP_Text text = logItem.GetComponentInChildren<TMP_Text>();
|
||
|
||
if (toggle == null)
|
||
{
|
||
Debug.LogWarning($"[ConsoleModule] Toggle component not found on {logItem.name}!");
|
||
}
|
||
|
||
if (text == null)
|
||
{
|
||
Debug.LogWarning($"[ConsoleModule] TMP_Text component not found on {logItem.name}!");
|
||
return;
|
||
}
|
||
|
||
// 设置文本内容和颜色
|
||
Color32 color = GetLogStringColor(logNode.LogType);
|
||
string logText = GetLogString(logNode);
|
||
|
||
text.text = logText;
|
||
text.color = color;
|
||
|
||
// 应用字体
|
||
if (savedFontAsset != null)
|
||
{
|
||
text.font = savedFontAsset;
|
||
}
|
||
|
||
if (toggle != null)
|
||
{
|
||
// 设置Toggle状态
|
||
toggle.isOn = (selectedNode == logNode);
|
||
|
||
// 设置Toggle事件
|
||
toggle.onValueChanged.RemoveAllListeners();
|
||
toggle.onValueChanged.AddListener((isOn) =>
|
||
{
|
||
if (isOn)
|
||
{
|
||
OnLogItemSelected(logNode);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
private void OnLogItemSelected(LogNode logNode)
|
||
{
|
||
selectedNode = logNode;
|
||
|
||
// 显示详细信息
|
||
if (detailText != null && logNode != null)
|
||
{
|
||
Color32 color = GetLogStringColor(logNode.LogType);
|
||
string colorHex = ColorUtility.ToHtmlStringRGBA(color);
|
||
|
||
string detailInfo = $"<color=#{colorHex}><b>{logNode.LogMessage}</b></color>\n\n";
|
||
detailInfo += $"<color=#888888>时间: {logNode.LogTime.ToLocalTime():HH:mm:ss.fff}\n";
|
||
detailInfo += $"帧数: {logNode.LogFrameCount}\n";
|
||
detailInfo += $"类型: {logNode.LogType}</color>\n\n";
|
||
|
||
if (!string.IsNullOrEmpty(logNode.StackTrace))
|
||
{
|
||
detailInfo += $"<color=#AAAAAA>堆栈跟踪:\n{logNode.StackTrace}</color>";
|
||
}
|
||
|
||
detailText.text = detailInfo;
|
||
}
|
||
|
||
// 重置详情滚动位置
|
||
if (detailScrollRect != null)
|
||
{
|
||
detailScrollRect.verticalNormalizedPosition = 1f;
|
||
}
|
||
}
|
||
|
||
private string GetLogString(LogNode logNode)
|
||
{
|
||
return $"[{logNode.LogTime.ToLocalTime():HH:mm:ss.fff}][{logNode.LogFrameCount}] {logNode.LogMessage}";
|
||
}
|
||
|
||
private Color32 GetLogStringColor(LogType logType)
|
||
{
|
||
switch (logType)
|
||
{
|
||
case LogType.Log:
|
||
return infoColor;
|
||
case LogType.Warning:
|
||
return warningColor;
|
||
case LogType.Error:
|
||
return errorColor;
|
||
case LogType.Exception:
|
||
return fatalColor;
|
||
default:
|
||
return Color.white;
|
||
}
|
||
}
|
||
|
||
private void RefreshCount()
|
||
{
|
||
infoCount = infoLogNodes.Count;
|
||
warningCount = warningLogNodes.Count;
|
||
errorCount = errorLogNodes.Count;
|
||
fatalCount = fatalLogNodes.Count;
|
||
}
|
||
|
||
private void UpdateFilterToggleText()
|
||
{
|
||
if (!uiInitialized)
|
||
{
|
||
return;
|
||
}
|
||
|
||
RefreshCount();
|
||
|
||
UpdateFilterLabel(infoFilterLabel, "Info", infoCount, ref lastDisplayedInfoCount);
|
||
UpdateFilterLabel(warningFilterLabel, "Warning", warningCount, ref lastDisplayedWarningCount);
|
||
UpdateFilterLabel(errorFilterLabel, "Error", errorCount, ref lastDisplayedErrorCount);
|
||
UpdateFilterLabel(fatalFilterLabel, "Fatal", fatalCount, ref lastDisplayedFatalCount);
|
||
}
|
||
|
||
private void UpdateFilterLabel(TMP_Text label, string prefix, int count, ref int lastDisplayedCount)
|
||
{
|
||
if (label == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (lastDisplayedCount == count)
|
||
{
|
||
return;
|
||
}
|
||
|
||
label.text = $"{prefix} ({count})";
|
||
lastDisplayedCount = count;
|
||
}
|
||
|
||
private void ClearAllLogs()
|
||
{
|
||
infoLogNodes.Clear();
|
||
warningLogNodes.Clear();
|
||
errorLogNodes.Clear();
|
||
fatalLogNodes.Clear();
|
||
selectedNode = null;
|
||
lastDisplayedInfoCount = -1;
|
||
lastDisplayedWarningCount = -1;
|
||
lastDisplayedErrorCount = -1;
|
||
lastDisplayedFatalCount = -1;
|
||
|
||
if (detailText != null)
|
||
detailText.text = "点击日志查看详细信息...";
|
||
|
||
RefreshLogDisplay();
|
||
|
||
Debug.Log("[ConsoleModule] 已清空所有日志");
|
||
}
|
||
|
||
private void OnLockScrollChanged(bool value)
|
||
{
|
||
lockScroll = value;
|
||
}
|
||
|
||
private void OnInfoFilterChanged(bool value)
|
||
{
|
||
infoFilter = value;
|
||
needRefresh = true;
|
||
}
|
||
|
||
private void OnWarningFilterChanged(bool value)
|
||
{
|
||
warningFilter = value;
|
||
needRefresh = true;
|
||
}
|
||
|
||
private void OnErrorFilterChanged(bool value)
|
||
{
|
||
errorFilter = value;
|
||
needRefresh = true;
|
||
}
|
||
|
||
private void OnFatalFilterChanged(bool value)
|
||
{
|
||
fatalFilter = value;
|
||
needRefresh = true;
|
||
}
|
||
|
||
private void OnTextFilterChanged(string value)
|
||
{
|
||
textFilter = value;
|
||
needRefresh = true;
|
||
}
|
||
#endregion
|
||
}
|
||
}
|