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技术站