kyuskoj 发表于 2022-1-24 16:20

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]
查看完整版本: Tolua Log跳转 xlua日志