SceneTree

继承: MainLoop < Object

通过节点层次结构管理游戏循环。

描述

作为最重要的类之一,SceneTree 管理着场景中节点的层次结构以及场景本身。节点可以被添加、获取和移除。整个场景树可以被暂停,包括当前场景。场景可以被加载、切换和重新加载。

你也可以使用 SceneTree 将你的节点组织成:每个节点都可以被添加到你想要创建的任意多个组中,例如“敌人”组。然后你可以遍历这些组,甚至可以在属于任何给定组的所有节点上调用方法并设置属性。

SceneTree 是引擎所使用的默认 MainLoop 实现,因此负责游戏循环。

教程

属性

bool

auto_accept_quit

true

Node

current_scene

bool

debug_collisions_hint

false

bool

debug_navigation_hint

false

bool

debug_paths_hint

false

Node

edited_scene_root

bool

multiplayer_poll

true

bool

paused

false

bool

physics_interpolation

false

bool

quit_on_go_back

true

Window

root

方法

void

call_group(group: StringName, method: StringName, …) vararg

void

call_group_flags(flags: int, group: StringName, method: StringName, …) vararg

Error

change_scene_to_file(path: String)

Error

change_scene_to_packed(packed_scene: PackedScene)

SceneTreeTimer

create_timer(time_sec: float, process_always: bool = true, process_in_physics: bool = false, ignore_time_scale: bool = false)

Tween

create_tween()

Node

get_first_node_in_group(group: StringName)

int

get_frame() const

MultiplayerAPI

get_multiplayer(for_path: NodePath = NodePath(“”)) const

int

get_node_count() const

int

get_node_count_in_group(group: StringName) const

Array[Node]

get_nodes_in_group(group: StringName)

Array[Tween]

get_processed_tweens()

bool

has_group(name: StringName) const

void

notify_group(group: StringName, notification: int)

void

notify_group_flags(call_flags: int, group: StringName, notification: int)

void

queue_delete(obj: Object)

void

quit(exit_code: int = 0)

Error

reload_current_scene()

void

set_group(group: StringName, property: String, value: Variant)

void

set_group_flags(call_flags: int, group: StringName, property: String, value: Variant)

void

set_multiplayer(multiplayer: MultiplayerAPI, root_path: NodePath = NodePath(“”))

void

unload_current_scene()


信号

node_added(node: Node) 🔗

node 进入该树时发出。


node_configuration_warning_changed(node: Node) 🔗

nodeNode.update_configuration_warnings 被调用时发出。仅在编辑器中发出。


node_removed(node: Node) 🔗

node 退出该树时发出。


node_renamed(node: Node) 🔗

nodeNode.name 被更改时发出。


physics_frame() 🔗

在该树中的每个节点上调用 Node._physics_process 之前立即发出。


process_frame() 🔗

在该树中的每个节点上调用 Node._process 之前立即发出。


tree_changed() 🔗

每当该树的层次结构发生变化(节点被移动、重命名等)时发出。


tree_process_mode_changed() 🔗

当树内任意节点的 Node.process_mode 更改时触发。仅在编辑器中触发,以更新禁用节点的可见性。


枚举

enum GroupCallFlags: 🔗

GroupCallFlags GROUP_CALL_DEFAULT = 0

没有特殊行为地调用组内的节点(默认)。

GroupCallFlags GROUP_CALL_REVERSE = 1

按相反的树层次结构顺序调用组内的节点(所有嵌套子节点都在其各自的父节点之前调用)。

GroupCallFlags GROUP_CALL_DEFERRED = 2

在当前帧(可以是处理帧或物理帧)末尾调用组内的节点,类似于 Object.call_deferred

GroupCallFlags GROUP_CALL_UNIQUE = 4

即使在同一帧中执行多次,也仅调用组内的节点一次。必须与 GROUP_CALL_DEFERRED 结合使用才能工作。

注意:不考虑不同的参数。因此,当使用不同的参数执行相同的调用时,只会执行第一个调用。


属性说明

bool auto_accept_quit = true 🔗

  • void set_auto_accept_quit(value: bool)

  • bool is_auto_accept_quit()

如果为 true,则应用程序会自动接受退出请求。

