Tolua Log跳转 xlua日志
效果image-20211223185617831.png
双击便弹出lua堆栈
点击即可跳转到对应位置
原cs日志跳转不影响
LuaLogLocate.cs
using System;using System.Collections.Generic;using System.IO;using System.Reflection;using System.Text;using System.Text.RegularExpressions;using UnityEditor;using UnityEngine;public class PathLine{ public PathLine(string s, int l) { path = s; line = l; } public string path { get; set; } public int line { get; set; } public override string ToString() { return $"{path.Substring(path.LastIndexOf('/') + 1)}:{line}"; }};public class LuaLogLocate{ private static string[] luaRootPaths = { "Assets/LuaFramework/Lua/", "Assets/LuaFramework/ToLua/Lua/", }; // 处理asset打开的callback函数 static bool OnOpenAsset(int instance, int line) { //获取资源根目录 string assetsPath = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("Assets", StringComparison.Ordinal)); StringBuilder fileFullPathBuilder = new StringBuilder(); //获取Console中的tolua调用堆栈 string stackTrace = GetStackTrace(); string name = EditorUtility.InstanceIDToObject(instance).name; if (stackTrace == null || !stackTrace.Contains("stack traceback:")) return false; MatchCollection csharpMatchs = Regex.Matches(stackTrace, @"\(at.*\)"); if (!csharpMatchs.Value.Contains(name)) return false; MatchCollection luaMatchs = Regex.Matches(stackTrace, @"\t.*:\d+:"); List<PathLine> pathLines = new List<PathLine>(); foreach (Match luaMatch in luaMatchs) { string[] strs; if (luaMatch.Value.Contains("\t:165: in function 'func' string temp = luaMatch.Value .Replace("\t", ""); strs = temp.Substring(1, temp.Length - 1).Split(':'); } else { strs = luaMatch.Value.Substring(1, luaMatch.Value.Length - 1).Split(':'); } foreach (string luaRootPath in luaRootPaths) { fileFullPathBuilder.Clear(); fileFullPathBuilder.Append(assetsPath); fileFullPathBuilder.Append(luaRootPath); fileFullPathBuilder.Append(strs); if (!strs.EndsWith(".lua")) fileFullPathBuilder.Append(".lua"); if (File.Exists(fileFullPathBuilder.ToString())) { pathLines.Add(new PathLine(fileFullPathBuilder.ToString(), Int32.Parse(strs))); break; } } } //最顶层报错cs文件 var strs2 = csharpMatchs.Value.Substring(4, csharpMatchs.Value.Length - 5).Split(':'); fileFullPathBuilder.Clear(); fileFullPathBuilder.Append(assetsPath); fileFullPathBuilder.Append(strs2); if (!strs2.EndsWith(".cs")) fileFullPathBuilder.Append(".cs"); pathLines.Add(new PathLine(fileFullPathBuilder.ToString(), Int32.Parse(strs2))); //可跳转路径 Vector2 currentMousePosition = Event.current.mousePosition; Rect contextRect = new Rect(currentMousePosition.x, currentMousePosition.y, 0, 0); List<GUIContent> options = new List<GUIContent>(); foreach (PathLine pathLine in pathLines) { options.Add(new GUIContent(pathLine.ToString())); } EditorUtility.DisplayCustomMenu(contextRect, options.ToArray(), -1, Select, pathLines); return true; } private static void OpenFileLine(PathLine pathLine) { UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(pathLine.path, pathLine.line); } private static void Select(object userData, string[] options, int selected) { List<PathLine> pathLines = (List<PathLine>) userData; PathLine selectedPathLine = pathLines; OpenFileLine(selectedPathLine); } static string GetStackTrace() { // 找到UnityEditor.EditorWindow的assembly var assembly_unity_editor = Assembly.GetAssembly(typeof(UnityEditor.EditorWindow)); if (assembly_unity_editor == null) return null; // 找到类UnityEditor.ConsoleWindow var type_console_window = assembly_unity_editor.GetType("UnityEditor.ConsoleWindow"); if (type_console_window == null) return null; // 找到UnityEditor.ConsoleWindow中的成员ms_ConsoleWindow var field_console_window = type_console_window.GetField("ms_ConsoleWindow", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic); if (field_console_window == null) return null; // 获取ms_ConsoleWindow的值 var instance_console_window = field_console_window.GetValue(null); if (instance_console_window == null) return null; // 如果console窗口时焦点窗口的话,获取stacktrace if (EditorWindow.focusedWindow == instance_console_window) { // 通过assembly获取类ListViewState var type_list_view_state = assembly_unity_editor.GetType("UnityEditor.ListViewState"); if (type_list_view_state == null) return null; // 找到类UnityEditor.ConsoleWindow中的成员m_ListView var field_list_view = type_console_window.GetField("m_ListView", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); if (field_list_view == null) return null; // 获取m_ListView的值 var value_list_view = field_list_view.GetValue(instance_console_window); if (value_list_view == null) return null; // 找到类UnityEditor.ConsoleWindow中的成员m_ActiveText var field_active_text = type_console_window.GetField("m_ActiveText", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); if (field_active_text == null) return null; // 获得m_ActiveText的值,就是我们需要的stacktrace string value_active_text = field_active_text.GetValue(instance_console_window).ToString(); return value_active_text; } return null; }}Unity菜单->Edit->Preferences
VSCode需修改External Tools,保存当前Vscode 项目工作区,替换路径
添加lua类型至Extentions Handler
image-20211223190146990.png
页:
[1]