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日

相关文章

  • js实现hashtable的赋值、取值、遍历操作实例详解

    JS实现Hashtable的赋值、取值、遍历操作实例详解 HashTable是一种常用的数据结构,它可以实现高效的数据存储和查找。在JS中,我们可以使用对象的方式来实现HashTable,将key-value对应的数据存储到对象中,从而实现高效的数据查询和遍历。在本文中,我们将讲解JS实现HashTable的赋值、取值、遍历操作的详细攻略。 实现思路 实现一…

    C# 2023年6月7日
    00
  • c#实现识别图片上的验证码数字

    C#是一种广泛使用的编程语言,可以用于开发各种类型的应用程序。本文将介绍如何使用C#实现识别图片上的验证码数字的完整攻略。 步骤一:获取验证码图片 首先,需要获取验证码图片。可以使用WebClient类从网站上下载验证码图片,也可以使用HttpWebRequest类从网站上获取验证码图片。以下是一个使用WebClient类下载验证码图片的示例: using …

    C# 2023年5月15日
    00
  • Asp.net 通用万级数据分页代码[修正下载地址]

    Asp.net 通用万级数据分页代码是一个用于实现数据分页的工具库。下面将给出该工具库的详细攻略: 安装 可以通过Nuget进行安装,输入以下命令即可: Install-Package AspNetPager 安装完成后可以通过以下命名引用Asp.net分页控件: using Wuqi.Webdiyer; 使用方法 在前端页面中添加控件 在前端页面中引用控件…

    C# 2023年5月31日
    00
  • C#实现的24点游戏实例详解

    C#实现的24点游戏实例详解 介绍 C#实现的24点游戏是一款运用纸牌来进行加减乘除的小游戏,主要目的是让玩家通过选择纸牌,使用加减乘除等运算,得到24这个数。本篇攻略将详细讲解如何实现这个小游戏。 代码实现 代码结构 在开始编写代码前,我们需要先了解一下这个小游戏的框架。C#实现的24点游戏包含三个主要部分:纸牌、答案计算以及游戏流程控制。我们需要将这些部…

    C# 2023年6月7日
    00
  • Asp.NET 生成静态页面并分页的代码

    生成静态页面是提高网站性能、SEO优化的主流方法之一。而Asp.NET作为.NET平台的核心技术之一,也提供了生成静态页面的方法。下面将介绍如何在Asp.NET中生成静态页面并实现分页。 1. 生成静态页面的方法 在Asp.NET中,可以使用Response对象的Write方法将页面的HTML代码输出到文件。通过使用FileStream或StreamWrit…

    C# 2023年5月31日
    00
  • C# 列表List的常用属性和方法介绍

    C# 列表List的常用属性和方法介绍 什么是列表List 在C#中,列表List是常用的集合类型,用于存储一组有序的数据。List类提供了一系列常用的属性和方法,使我们可以方便地对列表进行操作。 如何创建列表List 使用List类创建一个列表,需要注意以下几点: 指定列表元素的类型。 使用new运算符来实例化List对象。 以下是示例代码: List&l…

    C# 2023年5月31日
    00
  • C#键值对容器的介绍

    C#中的键值对容器主要指的是通过特定的键来访问元素的数据结构。它通常用于需要在某个特定条件下快速查找元素的情况,比如说搜索算法、缓存机制等。C#中的键值对容器有很多种,本文将从使用频率较高的Dictionary<TKey, TValue>和ConcurrentDictionary<TKey, TValue>两个类别来进行介绍。 Dic…

    C# 2023年6月1日
    00
  • 预处理器指令

    概述 预处理器指令 指导编译器在实际编译之前对信息进行预处理。 所有预处理指令以#开始。并由于预处理器指令不是语句,所以没有分号作为结尾。 一个预处理器指令,一定是这一行的唯一指令。 预处理指令列表 预处理器指令 描述 #define 将其后的一系列 成为符号 undef 取消定义的符号 if 测试符号是否为真 else 和if一起使用 endif 指定一个…

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