Godot 中怎么查找对象

default

尽量在 @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
Licensed under CC BY-NC-SA 4.0
Gear(夕照)的博客。记录开发、生活,以及一些不足为道的思考……