Unity输出带点击跳转功能的Log实现技巧详解

Unity输出带点击跳转功能的Log实现技巧详解

在Unity开发中,我们经常需要输出Log信息来检查程序运行的过程,但是在大项目中,很难快速定位到特定的代码行,于是带有点击跳转功能的Log输出就显得尤为重要。本文将详细介绍如何实现带有点击跳转功能的Log输出。

1. 前提条件

在实现具有点击跳转功能的Log输出之前,我们需要确保我们已经掌握了以下基础知识:

  • C#语言基础
  • Unity引擎基础

2. 实现步骤

2.1 封装Log输出函数

首先,我们需要封装一个具有点击跳转功能的Log输出函数,在输出Log信息的同时,我们需要将当前代码的调用栈信息记录下来,以便在点击Log信息时能够跳转到对应的代码行。

public static class DebugUtils
{
    public static void Log(string msg, [CallerFilePath] string path = "", [CallerLineNumber] int line = 0)
    {
        string logInfo = $"{Path.GetFileName(path)}:{line} {msg}";
        Debug.Log(logInfo);
    }
}

这里通过使用[CallerFilePath][CallerLineNumber]属性,获取当前代码的文件路径和行号信息,并使用$占位符字符串拼接方式,将消息内容和当前代码的调用栈信息合并成了一条Log信息。

2.2 为Log信息添加跳转功能

接下来,我们需要为输出的Log信息添加点击跳转功能。通常情况下,我们点击Log信息只能跳转到当前Log信息输出的位置,而无法跳转到真正的错误发生位置。因此,在Log信息的每个调用栈信息中都需要包含文件名、行号和方法名等信息,以便在点击时精确定位到错误发生的位置。

Unity提供了一个APIUnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(string fileName, int line),可以在外部编辑器中打开指定文件并跳转到指定行号的位置。我们可以在点击Log信息时,根据Log信息中记录的文件名和行号信息,调用该API打开代码文件并跳转到指定的行号。

using UnityEditorInternal;
using System.Diagnostics;

public static void Log(string msg, [CallerFilePath] string path = "", [CallerLineNumber] int line = 0, [CallerMemberName] string member = "")
{
    string fileName = Path.GetFileName(path);
    string logInfo = $"{fileName}:{line} {msg}";
    Debug.Log(logInfo);

    StackTrace stackTrace = new StackTrace(true);
    for (int i = 0; i < stackTrace.FrameCount; i++)
    {
        StackFrame stackFrame = stackTrace.GetFrame(i);

        string stackFileName = stackFrame.GetFileName();
        if (stackFileName != null && stackFileName.EndsWith(fileName))
        {
            int stackLine = stackFrame.GetFileLineNumber();

            string method = stackFrame.GetMethod().Name;
            string stackInfo = $"{stackFileName}:{stackLine} {method}";

            logInfo += $"\n\tat {stackInfo}";
            logInfo += (stackLine == line && member == method) ? " <- THIS" : "";
        }
    }

    Debug.Log(logInfo);

    EditorGUIUtility.AddCursorRect(
        GUILayoutUtility.GetLastRect(),
        MouseCursor.Link
    );

    if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
    {
        for (int i = 0; i < stackTrace.FrameCount; i++)
        {
            StackFrame stackFrame = stackTrace.GetFrame(i);
            string stackFileName = stackFrame.GetFileName();
            if (stackFileName != null && stackFileName.EndsWith(fileName))
            {
                int stackLine = stackFrame.GetFileLineNumber();
                string method = stackFrame.GetMethod().Name;

                if (stackLine == line && member == method)
                {
                    string fullPath = Path.GetFullPath(stackFileName);
                    InternalEditorUtility.OpenFileAtLineExternal(fullPath, stackLine);
                }
            }
        }
    }
}

在上面的代码中,我们使用了System.Diagnostics.StackTrace类获取了完整的调用栈信息,然后遍历每个调用栈信息,将每个调用栈信息都添加在Log信息中,并在当前的调用栈信息中添加一个“<- THIS”的标记。在输出Log信息时,我们使用GUILayoutUtility.GetLastRect()方法获取最后一次通过GUILayout函数创建的GUI矩形区域,然后使用EditorGUIUtility.AddCursorRect()方法为该区域添加鼠标光标标志,以表明该区域支持鼠标点击事件。如果检测到鼠标左键按下事件,就遍历调用栈信息,找到对应的代码文件名和行号信息,并使用InternalEditorUtility.OpenFileAtLineExternal()方法打开对应的编辑器并跳转到指定的行号。

2.3 示例

下面是一个简单的示例,我们可以在一个按钮点击事件中调用我们的Log输出函数来输出信息,并且可以在点击Log信息时跳转到真正的错误代码行。

public class Example : MonoBehaviour
{
    void OnGUI()
    {
        if (GUILayout.Button("Test"))
        {
            DoTest();
        }
    }

