看不到代码请重新刷新此页面

SceneTree(场景树)是 Godot 引擎的核心管理器,负责统筹游戏/项目的整个节点树、场景生命周期、游戏循环、主线程调度等核心功能。所有节点的创建、销毁、场景切换、进程控制都依赖它,以下是其核心能力和常用属性/方法的分类梳理(基于 Godot 4.x):

一、核心定位

SceneTree 是全局单例(整个游戏只有一个实例),可通过任意节点的 get_tree() 方法获取。它的核心作用是:

  • 管理所有活动节点的层级结构(节点树);

  • 控制游戏的运行/暂停/退出;

  • 处理场景的加载、切换、重载;

  • 调度主线程的回调(如 call_deferredcall_after);

  • 管理输入、定时器、网络多线程等全局逻辑。

二、常用属性(Properties)

属性名

类型

核心作用

current_scene

Node

获取/设置当前活动场景(游戏中显示的主场景),比如 get_tree().current_scene 可拿到当前运行的场景根节点

paused

bool

全局暂停开关:get_tree().paused = true 会暂停所有节点的 _process/_physics_process(除了标记为「暂停时仍处理」的节点)

root

Viewport

获取场景树的根视图(Viewport),所有场景都挂载在它下面

has_queue_free

bool

检查是否有节点等待被销毁(queue_free 标记的节点会在帧结束时销毁)

time_scale

float

全局时间缩放系数(默认 1.0):设置为 0.5 则游戏速度减半,设置为 0 等价于暂停物理/进程(比 paused 更灵活)

三、核心方法(Methods)

1. 场景管理(最常用)

方法名

作用

示例

reload_current_scene()

重载当前活动场景(销毁后重新加载)

get_tree().reload_current_scene.call_deferred()

change_scene_to_file(path)

切换到指定路径的场景(同步加载)

get_tree().change_scene_to_file("res://Scenes/Level2.tscn")

change_scene_to_packed(packed_scene)

切换到已预加载的 PackedScene 实例

var scene = preload("res://Level2.tscn")<br>get_tree().change_scene_to_packed(scene)

call_deferred(method, ...args)

延迟执行方法(主线程安全)

get_tree().call_deferred("reload_current_scene")

call_after(time, method, ...args)

延迟 N 秒后执行方法

get_tree().call_after(2.0, "change_scene_to_file", "res://GameOver.tscn")

2. 游戏进程控制

方法名

作用

示例

quit()

退出游戏/关闭项目窗口

get_tree().quit()(打包后生效,编辑器中按停止按钮)

set_auto_accept_quit(enable)

设置是否自动响应退出请求(比如点击窗口关闭按钮)

get_tree().set_auto_accept_quit(false)(需手动处理退出逻辑)

process_events()

强制处理待处理的输入/系统事件(极少手动调用)

-

3. 节点/回调管理

方法名

作用

示例

create_timer(time)

创建全局定时器(无需手动挂载节点)

var timer = get_tree().create_timer(3.0)<br>timer.timeout.connect(_on_timer_timeout)

call_group(group, method, ...args)

调用指定分组下所有节点的某个方法

get_tree().call_group("enemies", "take_damage", 10)

notify_group(group, what)

给指定分组的节点发送通知

-

get_nodes_in_group(group)

获取指定分组的所有节点列表

var enemies = get_tree().get_nodes_in_group("enemies")

4. 多线程/异步(进阶)

方法名

作用

start_threaded_function(func, args)

启动线程执行指定函数(避免阻塞主线程)

wait_for_thread(thread)

等待线程完成(主线程会阻塞,慎用)

四、常用信号(Signals)

SceneTree 也提供信号来监听全局状态变化:

信号名

触发时机

tree_changed

节点树结构变化时(比如添加/删除节点)

current_scene_changed

当前活动场景切换完成时

idle_frame

每帧空闲时触发(在 _process 之后)

physics_frame

每物理帧触发(在 _physics_process 之后,默认 60 次/秒)

quit_requested

收到退出请求时(比如点击窗口关闭按钮)

五、典型使用场景示例

# 1. 切换场景(延迟 2 秒后切到游戏结束场景)
func _on_player_death():
    get_tree().call_after(2.0, "change_scene_to_file", "res://Scenes/GameOver.tscn")

# 2. 全局暂停游戏(保留 UI 响应)
func pause_game():
    get_tree().paused = true
    # 让 UI 节点不受暂停影响
    $UI/ResumeButton.process_mode = Node.PROCESS_MODE_ALWAYS

# 3. 退出游戏前确认
func _ready():
    get_tree().set_auto_accept_quit(false)
    get_tree().quit_requested.connect(_on_quit_request)

func _on_quit_request():
    print("是否确认退出?")
    # 手动处理退出逻辑,比如弹出确认框后调用 get_tree().quit()

# 4. 给所有敌人分组节点调用方法
func _on_player_attack():
    get_tree().call_group("enemies", "on_attack_land", 20)

六、关键注意事项

  1. SceneTree 的所有方法必须在主线程调用:物理回调(如 _physics_process_on_body_entered)中修改场景树(切换/重载场景、销毁节点)时,需用 call_deferred 包裹,避免线程冲突;

  2. change_scene_to_file 是同步加载:大场景会导致卡顿,建议用 ResourceLoader.load_threaded_request 异步加载后,再调用 change_scene_to_packed

  3. create_timer 创建的定时器是全局的:无需挂载到任意节点,但需注意手动断开信号避免内存泄漏。

如果需要更聚焦某类功能(比如场景切换的最佳实践、全局暂停的细节),可以进一步说明,我会针对性补充。