您的位置:首页 > 移动开发 > Unity3D

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

2017-07-25 17:21 281 查看
很多项目都有自己重写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
//
4000
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';
}
}
}


如果感兴趣的话请多多支持下吧~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: