Unity Debug Viewer by AsanCai - 3

ToolsSDKAnalytics

A powerful Unity debug tool integrated with ADB plugin

Unity 5.6.6f2Apache License 2.0Updated 27 days agoCreated on January 5th, 2020
Go to source

UnityDebugViewer

UnityDebugViewer是一个功能强大的Unity Log查看工具,它集成了Unity Console Window的所有功能,并在此基础上加入了搜索查看堆栈源码Log统计等功能。 通过使用UnityDebugViewer,无需安装Android Studio或者下载SDK就可以很方便地查看Unity在手机上输出的Log并获取相应的堆栈信息。此外,UnityDebugViewer还提供了解析Unity保存在手机上的Log文件的功能,帮助开发者使用UnityDebugViewer快速分析、定义游戏在手机上运行时遇到的问题。

支持版本

UnityDebugViewer使用Unity 5.6.6f2开发完成,能支持Unity 4.x以上版本

如何使用

方法一:

  1. 将本仓库克隆至本地
  2. UnityDebugViewer文件夹移植至项目中Assets目录下的任意文件夹
  3. 选择Window->Debug Viewer打开窗口

方法二:

  1. 下载最新版本的Package
  2. 将下载好的Package导入至项目中
  3. 选择Window->Debug Viewer打开窗口

注意:如果想要使用UnityDebugViewer提供的接口,需要避免将UnityDebugViewer存放至名称为Editor文件夹之下(包括子文件夹)

基本功能

  1. 工具栏功能:
    1. 清理log(Clear)、折叠log(Collapse)、运行时清理log(Clear On Player)、遇到error时暂停(Error Pause)和过滤log类型等Console Window具备的功能;

    2. 滚动至最新log:勾选Auto Scroll按钮,当有新的log输出至窗口时,滚动条会自动滚动至底部;

    3. 统计Log:勾选Show Analysis按钮,窗口下方会展示出当前所有log的统计信息(可以通过切换Sort Type来改变当前用于筛选log的类型,也可以在右边的搜索框输入关键词或者正则表达式进行搜索); Show Analysis

    4. 筛选log的功能

      1. 启用正则表达式搜索:选中工具栏搜索框右侧的Regex按钮,就可以输入正则表达式对log进行筛选;
      2. 显示log的时间:勾选工具栏搜索框右侧的Time按钮,将显示产生log的时间,此时可以对时间进行筛选,从而获取某个时间段内产生的所有log;

      Show Source Content

  2. 堆栈相关功能:
    1. 显示堆栈源码的功能:选中某一条log,可以展示该log的所有堆栈信息。如果堆栈包含源代码信息,且对应的文件存在,可以直接展示源码的内容;
    2. 打开堆栈源码的功能:如果log的堆栈包含源代码信息,直接用鼠标右键双击log或者堆栈,可以直接打开对应的源代码文件,并直接跳转对应的行数; Show Source Content
  3. 其他功能:
    1. 在log或者堆栈上点击鼠标右键并选择Copy,可以复制log的内容或者堆栈的完整信息;

    2. 按方向键可以当前选中的对象;

    3. 选中log时,点击鼠标中键可以快速跳转到当前选中的log;

    4. DebugViewer窗口标签页处点击鼠标右键,可以呼出窗口菜单:

      1. 选择Log Entry可以修改log框的大小;
      2. 选择Save Log可以将窗口中的log保存至指定文件;
      3. 选择About UnityDebugViewer可以打开在线文档;

      Show Menu

拓展功能

UnityDebugViewer默认提供了EditorADB ForwardADB LogcatLog File四种模式,它们分别拥有不同的拓展功能。

Editor

UnityDebugViewerEditor模式等同于Unity自带的Console Window,它能获取使用UnityEngine.Debug输出的log以及项目编译、运行时产生的告警或者异常信息。 Editor Mode

ADB Forward

UnityDebugViewerADB Forward模式集成了adb的forward指令,允许使用者通过Tcp将项目在手机上运行时产生的数据传输至UnityDebugViewer上并显示。 ADB Forward Mode

使用方式:

  1. UnityDebugViewer/Test/TestTcp.cs附加到项目初始场景的某一空物体中
  2. 在将项目构建成apk时勾选Development,然后将构建好的apk安装至安卓设备并运行
  3. 使用usb连接线将安卓设备连接至电脑,并开启开发者调试选项
  4. 根据需要修改PC Port(PC端用于数据转发的端口)和Phone Port(手机端用于数据转发的端口)
  5. 点击Start开始收集并输出log,点击Stop停止收集log

通过使用UnityDebugViewer提供的工具类,使用者可以很方便地定义并传输自定义的数据,其基本步骤如下:

  1. 定义用于Tcp传输的数据结构