移动平台见 quit_on_go_back


Node current_scene 🔗

  • void set_current_scene(value: Node)

  • Node get_current_scene()

当前加载的主场景的根节点,通常是 root 的直接子节点。另见 change_scene_to_filechange_scene_to_packedreload_current_scene

警告:直接设置该属性可能无法正常工作,因为这样不会在场景树中添加删除节点。


bool debug_collisions_hint = false 🔗

  • void set_debug_collisions_hint(value: bool)

  • bool is_debugging_collisions_hint()

如果为 true,从编辑器中运行游戏时会显示碰撞形状,方便调试。

注意:这个属性不应在运行时更改。在运行项目时更改 debug_collisions_hint 的值不会有想要的效果。


bool debug_navigation_hint = false 🔗

  • void set_debug_navigation_hint(value: bool)

  • bool is_debugging_navigation_hint()

如果为 true,从编辑器中运行游戏时会显示导航多边形,方便调试。

注意:这个属性不应在运行时更改。在运行项目时更改 debug_navigation_hint 的值不会有想要的效果。


bool debug_paths_hint = false 🔗

  • void set_debug_paths_hint(value: bool)

  • bool is_debugging_paths_hint()

如果为 true,从编辑器中运行游戏时,来自 Path2DPath3D 节点的曲线将可见以进行调试。

注意:该属性没有被设计为在运行时更改。在项目运行时更改 debug_paths_hint 的值不会产生预期的效果。


Node edited_scene_root 🔗

  • void set_edited_scene_root(value: Node)

  • Node get_edited_scene_root()

编辑器中当前正在编辑场景的根节点。通常是 root 的直接子节点。

注意:该属性在发布版本中不起任何作用。


bool multiplayer_poll = true 🔗

  • void set_multiplayer_poll_enabled(value: bool)

  • bool is_multiplayer_poll_enabled()

如果为 true(默认值),则在 process_frame 期间为该 SceneTree 启用 MultiplayerAPI 的自动轮询。

如果为 false,则需要手动调用 MultiplayerAPI.poll 以处理网络数据包并下发 RPC。这允许在一个不同的循环(例如物理、线程、特定时间步长)中运行 RPC,并在从线程访问 MultiplayerAPI 时进行手动 Mutex 保护。


bool paused = false 🔗

  • void set_pause(value: bool)

  • bool is_paused()

如果为 true,则该场景树被视为暂停。这会导致以下行为:


bool physics_interpolation = false 🔗

  • void set_physics_interpolation_enabled(value: bool)

  • bool is_physics_interpolation_enabled()

如果为 true,则渲染器将在最后两个变换之间插入物理对象的变换,这样即使物理刻度与渲染帧不一致,也能看到平滑的运动。

该属性的默认值由 ProjectSettings.physics/common/physics_interpolation 控制。


bool quit_on_go_back = true 🔗

  • void set_quit_on_go_back(value: bool)

  • bool is_quit_on_go_back()

如果为 true,则该应用程序会在导航返回时自动退出(例如在 Android 上使用系统“返回”键)。

禁用这个选项时,如果要处理“返回”按钮,请使用 DisplayServer.WINDOW_EVENT_GO_BACK_REQUEST


Window root 🔗

场景树的根 Window。这是场景树的最顶层 Node,始终存在。绝对 NodePath 始终从这个节点开始。加载的 current_scene 以及“项目设置”中配置的自动加载可能也是根节点的子节点。

警告:请勿删除该节点。删除会导致不稳定的行为并引起崩溃。


方法说明

void call_group(group: StringName, method: StringName, …) vararg 🔗

在该树内添加到给定 group的每个节点上调用 method。你可以通过在该方法调用末尾指定参数来将参数传递给 method。无法调用 method 的节点(因为该方法不存在或参数不匹配)将被忽略。另见 set_groupnotify_group

注意:该方法立即作用于所有选定的节点,这可能会在某些性能密集型情况下导致卡顿。

注意:在 C# 中,当引用内置的 Godot 方法时,method 必须使用 snake_case。最好使用 MethodName 类中公开的名称,以避免在每次调用时分配新的 StringName


void call_group_flags(flags: int, group: StringName, method: StringName, …) vararg 🔗

