zoukankan      html  css  js  c++  java
  • Unity3D中Console控制台的扩展

    Assert Store上有一个Editor Console Pro,功能非常全面,百度也能搜到破解。如果有需要建议使用,不要再造车轮

    起初因为自带Console功能太弱,有不少可以提升空间。于是尝试自己写,可是写到后面发现上面那个工具。。大致原理明白之后发上来分享一下。

    =======================================

    读到Log信息,有两个方法

    1.Application.RegisterLogCallback

    可惜是运行时用的,Editor下需要创建一个GameObject绑上运行时脚本,还有一个很严重的问题,就是会占用其他的回调注册,或者被占用而读不到Log。

    2.调用内部类LogEntries

    在看EditorConsolePro源码时发现它这么用,很奇怪这个类Unity官方没完全开放出来,在UnityEditorInternal.LogEtries下,只能通过反射调用。Unity官方论坛的资料也很少

    -------------------------------------------------------

    在尝试第一种方法无果之后,选用第二种方法。

    ILSpy里稍微看了下

    GetCount()可以直接得到Log的总数

    bool GetEntryInternal(int,LogEntry) 可以得到详细的Title和stack信息。

    int StartGettingEntries()和void EndGettingEntries()在取值的时候需要调用两个方法包围取值代码,否则会报指针错误。

    SetConsoleFlag(int,bool)可以屏蔽Warning,Error之类的,和自带Console一样。

    Clear()也是自带Console的Clear。

    取值代码如下

    string GetSourceText(int row)
    {
        var LogEntriesType = typeof(EditorWindow).Assembly.GetType("UnityEditorInternal.LogEntries");
        var startGettingEntriesMethod = LogEntriesType.GetMethod("StartGettingEntries", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
        var endGettingEntriesMethod = LogEntriesType.GetMethod("EndGettingEntries", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
    
        startGettingEntriesMethod.Invoke(null, new object[0]);
        var GetEntryInternalMethod = LogEntriesType.GetMethod("GetEntryInternal", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
        var logEntryType = typeof(EditorWindow).Assembly.GetType("UnityEditorInternal.LogEntry");
    
        var logEntry = Activator.CreateInstance(logEntryType);
        //Get detail debug info.
        GetEntryInternalMethod.Invoke(null, new object[2] { row, logEntry });
        //More info please search "UnityEditorInternal.LogEntry" class of ILSPY.
        var fieldInfo = logEntryType.GetField("condition", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        var result = fieldInfo.GetValue(logEntry).ToString();
        endGettingEntriesMethod.Invoke(null, new object[0]);
        return result;
    }
    
    int GetCount()
    {
        var debugType = typeof(EditorWindow).Assembly.GetType("UnityEditorInternal.LogEntries");
        var methodInfo = debugType.GetMethod("GetCount", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
        return (int)methodInfo.Invoke(null, new object[0]);
    }
    View Code

    调用GetEntryInternal取到的Log会返回LogEntry class结构,其中condition是栈跟踪信息。

    然后遇到第二个问题,读到的Log信息始终都是最末输出的那个。

    查了一下发现是用GetStatusTest()来读的Title,只能读到最后一行,似乎Unity内部输出Debug信息是在另一个线程里,才导致这个问题。

    于是对每次得到的Count和上一次的Count值对比重新遍历,以输出所有的信息。

    还需要加Count数的改变判断,不会像注册Log回调那样直接给你每条Log

    点击具体Log跳转到IDE指定行数,调用这个接口

    InternalEditorUtility.OpenFileAtLineExternal(Path, Line);

    这样的话,可以做到对Console过滤,加标签。

    具体就写到这里

  • 相关阅读:
    25个可遇不可求的jQuery插件
    微网站|h5弹窗|手机网站 html5 弹窗、弹层、提示框、加载条
    逻辑设计--每一层的验证策略
    [傅里叶变换及其应用学习笔记] 八. 时延性,尺度变化,卷积
    [傅里叶变换及其应用学习笔记] 七. 傅里叶正(反)变换复习
    [傅里叶变换及其应用学习笔记] 六. 热方程讨论
    [傅里叶变换及其应用学习笔记] 五. 傅里叶级数连续性讨论,热方程
    [傅里叶变换及其应用学习笔记] 四. 傅里叶级数
    [傅里叶变换及其应用学习笔记] 三. 复习,将一般周期函数表示成简单周期函数和
    [傅里叶变换及其应用学习笔记] 二. 周期性,三角函数表示复杂函数
  • 原文地址:https://www.cnblogs.com/hont/p/3751628.html
Copyright © 2011-2022 走看看