[Serializable]
[StructLayoutAttribute(LayoutKind.Sequential, Pack=1)]
struct TestStruct
{
    public int c;
    /// 字符串,SizeConst为字符串的最大长度
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    public string str;
    /// int数组,SizeConst表示数组的个数
    /// 初始化的数组长度必须和SizeConst一致,例test = new int[6];
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
    public int[] test;
}
  1. 在手机端上创建Tcp Server并发送数据
    • 创建一个UnityDebugViewerTransfer实例,并调用CreateServerSocket方法创建一个Tcp Server Socket
    • 使用UnityDebugViewerTransferUtility.StructToBytes将数据结构序列化成byte数组
    • 调用UnityDebugViewerTransfer实例的SendData方法向已建立连接的Client发送数据
/// 创建一个tcp传输实例
var transfer = new UnityDebugViewerTransfer();
/// 创建一个tcp server socket并侦听50000端口
transfer.CreateServerSocket(50000);

var testData = new TestStruct();
byte[] sendData = UnityDebugViewerTransferUtility.StructToBytes(testData);
transfer.SendData(sendData);
  1. 检查adb以及设备连接状态,然后使用adb forward指令开启ADB Forward进程,并建立转发端口
private void StartADBForward()
{
    if (UnityDebugViewerWindowUtility.CheckADBStatus() == false)
    {
        return;
    }

    string adbPath = UnityDebugViewerWindowUtility.GetAdbPath();
    startForwardProcess = UnityDebugViewerADBUtility.StartForwardProcess(pcPort, phonePort, adbPath);
    /// 成功创建adb forward进程
    if (startForwardProcess)
    {
        ...
    }
}
  1. 在Editor下创建Tcp Client并接收数据
    1. 创建一个UnityDebugViewerTransfer实例,并绑定receiveDaraFromServerEvent回调事件
    2. 调用UnityDebugViewerTransfer实例的ConnectToServer方法,创建一个Tcp Client并连接到指定的Server
    3. 在receiveDaraFromServerEvent回调事件中处理从服务器收到的数据
    4. 使用UnityDebugViewerTransferUtility.BytesToStruct将byte数组反序列化为数据结构
private void ReceiveDataFromServerHandler(byte[] data)
{
    TestStruct logData = UnityDebugViewerTransferUtility.BytesToStruct<TestStruct>(data);
    ...
}

private void StartADBForward()
{
    if (UnityDebugViewerWindowUtility.CheckADBStatus() == false)
    {
        return;
    }

    string adbPath = UnityDebugViewerWindowUtility.GetAdbPath();
    startForwardProcess = UnityDebugViewerADBUtility.StartForwardProcess(pcPort, phonePort, adbPath);
    /// 成功创建adb forward进程
    if (startForwardProcess)
    {
        UnityDebugViewerTransferUtility.receiveDaraFromServerEvent += ReceiveDataFromServerHandler;
        UnityDebugViewerTransferUtility.ConnectToServer("127.0.0.1", port);
    }
}
  1. 停止ADB Forward进程,并调用UnityDebugViewerTransfer的Clear方法清理Tcp socket和侦听进程
 private void StopADBForward()
{
    string adbPath = UnityDebugViewerWindowUtility.GetAdbPath();

    UnityDebugViewerADBUtility.StopForwardProcess(adbPath);
    startForwardProcess = false;

    /// will abort process, should excute at last
    UnityDebugViewerTransferUtility.Clear();
}

说明:

  • UnityDebugViewerTransferUtility是一个在UnityDebugViewerTransfer基础上封装而成的工具类,它管理一个静态UnityDebugViewerTransfer实例,并提供了许多在使用UnityDebugViewerTransfer时会用到的公共接口
  • UnityDebugViewerTransferUtility封装了UnityDebugViewerTransfer的所有公有属性和方法,在大部分情况下,可以直接将UnityDebugViewerTransferUtility当成UnityDebugViewerTransfer实例使用
  • 但如果需要同时使用多个UnityDebugViewerTransfer实例,则需要自己创建UnityDebugViewerTransfer实例并进行管理

Assets/Test/TestTcp.cs提供了如何获取、转发log数据的例子,关于如何添加一个自定义模式用于展示自定义数据,详见添加自定义的模式

using UnityEngine;

namespace UnityDebugViewer
{
    public class TestTcp : MonoBehaviour
    {
        private UnityDebugViewerTransfer transfer;
        private void Awake()
        {
            /// 创建一个tcp传输实例
            transfer = new UnityDebugViewerTransfer();
            /// 创建一个tcp server socket并侦听50000端口
            transfer.CreateServerSocket(50000);

            /// 开始收集log信息
            Application.logMessageReceivedThreaded += CaptureLogThread;

            DontDestroyOnLoad(this.gameObject);
        }

        private void OnDestroy()
        {
            Application.logMessageReceivedThreaded -= CaptureLogThread;
            transfer.Clear();
        }

