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

来源:互联网 发布:江苏省困难职工数据库 编辑:程序博客网 时间:2024/06/03 18:16

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


1、将自己封装的日志类制作成DLL再导入到Unity使用,但是有时候想修改日志类的代码却比较麻烦了~~

2、使用本文提供的LogEditor类来自动定位!。!下面来详细说明下该类吧~~


使用方法:

1、将LogEditor类的脚本放到名字为Editor的目录下(如果没有Editor目录就新建一个吧)

2、在这里修改和添加自己封装过的日志类(路径+类型),支持添加多个封装的日志类


3、现在可以直接在Console窗口中双击日志,就会自动跳转到调用自己封装日志类的代码位置啦~


附上源代码:

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<UnityEngine.Object>(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<UnityEngine.Object>(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';        }    }}

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

原创粉丝点击