ConsoleWindow中的双击日志定位

    很多项目都有自己重写Debug.Log的习惯,难免会遇到在Unity的Console窗口中双击日志, 但是没法直接跳转到想要看到的代码那一行的时候,解决办法有以下2种:

  1. 将自己封装的日志类制作成DLL再导入到Unity使用,但是有时候想修改日志类的代码却比较麻烦了~~
  2. 使用本文提供的LogEditor类来自动定位!。!下面来详细说明下该类吧~~

使用方法:

  1. 将LogEditor类的脚本放到名字为Editor的目录下(如果没有Editor目录就新建一个吧)
  2. 在这里修改和添加自己封装过的日志类(路径+类型),支持添加多个封装的日志类 
  1 using System;
  2 using System.Reflection;
  3 using UnityEditor;
  4 using UnityEngine;
  5 
  6 namespace shaco
  7 {
  8     public static class LogEditor
  9     {
 10         private class LogEditorConfig
 11         {
 12             public string logScriptPath = "";
 13             public string logTypeName = "";
 14             public int instanceID = 0;
 15 
 16             public LogEditorConfig(string logScriptPath, System.Type logType)
 17             {
 18                 this.logScriptPath = logScriptPath;
 19                 this.logTypeName = logType.FullName;
 20             }
 21         }
 22 
 23         //Add your custom Log class here
 24         private static LogEditorConfig[] _logEditorConfig = new LogEditorConfig[]
 25         {
 26             new LogEditorConfig("Assets/shaco/Base/Scripts/Unity/Debug/Log.cs", typeof(shaco.Log)),
 27             new LogEditorConfig("Assets/shaco/Base/Scripts/CSharp/Debug/Log.cs", typeof(shaco.Base.Log))
 28         };
 29 
 30         [UnityEditor.Callbacks.OnOpenAssetAttribute(-1)]
 31         private static bool OnOpenAsset(int instanceID, int line)
 32         {
 33             for (int i = _logEditorConfig.Length - 1; i >= 0; --i)
 34             {
 35                 var configTmp = _logEditorConfig[i];
 36                 UpdateLogInstanceID(configTmp);
 37                 if (instanceID == configTmp.instanceID)
 38                 {
 39                     var statckTrack = GetStackTrace();
 40                     if (!string.IsNullOrEmpty(statckTrack))
 41                     {
 42                         var fileNames = statckTrack.Split('\n');
 43                         var fileName = GetCurrentFullFileName(fileNames);
 44                         var fileLine = LogFileNameToFileLine(fileName);
 45                         fileName = GetRealFileName(fileName);
 46 
 47                         AssetDatabase.OpenAsset(AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(fileName), fileLine);
 48                         return true;
 49                     }
 50                     break;
 51                 }
 52             }
 53             
 54             return false;
 55         }
 56 
 57         private static string GetStackTrace()
 58         {
 59             var consoleWindowType = typeof(EditorWindow).Assembly.GetType("UnityEditor.ConsoleWindow");
 60             var fieldInfo = consoleWindowType.GetField("ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic);
 61             var consoleWindowInstance = fieldInfo.GetValue(null);
 62 
 63             if (null != consoleWindowInstance)
 64             {
 65                 if ((object)EditorWindow.focusedWindow == consoleWindowInstance)
 66                 {
 67                     // Get ListViewState in ConsoleWindow
 68                     // var listViewStateType = typeof(EditorWindow).Assembly.GetType("UnityEditor.ListViewState");
 69                     // fieldInfo = consoleWindowType.GetField("m_ListView", BindingFlags.Instance | BindingFlags.NonPublic);
 70                     // var listView = fieldInfo.GetValue(consoleWindowInstance);
 71 
 72                     // Get row in listViewState
 73                     // fieldInfo = listViewStateType.GetField("row", BindingFlags.Instance | BindingFlags.Public);
 74                     // int row = (int)fieldInfo.GetValue(listView);
 75 
 76                     // Get m_ActiveText in ConsoleWindow
 77                     fieldInfo = consoleWindowType.GetField("m_ActiveText", BindingFlags.Instance | BindingFlags.NonPublic);
 78                     string activeText = fieldInfo.GetValue(consoleWindowInstance).ToString();
 79 
 80                     return activeText;
 81                 }
 82             }
 83             return "";
 84         }
 85 
 86         private static void UpdateLogInstanceID(LogEditorConfig config)
 87         {
 88             if (config.instanceID > 0)
 89             {
 90                 return;
 91             }
 92 
 93             var assetLoadTmp = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(config.logScriptPath);
 94             if (null == assetLoadTmp)
 95             {
 96                 throw new System.Exception("not find asset by path=" + config.logScriptPath);
 97             }
 98             config.instanceID = assetLoadTmp.GetInstanceID();
 99         }
100 
101         private static string GetCurrentFullFileName(string[] fileNames)
102         {
103             string retValue = "";
104             int findIndex = -1;
105 
106             for (int i = fileNames.Length - 1; i >= 0; --i)
107             {
108                 bool isCustomLog = false;
109                 for (int j = _logEditorConfig.Length - 1; j >= 0; --j)
110                 {
111                     if (fileNames[i].Contains(_logEditorConfig[j].logTypeName))
112                     {
113                         isCustomLog = true;
114                         break;
115                     }
116                 }
117                 if (isCustomLog)
118                 {
119                     findIndex = i;
120                     break;
121                 }
122             }
123 
124             if (findIndex >= 0 && findIndex < fileNames.Length - 1)
125             {
126                 retValue = fileNames[findIndex + 1];
127             }
128 
129             return retValue;
130         }
131 
132         private static string GetRealFileName(string fileName)
133         {
134             int indexStart = fileName.IndexOf("(at ") + "(at ".Length;
135             int indexEnd = ParseFileLineStartIndex(fileName) - 1;
136 
137             fileName = fileName.Substring(indexStart, indexEnd - indexStart);
138             return fileName;
139         }
140 
141         private static int LogFileNameToFileLine(string fileName)
142         {
143             int findIndex = ParseFileLineStartIndex(fileName);
144             string stringParseLine = "";
145             for (int i = findIndex; i < fileName.Length; ++i)
146             {
147                 var charCheck = fileName[i];
148                 if (!IsNumber(charCheck))
149                 {
150                     break;
151                 }
152                 else
153                 {
154                     stringParseLine += charCheck;
155                 }
156             }
157 
158             return int.Parse(stringParseLine);
159         }
160 
161         private static int ParseFileLineStartIndex(string fileName)
162         {
163             int retValue = -1;
164             for (int i = fileName.Length - 1; i >= 0; --i)
165             {
166                 var charCheck = fileName[i];
167                 bool isNumber = IsNumber(charCheck);
168                 if (isNumber)
169                 {
170                     retValue = i;
171                 }
172                 else
173                 {
174                     if (retValue != -1)
175                     {
176                         break;
177                     }
178                 }
179             }
180             return retValue;
181         }
182 
183         private static bool IsNumber(char c)
184         {
185             return c >= '0' && c <= '9';
186         }
187     }
188 }

本文为转载, 原文链接:https://blog.csdn.net/l449612236/article/details/76087616

posted @ 2018-06-21 10:11  非法关键字  阅读(400)  评论(0编辑  收藏  举报