        private void CaptureLogThread(string info, string stacktrace, UnityEngine.LogType type)
        {
            if (transfer == null)
            {
                return;
            }
            lock (transfer)
            {
                /// 将收集到的log数据序列化成byte[]
                /// 并转发至连接到指定端口的tcp client socket
                var logData = new TransferLogData(info, stacktrace, type);
                byte[] sendData = UnityDebugViewerTransferUtility.StructToBytes(logData);
                transfer.SendData(sendData);
            }
        }
    }
}

ADB Logcat

UnityDebugViewerADB Logcat模式集成了adb的logcat命令,无需安装Android Studio或者配置SDK环境,只需要使用usb线将手机连接至电脑,就可以直接看到项目在手机上运行时输出的所有log以及产生log的堆栈信息。 ADB Logcat Mode

使用方式:

  1. 在已开启开发者调试选项的安卓设备上运行项目
  2. 使用usb连接线将安卓设备连接至电脑
  3. 修改Tag Filter以指定使用logcat命令获取哪些log信息
    • Tag FilterUnity表示只捕获Unity生成的log
    • Tag Filter为空表示捕获安卓系统产生的所有log
  4. 点击Start开始从手机上捕获log并输出至窗口,点击Stop停止捕获log;

Log File

UnityDebugViewerLog File模式提供了解析log文件的功能,其能解析的log格式与UnityDebugViewer将log保存至文件时使用的格式一致,如下所示:

[log类型] 时间 log内容
堆栈信息
  • log类型可以是LogWarning或者Error,不区分大小写
  • log内容可以输入任何符号
  • 堆栈信息可以为空 Log File Mode

添加自定义模式

除了使用UnityDebugViewer提供的四种默认模式,UnityDebugViewer还允许使用者根据实际的需求添加自定义的模式。添加自定义模式的步骤并不复杂,如下所示:

  1. 在任一Editor文件夹下创建一个继承自UnityDebugViewer.UnityDebugViewerIntermediaryEditor的类
  2. 使用[InitializeOnLoadMethod]标记一个静态方法作为初始化入口
  3. 在初始化入口中使用UnityDebugViewerEditorManager.RegisterMode方法注册自定义模式

    UnityDebugViewerEditorManager.RegisterMode<T>(string mode, int order)
    T: UnityDebugViewerIntermediaryEditor或者其子类

    参数:

    mode: 自定义模式的名称

    order: 自定义模式的权重,用于决定其在下拉列表中的显示顺序。如果权重相同,则会根据注册的顺序来显示

  4. 覆写UnityDebugViewer.UnityDebugViewerIntermediaryEditor提供的方法:
    1. Clear:点击工具栏的Clear按钮时被调用
    2. OnGUI:在绘制工具栏时被调用,可用于在工具栏上绘制自定义的UI
    3. StartCompiling:项目开始编译时被调用,可用于清理线程等数据
  5. 使用UnityDebugViewerLogger.LogUnityDebugViewerLogger.LogWarning或者UnityDebugViewerLogger.LogError方法将log输出至自定义模式对应的UnityDebugViewerEditor上

为了方便使用者快速掌握如何添加自定义的模式,UnityDebugViewer提供了UnityDebugViewer/Test/Editor/TestCustomMode.cs作为添加自定义模式的例子。以下是TestCustomMode.cs的内容和详细注释,它包括了添加自定义模式的所有步骤。 Custom Mode

using UnityEngine;
using UnityEditor;

namespace UnityDebugViewer
{
    public class TestCustomMode : UnityDebugViewerIntermediaryEditor
    {
        /// <summary>
        /// 模式的名称
        /// </summary>
        private const string MODE_NAME = "TestCustomMode";

        /// <summary>
        /// 标记初始化的入口
        /// </summary>
        [InitializeOnLoadMethod]
        private static void InitializeTestCustomMode()
        {
            /// 自定义模式的权重,用于决定其在下拉列表中的显示顺序
            int order = 10;

            /// 添加自定义的模式
            UnityDebugViewerEditorManager.RegisterMode<TestCustomMode>(MODE_NAME, order);
        }

        /// <summary>
        /// 在点击Clear按钮时被调用
        /// </summary>
        public override void Clear()
        {
            base.Clear();

            UnityDebugViewerLogger.Log("Clear", MODE_NAME);
        }

        /// <summary>
        /// 在下拉列表中选择当前的模式时被调用
        /// </summary>
        public override void OnGUI()
        {
            base.OnGUI();

            if (GUILayout.Button(new GUIContent("Add Log"), EditorStyles.toolbarButton))
            {
                UnityDebugViewerLogger.Log("Add Log", MODE_NAME);
            }
        }

        /// <summary>
        /// 在脚本开始编译时被调用
        /// </summary>
        public override void StartCompiling()
        {
            base.StartCompiling();

            UnityDebugViewerLogger.Log("StartCompiling", MODE_NAME);
        }
    }
}
Show all projects by AsanCai