From 0e70f7d446c8c91625083ef09cbed989390573de Mon Sep 17 00:00:00 2001
From: ALEXTANG <574809918@qq.com>
Date: Mon, 23 Oct 2023 11:27:06 +0800
Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=BF=97=E9=87=8D=E5=AE=9A=E5=90=91?=
=?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=E5=AE=9E=E7=94=A8=E5=87=BD=E6=95=B0?=
=?UTF-8?q?=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
日志重定向相关的实用函数。
---
.../TEngine/Editor/Utility/LogRedirection.cs | 99 +++++++++++++++++++
.../Editor/Utility/LogRedirection.cs.meta | 11 +++
2 files changed, 110 insertions(+)
create mode 100644 UnityProject/Assets/TEngine/Editor/Utility/LogRedirection.cs
create mode 100644 UnityProject/Assets/TEngine/Editor/Utility/LogRedirection.cs.meta
diff --git a/UnityProject/Assets/TEngine/Editor/Utility/LogRedirection.cs b/UnityProject/Assets/TEngine/Editor/Utility/LogRedirection.cs
new file mode 100644
index 00000000..1d130e80
--- /dev/null
+++ b/UnityProject/Assets/TEngine/Editor/Utility/LogRedirection.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using UnityEditor;
+using UnityEditor.Callbacks;
+using UnityEditorInternal;
+
+namespace TEngine.Editor
+{
+ ///
+ /// 日志重定向相关的实用函数。
+ ///
+ internal static class LogRedirection
+ {
+ [OnOpenAsset(0)]
+ private static bool OnOpenAsset(int instanceID, int line)
+ {
+ if (line <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(line));
+ }
+ var stackTrace = GetStackTrace();
+ if (!string.IsNullOrEmpty(stackTrace) && (stackTrace.Contains("[Debug]") ||
+ stackTrace.Contains("[INFO]") ||
+ stackTrace.Contains("[ASSERT]") ||
+ stackTrace.Contains("[WARNING]") ||
+ stackTrace.Contains("[ERROR]") ||
+ stackTrace.Contains("[EXCEPTION]")))
+
+ {
+ // 使用正则表达式匹配at的哪个脚本的哪一行
+ var matches = Regex.Match(stackTrace, @"\(at (.+)\)",
+ RegexOptions.IgnoreCase);
+ while (matches.Success)
+ {
+ var pathLine = matches.Groups[1].Value;
+
+ if (!pathLine.Contains("Logger.cs") &&
+ !pathLine.Contains("DefaultLogHelper.cs") &&
+ !pathLine.Contains("GameFrameworkLog.cs") &&
+ !pathLine.Contains("AssetsLogger.cs") &&
+ !pathLine.Contains("Log.cs"))
+ {
+ var splitIndex = pathLine.LastIndexOf(":", StringComparison.Ordinal);
+ // 脚本路径
+ var path = pathLine.Substring(0, splitIndex);
+ // 行号
+ line = Convert.ToInt32(pathLine.Substring(splitIndex + 1));
+ var fullPath = UnityEngine.Application.dataPath.Substring(0, UnityEngine.Application.dataPath.LastIndexOf("Assets", StringComparison.Ordinal));
+ fullPath = $"{fullPath}{path}";
+ // 跳转到目标代码的特定行
+ InternalEditorUtility.OpenFileAtLineExternal(fullPath.Replace('/', '\\'), line);
+ break;
+ }
+
+ matches = matches.NextMatch();
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// 获取当前日志窗口选中的日志的堆栈信息。
+ ///
+ /// 选中日志的堆栈信息实例。
+ private static string GetStackTrace()
+ {
+ // 通过反射获取ConsoleWindow类
+ var consoleWindowType = typeof(EditorWindow).Assembly.GetType("UnityEditor.ConsoleWindow");
+ // 获取窗口实例
+ var fieldInfo = consoleWindowType.GetField("ms_ConsoleWindow",
+ BindingFlags.Static |
+ BindingFlags.NonPublic);
+ if (fieldInfo != null)
+ {
+ var consoleInstance = fieldInfo.GetValue(null);
+ if (consoleInstance != null)
+ if (EditorWindow.focusedWindow == consoleInstance)
+ {
+ // 获取m_ActiveText成员
+ fieldInfo = consoleWindowType.GetField("m_ActiveText",
+ BindingFlags.Instance |
+ BindingFlags.NonPublic);
+ // 获取m_ActiveText的值
+ if (fieldInfo != null)
+ {
+ var activeText = fieldInfo.GetValue(consoleInstance).ToString();
+ return activeText;
+ }
+ }
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/UnityProject/Assets/TEngine/Editor/Utility/LogRedirection.cs.meta b/UnityProject/Assets/TEngine/Editor/Utility/LogRedirection.cs.meta
new file mode 100644
index 00000000..f7ace159
--- /dev/null
+++ b/UnityProject/Assets/TEngine/Editor/Utility/LogRedirection.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8e219db54fde57a4aae694a55da3e1b1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: