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: