Node._enter_tree
2026/4/14大约 3 分钟
最后同步日期:2026-04-16 | Godot 官方原文 — Node._enter_tree
Node._enter_tree
定义
_enter_tree 是一个生命周期回调函数——当节点被加入场景树(SceneTree)的那一刻,引擎会自动调用它。你可以把它理解为"搬进新家"的通知:节点刚刚进入场景树,可以开始使用场景树的各种功能了。
它和 _Ready() 的区别是:_enter_tree 在 _Ready() 之前被调用,而且如果节点被移除后又被重新加入,_enter_tree 会再次触发,而 _Ready() 不会。
函数签名
C#
public override void _EnterTree()GDScript
_enter_tree() -> void参数说明
无参数。
返回值
无返回值(void)。
代码示例
基础用法
观察节点进入场景树的时机:
C#
public partial class MyNode : Node
{
public override void _EnterTree()
{
GD.Print("我进入场景树了!");
// 运行结果: 我进入场景树了!
}
public override void _Ready()
{
GD.Print("我准备好了!");
// 运行结果: 我准备好了!
// 注意:_enter_tree 在 _ready 之前执行
}
}GDScript
extends Node
func _enter_tree():
print("我进入场景树了!")
# 运行结果: 我进入场景树了!
func _ready():
print("我准备好了!")
# 运行结果: 我准备好了!
# 注意:_enter_tree 在 _ready 之前执行实际场景
在进入场景树时进行初始化设置:
C#
public partial class Player : CharacterBody2D
{
private bool _isInitialized = false;
public override void _EnterTree()
{
GD.Print($"玩家 {Name} 进入场景树");
// 运行结果: 玩家 Player 进入场景树
// 每次进入场景树时都需要执行的逻辑
_isInitialized = false;
}
public override void _Ready()
{
// 只在第一次进入时执行
if (!_isInitialized)
{
_isInitialized = true;
GD.Print("玩家初始化完成");
// 运行结果: 玩家初始化完成
}
}
}GDScript
extends CharacterBody2D
var _is_initialized = false
func _enter_tree():
print("玩家 %s 进入场景树" % name)
# 运行结果: 玩家 Player 进入场景树
# 每次进入场景树时都需要执行的逻辑
_is_initialized = false
func _ready():
# 只在第一次进入时执行
if not _is_initialized:
_is_initialized = true
print("玩家初始化完成")
# 运行结果: 玩家初始化完成进阶用法
利用 _enter_tree 可被多次调用的特性,在节点反复加入/移除场景树时管理状态:
C#
public partial class PooledObject : Node2D
{
private int _enterCount = 0;
public override void _EnterTree()
{
_enterCount++;
GD.Print($"第 {_enterCount} 次进入场景树");
// 第一次进入时: 运行结果: 第 1 次进入场景树
// 被移除后重新加入时: 运行结果: 第 2 次进入场景树
// 每次重新进入时重置位置
Position = Vector2.Zero;
Visible = true;
SetProcess(true);
}
public override void _ExitTree()
{
GD.Print("离开场景树,回到对象池");
// 运行结果: 离开场景树,回到对象池
SetProcess(false);
}
public void ReturnToPool()
{
// 从场景树移除但不销毁,以便复用
GetParent().RemoveChild(this);
}
}GDScript
extends Node2D
var _enter_count: int = 0
func _enter_tree():
_enter_count += 1
print("第 %d 次进入场景树" % _enter_count)
# 第一次进入时: 运行结果: 第 1 次进入场景树
# 被移除后重新加入时: 运行结果: 第 2 次进入场景树
# 每次重新进入时重置位置
position = Vector2.ZERO
visible = true
set_process(true)
func _exit_tree():
print("离开场景树,回到对象池")
# 运行结果: 离开场景树,回到对象池
set_process(false)
func return_to_pool():
# 从场景树移除但不销毁,以便复用
get_parent().remove_child(self)注意事项
- 执行顺序:
_enter_tree在_ready之前执行。父节点的_enter_tree先于子节点执行(从上到下),而_ready是子节点先执行完再执行父节点。 - 可被多次调用:如果节点被
RemoveChild移除后又用AddChild重新加入,_enter_tree会再次触发,但_ready不会(除非调用RequestReady())。 - 子节点可能尚未就绪:在父节点的
_enter_tree中,子节点可能还没有进入场景树,因此不要在这里访问子节点。 - C# 差异:C# 中用 PascalCase(
_EnterTree()),GDScript 中用 snake_case(_enter_tree())。
