尽量在 @onready 或 _onready() 中查找变量,避免 _process 中频繁查找
路径查找
1
2
3
4
5
6
7
8
|
# get_node() 和 $ 是一样的
# 绝对路径-从场景根节点开始
var player = get_node("/root/Main/Player")
var player = $"/root/Main/Player"
var sprite = $"./Sprite2D"
var sprite = $"Sprite2D"
var parent = $"../"
var weapon = $"../WeaponSystem/CurrentWeapon"
|
场景唯一名称查找(Godot 4.0+)
1
2
3
4
5
6
7
|
# 使用 % 符号查找场景唯一节点
var player = $"%Player"
var ui = $"%HUD"
# 必须先设置场景唯一名称
func _ready():
set_scene_unique_name("MyUniqueNode")
|
组(Group)查找
1
2
3
4
5
6
7
8
9
10
|
# 获取组中所有节点
var enemies = get_tree().get_nodes_in_group("enemies")
var players = get_tree().get_nodes_in_group("players")
# 获取组中第一个节点
var player = get_tree().get_first_node_in_group("player")
# 检查节点是否在组中
if node.is_in_group("interactive"):
print("可交互节点")
|
类型查找
1
2
3
4
5
6
7
8
9
10
11
12
|
# 查找所有特定类型的节点
func find_all_nodes_of_type(node_type: String):
var found = []
var all_nodes = get_tree().get_nodes_in_group("")
for node in all_nodes:
if node.is_class(node_type):
found.append(node)
return found
# 使用示例
var all_areas = find_all_nodes_of_type("Area2D")
var all_sprites = find_all_nodes_of_type("Sprite2D")
|
所有者(Owner)查找
1
2
3
4
5
6
|
# 获取场景的所有者节点
var scene_owner = get_owner()
# 通过所有者查找节点
var scene_root = get_tree().edited_scene_root
var main_node = scene_root.get_node("Main")
|
信号连接时获取
1
2
3
4
5
6
7
8
9
10
|
# 在信号回调中直接获取发送者
func _on_button_pressed():
var button = get_node("Button") # 传统方式
# 更好的方式 - 使用信号参数
func _on_button_pressed(button_node: Node):
print("按钮被点击:", button_node.name)
# 连接信号时
button.pressed.connect(_on_button_pressed.bind(button))
|
导出变量(@export)
1
2
3
4
5
6
7
|
# 在编辑器中拖拽赋值
@export var player: Node
@export var target_node: NodePath
func _ready():
if target_node:
var node = get_node(target_node)
|
查找子节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 查找直接子节点
var child = get_child(0) # 第一个子节点
# 按名称查找子节点
func find_child_by_name(parent: Node, name: String) -> Node:
for child in parent.get_children():
if child.name == name:
return child
return null
# 递归查找所有后代节点
func find_node_recursive(root: Node, node_name: String) -> Node:
if root.name == node_name:
return root
for child in root.get_children():
var result = find_node_recursive(child, node_name)
if result:
return result
return null
|
使用 @onready 延迟初始化
1
2
3
4
|
# 在节点就绪时自动获取
@onready var player = $"%Player"
@onready var sprite = $"./Sprite2D"
@onready var enemies = get_tree().get_nodes_in_group("enemies")
|
场景树遍历
1
2
3
4
5
6
7
8
9
10
|
# 遍历整个场景树
func print_scene_tree(node: Node, indent: int = 0):
var indent_str = " ".repeat(indent)
print(indent_str + node.name + " (" + node.get_class() + ")")
for child in node.get_children():
print_scene_tree(child, indent + 1)
# 使用
print_scene_tree(get_tree().root)
|
通过索引查找
1
2
3
4
5
6
7
8
9
10
|
# 通过索引获取子节点
var first_child = get_child(0)
var last_child = get_child(get_child_count() - 1)
# 查找特定类型的子节点
func find_child_by_type(parent: Node, class_name: String) -> Node:
for child in parent.get_children():
if child.is_class(class_name):
return child
return null
|