在树内添加到给定 group 的每个节点上调用给定的 method。使用 flags 自定义该方法的行为(请参阅 GroupCallFlags)。method 的附加参数可以在该方法的末尾传递。无法调用 method 的节点(因为该方法不存在或参数不匹配)将被忽略。

  1. # 在帧末尾以相反的树顺序,在 “enemies” 组的所有节点上调用 “hide”。
  2. get_tree().call_group_flags(
  3. SceneTree.GROUP_CALL_DEFERRED | SceneTree.GROUP_CALL_REVERSE,
  4. "enemies", "hide")

注意:在 C# 中,当引用内置的 Godot 方法时,method 必须使用 snake_case。最好使用 MethodName 类中公开的名称,以避免在每次调用时分配新的 StringName


Error change_scene_to_file(path: String) 🔗

将位于给定路径 path 的场景加载进一个 PackedScene 并新建其实例,然后将正在运行的场景修改为这个场景。

成功时返回 @GlobalScope.OK;如果 path 不能被加载到一个 PackedScene 中,则返回 @GlobalScope.ERR_CANT_OPEN;如果该场景无法被实例化,则返回 @GlobalScope.ERR_CANT_CREATE

注意:有关操作顺序的详细信息,请参阅 change_scene_to_packed


Error change_scene_to_packed(packed_scene: PackedScene) 🔗

将正在运行的场景更改为给定 PackedScene 的新实例(新实例必须有效)。

成功时返回 @GlobalScope.OK,场景无法被实例化时返回 @GlobalScope.ERR_CANT_CREATE,场景无效时返回 @GlobalScope.ERR_INVALID_PARAMETER

注意:change_scene_to_packed 被调用时,操作按以下顺序发生:

  1. 当前场景节点被立即从树中移除。从那时起,在当前(传出)场景上调用的 Node.get_tree 将返回 nullcurrent_scene 也将变为 null,因为新场景尚不可用。

  2. 在帧末尾时,已从树中移除的、之前的当前场景将被删除(从内存中释放),然后新场景将被实例化并添加到树中。Node.get_treecurrent_scene 将恢复正常工作。

这确保了两个场景不会同时运行,并且仍然会以类似于 Node.queue_free 的安全方式释放之前的场景。


SceneTreeTimer create_timer(time_sec: float, process_always: bool = true, process_in_physics: bool = false, ignore_time_scale: bool = false) 🔗

返回一个新的 SceneTreeTimer。在以秒为单位的 time_sec 过去后,该计时器将发出 SceneTreeTimer.timeout 并自动释放。

如果 process_alwaysfalse,则当将 paused 设置为 true 时,该计时器将被暂停。

如果 process_in_physicstrue,则该计时器将在物理帧结束时,而不是在过程帧结束时更新。

如果 ignore_time_scaletrue,则该计时器将忽略 Engine.time_scale 并使用实际的、经过的时间更新。

该方法通常用于创建一次性的延迟计时器,如下例所示:

GDScriptC#

  1. func some_function():
  2. print("开始")
  3. await get_tree().create_timer(1.0).timeout
  4. print("结束")
  1. public async Task SomeFunction()
  2. {
  3. GD.Print("开始");
  4. await ToSignal(GetTree().CreateTimer(1.0f), SceneTreeTimer.SignalName.Timeout);
  5. GD.Print("结束");
  6. }

注意:该计时器总是在树中的所有节点之后更新。在该计时器更新之前,将调用节点的 Node._process 方法(如果 process_in_physics 被设置为 true,则调用 Node._physics_process)。


Tween create_tween() 🔗

创建并返回在该树中处理的新的 Tween。该 Tween 将在下一个处理帧或物理帧中自动开始(取决于其 TweenProcessMode)。

注意:使用该方法创建的 Tween 不会被绑定到任何 Node。它可能会继续工作,直到没有任何东西可以进行动画。如果希望在 Node 被释放时自动终结该 Tween,请使用 Node.create_tweenTween.bind_node


Node get_first_node_in_group(group: StringName) 🔗

返回树中找到的第一个加入了 group 分组的 Node,查找时按照场景层次结构顺序。如果没有找到匹配的节点则返回 null。另见 get_nodes_in_group


