109 lines
4.0 KiB
C#
109 lines
4.0 KiB
C#
using System;
|
|
using UnityEditor;
|
|
using System.Reflection;
|
|
using System.Text.RegularExpressions;
|
|
using UnityEditor.Callbacks;
|
|
using UnityEditorInternal;
|
|
using UnityEngine;
|
|
|
|
namespace AlicizaX.Editor
|
|
{
|
|
public static class OpenAssetLogLine
|
|
{
|
|
[OnOpenAsset(0)]
|
|
private static bool OnOpenAsset(int instanceID, int line)
|
|
{
|
|
if (line <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
// 获取资源路径
|
|
string assetPath = AssetDatabase.GetAssetPath(instanceID);
|
|
|
|
// 判断资源类型
|
|
if (!assetPath.EndsWith(".cs"))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool autoFirstMatch = assetPath.Contains("Log.cs");
|
|
|
|
var stackTrace = GetStackTrace();
|
|
if (!string.IsNullOrEmpty(stackTrace) && stackTrace.Contains("Log.cs"))
|
|
|
|
{
|
|
if (!autoFirstMatch)
|
|
{
|
|
var fullPath = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("Assets", StringComparison.Ordinal));
|
|
fullPath = $"{fullPath}{assetPath}";
|
|
// 跳转到目标代码的特定行
|
|
InternalEditorUtility.OpenFileAtLineExternal(fullPath.Replace('/', '\\'), line);
|
|
return true;
|
|
}
|
|
|
|
// 使用正则表达式匹配at的哪个脚本的哪一行
|
|
var matches = Regex.Match(stackTrace, @"\(at (.+)\)",
|
|
RegexOptions.IgnoreCase);
|
|
while (matches.Success)
|
|
{
|
|
var pathLine = matches.Groups[1].Value;
|
|
|
|
if (!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 = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("Assets", StringComparison.Ordinal));
|
|
fullPath = $"{fullPath}{path}";
|
|
// 跳转到目标代码的特定行
|
|
InternalEditorUtility.OpenFileAtLineExternal(fullPath.Replace('/', '\\'), line);
|
|
break;
|
|
}
|
|
|
|
matches = matches.NextMatch();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取当前日志窗口选中的日志的堆栈信息。
|
|
/// </summary>
|
|
/// <returns>选中日志的堆栈信息实例。</returns>
|
|
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 == (EditorWindow)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;
|
|
}
|
|
}
|
|
}
|