Unity ConsoleLog双击重定向

在一个标准的开发流程中,unity原生的Log可能无法满足所有需求

于是我们需要定制自己的Log类

 

比如一个打印不同颜色信息的简单需求:

 public class Log
 {
    public void Debug(string format,params object[] args)
    {
        UnityEngine.Debug.Log(string.Format(@"[DEBUG][{0}]",args));
    }

    public void Info(string format,params object[] args)
    {
        UnityEngine.Debug.Log(string.Format("[INFO][{0}]",args));
    }

    public void Warn(string format,params object[] args)
    {
        UnityEngine.Debug.LogWarning(
            string.Format("[WARN][{0}]", args));
    }
}

 

使用Log类,Console窗口的debug确实有了颜色

但接着就会产生一个问题,双击log信息后的脚本跳转不在我们期望的位置

unity本身的支持的跳转是到调用Debug的地方,也就是说只会跳到我们这个Log类中的对应方法

 

这个时候,需要重定向跳转位置

 

1.获取console窗口当前选中条目的调用栈信息

 由于官方没有开放ConsoleWindow相关api,这一部分是通过反射去完成的

private static string GetStackTrace()
{
    var editorWindowAssembly = typeof(EditorWindow).Assembly;
    var consoleWindowType =editorWindowAssembly.GetType("UnityEditor.ConsoleWindow");
    
    var consoleWindowFieldInfo = consoleWindowType.GetField(
                        "ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic);

    var consoleWindow = consoleWindowFieldInfo.GetValue(null) as EditorWindow;

    if (consoleWindow != EditorWindow.focusedWindow)
    {
        return null;
    }

    var activeTextFieldInfo = consoleWindowType.GetField(
                           "m_ActiveText", BindingFlags.Instance | BindingFlags.NonPublic);

    return (string)activeTextFieldInfo.GetValue(consoleWindow);
}



 

2.添加回调方法

给方法加上此属性,会在unity尝试打开Asset资源时回调到这个方法

添加OnOpenAsset属性的方法收到两个参数:要打开的资产对应的id和行数

OnOpenAssetAttribute
//用正则来匹配对应的文件名和行号
private static readonly Regex LogRegex = new Regex(@" \(at (.+)\:(\d+)\)\r?\n");
//我们Log类所在的脚本名称,用来比较调用信息,判断log信息是否由自定义Log类打印
private static readonly string KeyCs = "Log.cs";


[OnOpenAsset(0)]
static bool ReposLog(int instanceID, int line)
{
    var trackInfo = GetStackTrace();

    if (string.IsNullOrEmpty(trackInfo) || !trackInfo.Contains(KeyCs)) return false;

    var match = LogRegex.Match(trackInfo);
    if (!match.Success) return false;

    match = match.NextMatch();
    if (!match.Success) return false;

    var file = match.Groups[1].Value;
    var lineId = int.Parse(match.Groups[2].Value);

    InternalEditorUtility.OpenFileAtLineExternal(
                              Path.Combine(GetProjectPath(), file),lineId);
    return true;
}



//获取当前的Project目录
private static string GetProjectPath()
{
    var di = new DirectoryInfo(Application.dataPath);
    return di.Parent.FullName;
}

 

双击Log信息就可以正常跳转了

你可能感兴趣的:(Unity,Unity)