    void DoTest()
    {
        DebugUtils.Log("Test Log");
        DebugUtils.Log("Test Log with Call Stack");
        SubMethod();
    }

    void SubMethod()
    {
        DebugUtils.Log("SubMethod Log");
    }
}

3. 总结

通过本文的讲解,我们学习了如何实现具有点击跳转功能的Log输出功能。我们首先封装了带有调用栈信息的Log输出函数,在输出Log信息的同时记录了当前代码的调用栈信息。然后,我们为Log信息添加了点击跳转功能,当我们点击Log信息时可以精确定位到代码错误的位置。在Unity开发中,具有点击跳转功能的Log输出是一个非常有用的工具,可以帮助我们快速定位错误并进行调试。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Unity输出带点击跳转功能的Log实现技巧详解 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • 详解Java中的checked异常和unchecked异常区别

    详解Java中的checked异常和unchecked异常区别 Java中的异常类型可以分为两种:checked异常和unchecked异常。两种异常的区别主要在于程序编译时期是否必须进行异常处理。 checked异常: checked异常即编译器在编译Java程序时检查出的异常,通常与I/O操作和网络连接相关。程序在编译时必须要强制进行处理,这意味着这些异…

    C# 2023年5月15日
    00
  • php通过淘宝API查询IP地址归属等信息

    下面是 “php通过淘宝API查询IP地址归属等信息”的完整攻略: 1. 获取淘宝API的AppKey 在使用淘宝API之前,我们需要先获得AppKey。具体步骤如下: 进入淘宝开放平台官网:https://open.taobao.com/ 点击“控制台”->“应用管理”->“创建应用”,按照提示进行填写并提交。 提交申请后,等待审核通过,审核通…

    C# 2023年6月1日
    00
  • c# 开发文字识别软件

    C#开发文字识别软件攻略 1. 确定需求和选取OCR引擎 在开始C#开发文字识别软件之前,我们需要明确需求和选择OCR(Optical Character Recognition,光学字符识别)引擎。OCR引擎是用来识别图片中的文字,将其转换为文本形式的工具。OCR引擎有很多种,我们需要根据实际需求选择适合的引擎。 常见的OCR引擎有Tesseract、百度…

    C# 2023年5月15日
    00
  • C#编程实现获取文件夹中所有文件的文件名

    下面是详细的攻略: 使用C#编程实现获取文件夹中所有文件的文件名 1. 打开Visual Studio创建新的控制台应用程序项目 以Visual Studio 2019为例,新建项目流程如下: 打开 Visual Studio。 选择“创建新项目”。 选择“控制台应用程序”。 可以选择使用.Net Framework或.Net Core,选择一个你习惯的就好…

    C# 2023年6月1日
    00
  • C#实现简单的飞行棋游戏

    我们来简要讲解如何实现一个简单的飞行棋游戏。 1. 游戏规则分析 在开始实现游戏前,我们需要先对飞行棋的规则进行分析: 游戏玩家为2~4人。 每个玩家都有4个棋子,初始位置位于起点。 按照顺时针方向轮流掷骰子,掷到6的可以将棋子从起点移动到起点以外的地方;其它点数则表示棋子可以向前移动相应的步数。 某个棋子走到了别人的棋子位置,就可以将别人的棋子送回起点,自…

    C# 2023年6月6日
    00
  • c# 断点续传的实现

    C# 断点续传的实现攻略 什么是断点续传 断点续传是指当网络传输中断或者用户主动暂停传输时,继续从中断或者暂停的地方继续传输,以达到复制大文件的目的。断点续传技术可以减少文件传输的时间,同时避免重复传输已经传输过的文件,减轻服务器负担,提高传输成功率和效率。 在 C# 中,我们可以通过一些类库和方法来实现断点续传功能。 实现断点续传的步骤 以下是基本的实现步…

    C# 2023年6月6日
    00
  • Unity实现桌面反弹的示例代码

    下面是Unity实现桌面反弹的完整攻略及示例代码。 桌面反弹的实现过程 首先,我们需要创建一个3D球体作为桌球,并且给它添加物理组件,如刚体和碰撞体,以便后面更好地实现球的反弹。 接着,我们需要创建多个3D立方体作为障碍物,并给它们添加物理组件,如刚体和碰撞体。这种障碍物的数量和形状将会对球的运动轨迹产生影响。 在程序中,我们需要创建OnCollisionE…

    C# 2023年5月15日
    00
  • CPF 使用C#的Native AOT 发布程序的详细过程

    一、什么是 Native AOT 在C#语言中,通常使用JIT进行运行时编译以提升程序性能,但AOT(Ahead of Time)则是在编译时将C#代码编译成本地代码,运行时无需JIT,直接执行本地代码,从而提高了程序的启动速度和执行效率。同时,通过Native AOT可生成单独的可执行文件,无需安装.NET运行时环境。 二、如何使用 Native AOT …

    C# 2023年6月6日
    00
合作推广
合作推广
分享本页
返回顶部