int get_frame() const 🔗

返回程序开始运行之后已经处理了多少帧。测量的不是经过的时间。


MultiplayerAPI get_multiplayer(for_path: NodePath = NodePath(“”)) const 🔗

搜索为给定路径配置的 MultiplayerAPI,如果不存在,则会搜索父路径,直到找到为止。如果路径为空,或者没有找到,则返回默认路径。参见 set_multiplayer


int get_node_count() const 🔗

返回该树中的节点数。


int get_node_count_in_group(group: StringName) const 🔗

返回分配给给定组的节点数。


Array[Node] get_nodes_in_group(group: StringName) 🔗

返回一个 Array,其中包含的是树中所有加入了 group 分组的节点,按照场景层次结构排序。


Array[Tween] get_processed_tweens() 🔗

返回树中当前存在的 TweenArray,包括暂停的补间。


bool has_group(name: StringName) const 🔗

如果树中存在添加到给定组 name 的节点,则返回 true


void notify_group(group: StringName, notification: int) 🔗

在树内添加到该 group 的所有节点上,使用给定 notification 调用 Object.notification。另见 call_groupset_group

注意:该方法立即作用于所有选定的节点,这可能会在某些性能密集型情况下导致卡顿。


void notify_group_flags(call_flags: int, group: StringName, notification: int) 🔗

使用给定的 notification 对添加到 group 的该树内的所有节点调用 Object.notification 。使用 call_flags 自定义该方法的行为(请参阅 GroupCallFlags)。


void queue_delete(obj: Object) 🔗

将要删除的给定 obj 排队,在当前帧末尾调用其 Object.free。该方法与 Node.queue_free 类似。


void quit(exit_code: int = 0) 🔗

使用给定的 exit_code 在当前迭代结束时退出应用程序。

按照惯例,退出代码 0 表示成功,而任何其他退出代码表示错误。出于可移植性的原因,它应该在 0125 (含)之间。

注意:这个方法在 iOS 上不起作用。相反,根据 《iOS 人机界面指南》 中的建议,用户应通过 Home 按钮关闭应用程序。


Error reload_current_scene() 🔗

重新加载当前活动的场景,将 current_scene 替换为其原始 PackedScene 的新实例。

成功时返回 @GlobalScope.OK,如果尚未定义 current_scene,则返回 @GlobalScope.ERR_UNCONFIGURED,如果 current_scene 无法加载到 PackedScene 中,则返回 @GlobalScope.ERR_CANT_OPEN,如果场景无法实例化,则返回 @GlobalScope.ERR_CANT_CREATE


void set_group(group: StringName, property: String, value: Variant) 🔗

将该树内被添加到给定 group 的所有节点上的给定 property 设置为 value。没有 property 的节点将被忽略。另见 call_groupnotify_group

注意:该方法立即作用于所有选定的节点上,这可能会在某些性能密集型的情况下导致卡顿。

注意:在 C# 中,在引用 Godot 内置属性时,property 必须是 snake_case。最好使用 PropertyName 类中公开的名称,以避免在每次调用时分配一个新的 StringName


void set_group_flags(call_flags: int, group: StringName, property: String, value: Variant) 🔗

将该树内被添加到给定 group 的所有节点上的给定 property 设置为 value。没有 property 的节点将被忽略。使用 call_flags 自定义该方法的行为(请参阅 GroupCallFlags)。

注意:在 C# 中,在引用 Godot 内置方法时,property 必须是 snake_case。最好使用 SignalName 类中公开的名称,以避免在每次调用时分配一个新的 StringName


void set_multiplayer(multiplayer: MultiplayerAPI, root_path: NodePath = NodePath(“”)) 🔗

用给定的 root_path 设置自定义的 MultiplayerAPI(同时控制相对的子路径),如果 root_path 为空,则会覆盖默认值。

注意:MultiplayerAPI 不能为包含 root_path 的子路径配置,嵌套的自定义多人游戏是不被允许的。例如,如果为 "/root/Foo" 配置了一项,则为 "/root/Foo/Bar" 设置一项将导致错误。


void unload_current_scene() 🔗

如果当前场景已加载,调用此方法将进行卸载。