NoiseFloor 发表于 2022-12-24 12:53

Unity 封装Debug.Log,代码重定向行号

封装Debug.Log,代码重定向

封装Debug.Log之后,双击ConsoleWindow,代码跳转到自定义的封装类.使用如下代码,即可跳转到正确行号.
Unity版本:2021.3.10f1
private static Type m_ConsoleWindow;

       //1 : 使用OnOpenAsset属性 接管当有资源打开时的操作
      private static bool OnOpenAssetSoundLog(int instanceID)
      {
            var asset = AssetDatabase.GetAssetPath(instanceID);
            if (!asset.Contains("/SoundLog/SoundLog.cs"))//SoundLog.cs 是笔者封装Debug.Log的MonoScripts文件这里进行筛选
            {
                return false;
            }

            if (m_ConsoleWindow == null) //反射出ConsoleWindow类
            {
                m_ConsoleWindow = Type.GetType("UnityEditor.ConsoleWindow,UnityEditor");
            }

            if (EditorWindow.focusedWindow.GetType() != m_ConsoleWindow)
            {
                return false;
            }

            var activeText =
                m_ConsoleWindow?.GetField("m_ActiveText", BindingFlags.Instance | BindingFlags.NonPublic);//m_ActiveText包含了当前Log的全部信息
            var consoleWindowFiledInfo =
                m_ConsoleWindow?.GetField("ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic);//ms_ConsoleWindow 是ConsoleWindow的对象字段
            var consoleWindowInstance = consoleWindowFiledInfo?.GetValue(null);//从对象字段中得到这个对象
            var str = activeText?.GetValue(consoleWindowInstance).ToString();//得到Log信息,用于后面解析

            var (path, lineIndex) = GetSubStringInStackStr(str, 1);//解析出对应的.cs文件全路径和 行号因为笔者的Log第二个cs文件即正确位置所以参数传1
            if (lineIndex == -1)
                return false;

            UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(path, lineIndex);//跳转到正确行号
            return true;
      }
解析log的信息,得到.cs文件和行号:
                /// <summary>
                /// 这个方法主要是参考 unity源码ConsoleWindow中的StacktraceWithHyperlinks函数
                /// </summary>
                /// <param name="stackStr"></param>
                /// <param name="needIndex"></param>
                /// <returns></returns>
      private static (string, int) GetSubStringInStackStr(string stackStr, int needIndex)
      {
            var lines = stackStr.Split(new string[] {"\n"}, StringSplitOptions.None);

            var tempIndex = 0;
            var count = lines.Length;
            for (int i = 0; i < count; i++)
            {
                string textBeforeFilePath = ") (at ";
                int filePathIndex = lines.IndexOf(textBeforeFilePath, StringComparison.Ordinal);
                if (filePathIndex > 0)
                {
                  filePathIndex += textBeforeFilePath.Length;
                  if (lines != '<')
                  {
                        string filePathPart = lines.Substring(filePathIndex);
                        int lineIndex = filePathPart.LastIndexOf(":", StringComparison.Ordinal);
                        if (lineIndex > 0)
                        {
                            int endLineIndex = filePathPart.LastIndexOf(")", StringComparison.Ordinal);
                            if (endLineIndex > 0)
                            {
                              string lineString =
                                    filePathPart.Substring(lineIndex + 1, (endLineIndex) - (lineIndex + 1));
                              string filePath = filePathPart.Substring(0, lineIndex);
                              if (tempIndex++ >= needIndex)
                              {
                                    return (filePath, int.Parse(lineString));
                              }
                            }
                        }
                  }
                }
            }

            return ("", -1);
      }
页: [1]
查看完整版本: Unity 封装Debug.Log,代码重定向行号