也是研究了一上午,写一下研究的结果和总结
我们都知道,在Godot中呢,是没有异常处理这个概念的,当代码出错时,游戏不会暂停也不会崩溃而是继续运行,但是会导致游戏运行逻辑出现错误
由此可见,Godot是鼓励用户进行防御式编程而非处理异常的,尽管这样不太便于调试。
所谓的防御式编程,一般就是在代码里到处写非空检查,返回值校验、类型判断。虽然能避免游戏直接挂掉,但也牺牲了调试的便利性。
不像其他具有异常处理特性的语言(如Java,C#,Python)能够通过异常对象知道具体发生了什么 在我们需要调试项目的情况下,我们肯定是需要知晓哪些地方出现了错误。
Godot编辑器本身当然是有提供调试器和控制台的,也会在调试时告诉我们具体的错误信息。
但是我们都知道:发布后的游戏行为,和编辑器中运行时可能不一样!
最典型的莫过于:
有时使用ResourceLoader加载资源,编辑器里正常;
但导出后却因路径或 remap 问题导致资源加载失败
这时,运行时查看日志信息就成为了必要。
问题是——我通过搜索和调试信息有关的关键词来翻阅GodotAPI文档,发现Godot并未向用户暴露获取编辑器内置控制台、调试器错误信息、标准输出流或标准错误流信息的有关API
难道,我们要止步于此了…………吗?
不!我们还有一计!
在项目设置中,我们可以看到,有一个"启用文件日志"的选项,如果勾选它,它会将Godot控制台和调试器的信息推送到日志文件中,这一选项在PC平台是默认开启的,其他平台(如安卓)需要手动开启。
而这个文件的存放路径取决于项目设置的“日志路径”,默认情况下是"user://logs/godot.log"。
通过翻阅 user:// 目录,我们可以看到有一个logs文件夹,里面存放着保存了每次游戏运行时控制台输出信息的日志文件
这样思路不就来了吗!
我们在游戏运行时读取该文件,并在文件每次更改时将内容推送到游戏内UI,游戏结束时关闭该文件,这样就能够做到运行时查看代码的错误信息了!
我们可以创建一个自动加载场景,根节点使用CanvasLayer,然后添加一个RichTextLabel节点为根节点
添加脚本:
1. 在_Ready中创建这个日志文件的读取流
2. 在_Process()中判断文件是否有更新,如果有就读取出来并追加到一个RichTextLabel上显示。
3. 在_ExitTree()中关闭文件流释放资源
这样,即使仍然无法像try-catch那样实时捕获异常,但是我们能够准确的得知出现了什么错误导致游戏逻辑出错。
而且,你还能以此进行拓展:
• 日志变更时发射一个信号(比如 LogUpdated),通知其他系统同步更新;
• 如果读取到的日志条目是错误信息(一般以 "ERROR:" 或 "SCRIPT ERROR:" 开头),就发射一个携带错误信息的信号,这样你虽然不知道是哪个对象,在脚本的哪一行触发,但你至少知道运行在这里的时候触发了一个错误,而且也可以从字符串来推断。
下面是简单的代码实现示例,使用C#,不过你也可以使用GDScript来实现一样的效果需要注意的是,C#未经处理的异常,只有在导出后的版本中才会被写入日志文件,在编辑器里的调试版本是不会写入的,不过大家应该都会try-catch吧?都用C#了
经过测试:
Windows:OK
安卓: OK(需要将项目设置的debug/file_logging/enable_file_logging更改为true)


我们都知道,在Godot中呢,是没有异常处理这个概念的,当代码出错时,游戏不会暂停也不会崩溃而是继续运行,但是会导致游戏运行逻辑出现错误
由此可见,Godot是鼓励用户进行防御式编程而非处理异常的,尽管这样不太便于调试。
所谓的防御式编程,一般就是在代码里到处写非空检查,返回值校验、类型判断。虽然能避免游戏直接挂掉,但也牺牲了调试的便利性。
不像其他具有异常处理特性的语言(如Java,C#,Python)能够通过异常对象知道具体发生了什么 在我们需要调试项目的情况下,我们肯定是需要知晓哪些地方出现了错误。
Godot编辑器本身当然是有提供调试器和控制台的,也会在调试时告诉我们具体的错误信息。
但是我们都知道:发布后的游戏行为,和编辑器中运行时可能不一样!
最典型的莫过于:
有时使用ResourceLoader加载资源,编辑器里正常;
但导出后却因路径或 remap 问题导致资源加载失败
这时,运行时查看日志信息就成为了必要。
问题是——我通过搜索和调试信息有关的关键词来翻阅GodotAPI文档,发现Godot并未向用户暴露获取编辑器内置控制台、调试器错误信息、标准输出流或标准错误流信息的有关API
难道,我们要止步于此了…………吗?
不!我们还有一计!
在项目设置中,我们可以看到,有一个"启用文件日志"的选项,如果勾选它,它会将Godot控制台和调试器的信息推送到日志文件中,这一选项在PC平台是默认开启的,其他平台(如安卓)需要手动开启。
而这个文件的存放路径取决于项目设置的“日志路径”,默认情况下是"user://logs/godot.log"。
通过翻阅 user:// 目录,我们可以看到有一个logs文件夹,里面存放着保存了每次游戏运行时控制台输出信息的日志文件
这样思路不就来了吗!
我们在游戏运行时读取该文件,并在文件每次更改时将内容推送到游戏内UI,游戏结束时关闭该文件,这样就能够做到运行时查看代码的错误信息了!
我们可以创建一个自动加载场景,根节点使用CanvasLayer,然后添加一个RichTextLabel节点为根节点
添加脚本:
1. 在_Ready中创建这个日志文件的读取流
2. 在_Process()中判断文件是否有更新,如果有就读取出来并追加到一个RichTextLabel上显示。
3. 在_ExitTree()中关闭文件流释放资源
这样,即使仍然无法像try-catch那样实时捕获异常,但是我们能够准确的得知出现了什么错误导致游戏逻辑出错。
而且,你还能以此进行拓展:
• 日志变更时发射一个信号(比如 LogUpdated),通知其他系统同步更新;
• 如果读取到的日志条目是错误信息(一般以 "ERROR:" 或 "SCRIPT ERROR:" 开头),就发射一个携带错误信息的信号,这样你虽然不知道是哪个对象,在脚本的哪一行触发,但你至少知道运行在这里的时候触发了一个错误,而且也可以从字符串来推断。
下面是简单的代码实现示例,使用C#,不过你也可以使用GDScript来实现一样的效果需要注意的是,C#未经处理的异常,只有在导出后的版本中才会被写入日志文件,在编辑器里的调试版本是不会写入的,不过大家应该都会try-catch吧?都用C#了

经过测试:
Windows:OK
安卓: OK(需要将项目设置的debug/file_logging/enable_file_logging更改为true)


