ConsoleWindow中的双击日志定位
很多项目都有自己重写Debug.Log的习惯,难免会遇到在Unity的Console窗口中双击日志, 但是没法直接跳转到想要看到的代码那一行的时候,解决办法有以下2种:
- 将自己封装的日志类制作成DLL再导入到Unity使用,但是有时候想修改日志类的代码却比较麻烦了~~
- 使用本文提供的LogEditor类来自动定位!。!下面来详细说明下该类吧~~
使用方法:
- 将LogEditor类的脚本放到名字为Editor的目录下(如果没有Editor目录就新建一个吧)
- 在这里修改和添加自己封装过的日志类(路径+类型),支持添加多个封装的日志类
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