菜单

节点和树结构

相关源文件

本文档详细介绍了节点如何构成 Godot Engine 中场景的构建块,以及它们是如何以分层结构组织起来以创建场景树结构的。理解节点和树系统是 Godot 架构和游戏开发工作流的基础。

有关渲染这些节点的视口系统的信息,请参阅 视口系统

节点基础

节点是 Godot 中所有场景的基础构建块。 Node 类是所有场景对象的基类,提供树管理、场景组织和消息传递的核心功能。

Godot 场景中的每个元素——从 UI 控件到 3D 对象,从音频播放器到物理实体——都是 Node 或派生自 Node 类。

节点的主要特性

  • 基于层级:节点可以拥有任意数量的子节点,形成树结构
  • 唯一名称:所有同级节点(节点的直接子节点)必须具有唯一的名称
  • 所有权:父节点被删除时,其所有子节点都会自动删除
  • 处理:节点可以逐帧处理
  • 分组:节点可以组织到组中以便于管理
  • 信号:节点可以发出信号以进行事件驱动的通信

来源

节点树结构

Godot 中的节点构成了称为场景树的分层树结构。这个节点树是决定节点之间如何关联、如何处理以及如何渲染的核心组织结构。

代码中的树结构

父子关系在 Node 类的的数据结构中明确表示

来源

场景树

虽然节点构成了层级关系,但 SceneTree 类管理着整个活动的层级结构。SceneTree 负责:

  1. 管理游戏循环
  2. 处理输入事件
  3. 管理节点组
  4. 跟踪树结构的变化
  5. 向节点提供通知回调

活动场景中的每个节点都属于 SceneTree,并且每个节点都可以通过 get_tree() 方法访问 SceneTree。

来源

节点生命周期

节点在场景树中遵循一个明确定义的生命周期。理解这个生命周期对于初始化资源、启动行为和正确清理至关重要。

关键生命周期方法

  • _enter_tree():当节点进入场景树时调用
  • _ready():当节点及其所有子节点都已初始化并准备就绪时调用
  • _process(delta):每帧调用一次,用于基于帧的行为
  • _physics_process(delta):以固定时间间隔(物理滴答)调用,用于基于物理的行为
  • _exit_tree():当节点即将离开场景树时调用

生命周期回调的顺序很重要

  1. 添加节点时:父节点的 _enter_tree() → 子节点的 _enter_tree() → 子节点的 _ready() → 父节点的 _ready()
  2. 移除节点时:子节点的 _exit_tree() → 父节点的 _exit_tree()

来源

添加和移除节点

节点可以动态地添加到树中或从中移除

添加节点

使用 add_child() 方法将一个节点添加为另一个节点的子节点

Node::add_child(Node* p_node, bool p_force_readable_name = false, Node::InternalMode p_internal = INTERNAL_MODE_DISABLED)

移除节点

节点可以通过两种方式移除

  1. remove_child():从父节点中移除节点,但不释放内存
  2. queue_free():安全地将节点的删除推迟到当前帧结束时

来源

节点属性与处理

处理模式

节点具有一种处理模式,该模式决定了何时应处理它们

处理回调

节点有几个与处理相关的回调

  1. _process(delta):每帧调用一次,用于平滑动画和非物理行为
  2. _physics_process(delta):以固定间隔调用,用于物理相关行为
  3. _input(event):当发生输入事件时调用
  4. _unhandled_input(event):当输入事件未被任何控件处理时调用
  5. _unhandled_key_input(event):当按键输入事件未被处理时调用

来源

分组与场景树通信

节点可以组织成组以便于管理和访问。这允许您通过单个函数调用来定位多个节点。

组操作

SceneTree 提供了与组交互的方法

  • call_group(group, method, ...):在组中的所有节点上调用一个方法
  • notify_group(group, notification):向组中的所有节点发送通知
  • set_group(group, property, value):在组中的所有节点上设置一个属性

来源

视口与控件树

Godot 的 UI 也建立在节点树结构之上,具有额外的层级概念

  1. Viewport:场景的一个视图,作为 UI 节点的根
  2. Control:所有 UI 元素的基类,构成一个控件树
  3. Window:一个可以嵌入其他控件的顶级容器

控件除了正常的节点结构之外,还具有额外的父子关系,以及专门的布局系统、大小调整和定位。

来源

主题系统和节点外观

节点,特别是 UI 控件,可以通过主题系统修改其外观。主题是定义控件视觉属性的资源。

主题可以

  1. 全局设置,应用于整个项目
  2. 应用于特定的控件节点及其所有子节点
  3. 为单个控件覆盖

来源

场景实例化和运行时结构

Godot 中的场景是保存到磁盘的节点集合,可以实例化多次。这种系统允许高效地重用节点结构。

当场景被实例化时

  1. 节点结构会被复制
  2. 每个节点在添加到树中时都会调用其 _enter_tree()
  3. 所有节点添加完毕后,它们会收到 _ready() 通知

来源

实现细节

Godot 的节点系统核心围绕几个关键类和机制构建

  1. Node 类:基类,具有树遍历、子节点管理和生命周期方法
  2. SceneTree 类:管理活动层次结构,并提供对所有节点的全局访问
  3. 通知系统:使用整数通知代码向节点发出状态更改信号
  4. Viewport 类:创建游戏世界视图的特殊节点

节点系统使用各种数据结构来有效地维护树

  • HashMap 用于按名称存储子节点
  • 列表用于跟踪所有权关系
  • 组映射用于将节点组织到组中

来源

场景树中的操作顺序

场景树中的处理遵循特定顺序

对于节点,处理顺序如下

  1. 输入事件(如果处理输入)
  2. 物理处理(固定时间步长,用于与物理相关的代码)
  3. 常规处理(可变时间步长,用于一般行为)

在每个处理阶段内,节点按优先级顺序(数值越小越靠前),然后按树顺序(对于具有相同优先级的节点)进行处理。

来源

结论

节点和树结构是 Godot 架构的核心。这种分层方法提供了一种清晰、直观的方式来组织游戏元素,同时为场景管理、处理和组件间的通信提供了强大的功能。

理解节点之间的关系,它们是如何处理的,以及它们如何进入和退出树,对于有效的 Godot 开发至关重要。