Unity编辑器扩展-ConsoleWindow中的双击日志定位

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

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

使用方法:
1、将LogEditor类的脚本放到名字为Editor的目录下(如果没有Editor目录就新建一个吧)
2、在这里修改和添加自己封装过的日志类(路径+类型),支持添加多个封装的日志类

3、现在可以直接在Console窗口中双击日志,就会自动跳转到调用自己封装日志类的代码位置啦~
Unity编辑器扩展-ConsoleWindow中的双击日志定位_第1张图片

附上源代码:

using System;  
using System.Reflection;  
using UnityEditor;  
using UnityEngine;  
  
namespace shaco  
{  
    public static class LogEditor  
    {  
        private class LogEditorConfig  
        {  
            public string logScriptPath = "";  
            public string logTypeName = "";  
            public int instanceID = 0;  
  
            public LogEditorConfig(string logScriptPath, System.Type logType)  
            {  
                this.logScriptPath = logScriptPath;  
                this.logTypeName = logType.FullName;  
            }  
        }  
  
        //Add your custom Log class here  
        private static LogEditorConfig[] _logEditorConfig = new LogEditorConfig[]  
        {  
            new LogEditorConfig("Assets/shaco/Base/Scripts/Unity/Debug/Log.cs", typeof(shaco.Log)),  
            new LogEditorConfig("Assets/shaco/Base/Scripts/CSharp/Debug/Log.cs", typeof(shaco.Base.Log))  
        };  
  
        [UnityEditor.Callbacks.OnOpenAssetAttribute(-1)]  
        private static bool OnOpenAsset(int instanceID, int line)  
        {  
            for (int i = _logEditorConfig.Length - 1; i >= 0; --i)  
            {  
                var configTmp = _logEditorConfig[i];  
                UpdateLogInstanceID(configTmp);  
                if (instanceID == configTmp.instanceID)  
                {  
                    var statckTrack = GetStackTrace();  
                    if (!string.IsNullOrEmpty(statckTrack))  
                    {  
                        var fileNames = statckTrack.Split('\n');  
                        var fileName = GetCurrentFullFileName(fileNames);  
                        var fileLine = LogFileNameToFileLine(fileName);  
                        fileName = GetRealFileName(fileName);  
  
                        AssetDatabase.OpenAsset(AssetDatabase.LoadAssetAtPath(fileName), fileLine);  
                        return true;  
                    }  
                    break;  
                }  
            }  
              
            return false;  
        }  
  
        private static string GetStackTrace()  
        {  
            var consoleWindowType = typeof(EditorWindow).Assembly.GetType("UnityEditor.ConsoleWindow");  
            var fieldInfo = consoleWindowType.GetField("ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic);  
            var consoleWindowInstance = fieldInfo.GetValue(null);  
  
            if (null != consoleWindowInstance)  
            {  
                if ((object)EditorWindow.focusedWindow == consoleWindowInstance)  
                {  
                    // Get ListViewState in ConsoleWindow  
                    // var listViewStateType = typeof(EditorWindow).Assembly.GetType("UnityEditor.ListViewState");  
                    // fieldInfo = consoleWindowType.GetField("m_ListView", BindingFlags.Instance | BindingFlags.NonPublic);  
                    // var listView = fieldInfo.GetValue(consoleWindowInstance);  
  
                    // Get row in listViewState  
                    // fieldInfo = listViewStateType.GetField("row", BindingFlags.Instance | BindingFlags.Public);  
                    // int row = (int)fieldInfo.GetValue(listView);  
  
                    // Get m_ActiveText in ConsoleWindow  
                    fieldInfo = consoleWindowType.GetField("m_ActiveText", BindingFlags.Instance | BindingFlags.NonPublic);  
                    string activeText = fieldInfo.GetValue(consoleWindowInstance).ToString();  
  
                    return activeText;  
                }  
            }  
            return "";  
        }  
  
        private static void UpdateLogInstanceID(LogEditorConfig config)  
        {  
            if (config.instanceID > 0)  
            {  
                return;  
            }  
  
            var assetLoadTmp = AssetDatabase.LoadAssetAtPath(config.logScriptPath);  
            if (null == assetLoadTmp)  
            {  
                throw new System.Exception("not find asset by path=" + config.logScriptPath);  
            }  
            config.instanceID = assetLoadTmp.GetInstanceID();  
        }  
  
        private static string GetCurrentFullFileName(string[] fileNames)  
        {  
            string retValue = "";  
            int findIndex = -1;  
  
            for (int i = fileNames.Length - 1; i >= 0; --i)  
            {  
                bool isCustomLog = false;  
                for (int j = _logEditorConfig.Length - 1; j >= 0; --j)  
                {  
                    if (fileNames[i].Contains(_logEditorConfig[j].logTypeName))  
                    {  
                        isCustomLog = true;  
                        break;  
                    }  
                }  
                if (isCustomLog)  
                {  
                    findIndex = i;  
                    break;  
                }  
            }  
  
            if (findIndex >= 0 && findIndex < fileNames.Length - 1)  
            {  
                retValue = fileNames[findIndex + 1];  
            }  
  
            return retValue;  
        }  
  
        private static string GetRealFileName(string fileName)  
        {  
            int indexStart = fileName.IndexOf("(at ") + "(at ".Length;  
            int indexEnd = ParseFileLineStartIndex(fileName) - 1;  
  
            fileName = fileName.Substring(indexStart, indexEnd - indexStart);  
            return fileName;  
        }  
  
        private static int LogFileNameToFileLine(string fileName)  
        {  
            int findIndex = ParseFileLineStartIndex(fileName);  
            string stringParseLine = "";  
            for (int i = findIndex; i < fileName.Length; ++i)  
            {  
                var charCheck = fileName[i];  
                if (!IsNumber(charCheck))  
                {  
                    break;  
                }  
                else  
                {  
                    stringParseLine += charCheck;  
                }  
            }  
  
            return int.Parse(stringParseLine);  
        }  
  
        private static int ParseFileLineStartIndex(string fileName)  
        {  
            int retValue = -1;  
            for (int i = fileName.Length - 1; i >= 0; --i)  
            {  
                var charCheck = fileName[i];  
                bool isNumber = IsNumber(charCheck);  
                if (isNumber)  
                {  
                    retValue = i;  
                }  
                else  
                {  
                    if (retValue != -1)  
                    {  
                        break;  
                    }  
                }  
            }  
            return retValue;  
        }  
  
        private static bool IsNumber(char c)  
        {  
            return c >= '0' && c <= '9';  
        }  
    }  
}  

如果感兴趣的话请多多支持下吧~~~

原文章转自:http://blog.csdn.net/l449612236/article/details/76087616

你可能感兴趣的:(Unity编辑器扩展-ConsoleWindow中的双击日志定位)