2026-04-02 游戏开发 Godot 1.1k 3 分钟

那些藏在 Godot 文档中的宝藏特性 1

Debug - 调试

  • 通过 breakpoint 关键字可以添加随gd脚本文件存储的永久性断点
  • 脚本编辑器有独立的Debug设置
  • 在项目设置中有单独的Debug分类,提供了很多有用的功能,包括但不限于:
    • 将控制台输出记录成文件日志
    • 设置Gdscript warnings,配置什么语法需要警告,什么不需要
    • 配置Debug中可显示内容(如路径、碰撞箱)的颜色
  • Remote远程调试:可以查看运行时的实时场景树
  • print_tree_pretty()可以打印节点树、print_stack()可以打印调用栈、print_rich()可以打印富文本
  • Profiler / Visual Profiler 可视化分析仪可以直观地展示各个功能对资源的占用情况
  • ObjectDB profiler 可以对内存拍摄快照,比较多个快照之间的差异
  • 自定义 Performance Monitors:功能强大,例如可以实时跟踪当前在场的敌人数量

Groups (Tagging) - 分组

这是一个为节点打标签的功能,每个节点可以属于多个不同组。同一个组的节点可以统一管理,例如统一接收信号、调用方法。

Node and scene instances - 节点和场景实例

  • get_node("Sprite2D") == $Sprite2D
  • 优先使用.queue_free()而不是 .free(),因为后者会立即销毁节点、导致所有对节点的引用都立即变成 null
  • preload() 发生在编译时而不是运行时

Overridable functions - 常用内置虚函数

  • _enter_tree():节点自身挂载到场景树后
  • _ready():节点及其所有子节点挂载到场景树后
    • 此时可以安全的调用 get_node()
  • _exit_tree():节点自身将要从场景树卸载后
    • 可以由调用 remove_child() 触发
  • _process()_physics_process()
  • _unhandled_input() 接收 UI界面和 _input() 中未处理的输入事件,通常将他们 作为针对游戏玩法的输入
    • _input() 用于在 _unhandled_input() 之前拦截输入事件
  • 更多回调虚函数可以通过查看大基类(Node、CanvasItem、Control等)的文档查看,包括但不限于:
    • Node._get_configuration_warnings()
    • CanvasItem._draw()
    • Control._gui_input()

Script Templates - 脚本模板

一些预定义好的代码片段...我不太常用。也许很有用?

Evaluating expressions - 解析并执行表达式

对我来说意义不明的功能...

评论区大佬列出了一些功能:多函数一行调用、条件执行...

表达式可以是:

  • 数学表达式
  • 布尔表达式
  • 内置方法的调用
  • 用户脚本中定义的方法的调用

Expression类可以被实例化,以关联特定的实例,使其能访问实例中的成员们

Change scenes manually - 三种手动切换场景的办法

  • (从内存中)删除当前场景:free()SceneTree.change_scene_to_file()/change_scene_to_packed()
  • 隐藏当前场景:CanvasItem.show()/hide()
  • (从节点树上)卸载当前场景:Node.remove_child(Node)/add_child(Node)

Instancing with signals - 用信号解耦实例化

可以用信号解耦实例化对被实例化场景的容器的依赖,因为只需要发出信号即可,不用依赖实现信号的那个引用

Pausing games and process mode - 暂停游戏和进程模式

Resources 资源

一切都是资源(Texture, Script, Mesh, Animation, AudioStream, Font, Translation...),用好 自定义资源

Singletons(Autoload) - 单例

用于跨场景存储运行时信息、用于处理切换场景和场景间过渡。

不要滥用!

Using SceneTree - 场景树

  • 了解Godot两个底层类:OSMainLoop

  • SceneTree 运行在前两者之上,它为OS提供自己的MainLoop实例,它十分重要,因为:

    • 其包含了根视口 Viewport
    • 包含所有节点的信息
    • 包含操作全局状态的功能
  • 获取根视口

    • get_tree().root
      get_node("/root")
  • 放场景进入场景树,就被实例化为活跃的节点

  • 场景树的顺序(重要)

    • (在编辑器界面中的场景预览)从上到下
    • 所有的回调都是以这个顺序调用(例如 _process()),除了...
    • 除了_ready()
    • 顺序可以被process_priority改变,越小越优先

Scene Unique Nodes - 场景唯一节点

非常好用的功能,用了之后再也不写任何的场景路径来定位节点,直接一个名字搞定!

  • 创建场景唯一节点的两种方法
    • 在重命名节点的时候在名字最前面加一个% 符号
    • 右键节点,在弹出的菜单中勾选 % Access as Unique Name
  • 同场景限制及绕过
    • 场景唯一节点只能被同一场景内的节点检索到
    • 但是可以通过一个中间节点来绕过这个限制:例如 get_node("%StateMachine/%InitState")