SceneTree.get_nodes_in_group
2026/4/14大约 4 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — SceneTree.get_nodes_in_group
SceneTree.get_nodes_in_group
定义
get_nodes_in_group 就像在学校里点名——你说"叫所有篮球队员集合",然后把名单给你。你不需要提前知道有几个人在队里,它会帮你把整个组的人全部找出来,给你一个名单(列表)。
和 call_group 不同的是,call_group 是"喊完就完事了"(广播式通知),而 get_nodes_in_group 是"把名单给我,我自己一个一个来"(获取列表后手动处理)。
当你需要对组内的每个节点做不同的事情(而不是统一调用同一个方法)时,就需要用 get_nodes_in_group。
函数签名
C#
public Godot.Collections.Array<Node> GetNodesInGroup(StringName group)GDScript
func get_nodes_in_group(group: StringName) -> Array[Node]参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
group | StringName | 是 | 要查询的分组名称,例如 "enemies"、"collectibles" |
返回值
节点数组——返回指定分组中所有节点的列表。
| 情况 | 返回值 |
|---|---|
| 组内有节点 | 包含所有组内节点的数组 |
| 组为空或不存在 | 空数组(不会返回 null) |
代码示例
基础用法:获取分组中所有节点
C#
public override void _Ready()
{
// 获取 "enemies" 组中的所有节点
var enemies = GetTree().GetNodesInGroup("enemies");
GD.Print($"敌人数量: {enemies.Count}");
// 运行结果: 敌人数量: 3
// 遍历并打印每个敌人的名字
foreach (Node enemy in enemies)
{
GD.Print($" 敌人: {enemy.Name}");
}
// 运行结果:
// 敌人: Slime
// 敌人: Goblin
// 敌人: Skeleton
}GDScript
func _ready():
# 获取 "enemies" 组中的所有节点
var enemies = get_tree().get_nodes_in_group("enemies")
print("敌人数量: %d" % enemies.size())
# 运行结果: 敌人数量: 3
# 遍历并打印每个敌人的名字
for enemy in enemies:
print(" 敌人: %s" % enemy.name)
# 运行结果:
# 敌人: Slime
# 敌人: Goblin
# 敌人: Skeleton实际场景:找出距离玩家最近的敌人
C#
using Godot;
public partial class TargetingSystem : Node2D
{
/// <summary>
/// 找出距离指定位置最近的敌人
/// </summary>
public Node2D FindNearestEnemy(Vector2 fromPosition)
{
var enemies = GetTree().GetNodesInGroup("enemies");
Node2D nearest = null;
float minDistance = float.MaxValue;
foreach (Node node in enemies)
{
// 只处理 Node2D 类型的敌人
if (node is Node2D enemy)
{
float distance = fromPosition.DistanceTo(enemy.Position);
if (distance < minDistance)
{
minDistance = distance;
nearest = enemy;
}
}
}
if (nearest != null)
{
GD.Print($"最近的敌人: {nearest.Name},距离: {minDistance:F1}");
}
// 运行结果: 最近的敌人: Slime,距离: 45.3
return nearest;
}
}GDScript
extends Node2D
## 找出距离指定位置最近的敌人
func find_nearest_enemy(from_position: Vector2) -> Node2D:
var enemies = get_tree().get_nodes_in_group("enemies")
var nearest: Node2D = null
var min_distance: float = INF
for node in enemies:
# 只处理 Node2D 类型的敌人
if node is Node2D:
var enemy: Node2D = node
var distance = from_position.distance_to(enemy.position)
if distance < min_distance:
min_distance = distance
nearest = enemy
if nearest != null:
print("最近的敌人: %s,距离: %.1f" % [nearest.name, min_distance])
# 运行结果: 最近的敌人: Slime,距离: 45.3
return nearest进阶用法:统计不同类型敌人并批量处理
C#
using Godot;
public partial class WaveManager : Node
{
public enum EnumEnemyType { Slime, Goblin, Skeleton, Boss }
public void OnWaveComplete()
{
var enemies = GetTree().GetNodesInGroup("enemies");
// 统计各类敌人数量
int slimeCount = 0;
int goblinCount = 0;
int skeletonCount = 0;
int bossCount = 0;
foreach (Node node in enemies)
{
string name = node.Name.ToString().ToLower();
if (name.Contains("slime")) slimeCount++;
else if (name.Contains("goblin")) goblinCount++;
else if (name.Contains("skeleton")) skeletonCount++;
else if (name.Contains("boss")) bossCount++;
}
GD.Print($"--- 剩余敌人统计 ---");
GD.Print($"史莱姆: {slimeCount}");
GD.Print($"哥布林: {goblinCount}");
GD.Print($"骷髅兵: {skeletonCount}");
GD.Print($"Boss: {bossCount}");
// 运行结果:
// --- 剩余敌人统计 ---
// 史莱姆: 5
// 哥布林: 3
// 骷髅兵: 2
// Boss: 1
// 找出所有血量低于 30% 的敌人,给它们加上"虚弱"标记
foreach (Node node in enemies)
{
if (node is CharacterBody2D enemy)
{
// 假设敌人脚本有一个 Health 属性
var healthValue = enemy.GetMeta("Health").AsSingle();
var maxHealth = enemy.GetMeta("MaxHealth").AsSingle();
if (healthValue < maxHealth * 0.3f)
{
enemy.SetMeta("Weakened", true);
GD.Print($"{enemy.Name} 已进入虚弱状态!");
}
}
}
}
}GDScript
extends Node
enum EnumEnemyType { SLIME, GOBLIN, SKELETON, BOSS }
func on_wave_complete():
var enemies = get_tree().get_nodes_in_group("enemies")
# 统计各类敌人数量
var slime_count = 0
var goblin_count = 0
var skeleton_count = 0
var boss_count = 0
for node in enemies:
var name = node.name.to_lower()
if "slime" in name:
slime_count += 1
elif "goblin" in name:
goblin_count += 1
elif "skeleton" in name:
skeleton_count += 1
elif "boss" in name:
boss_count += 1
print("--- 剩余敌人统计 ---")
print("史莱姆: %d" % slime_count)
print("哥布林: %d" % goblin_count)
print("骷髅兵: %d" % skeleton_count)
print("Boss: %d" % boss_count)
# 运行结果:
# --- 剩余敌人统计 ---
# 史莱姆: 5
# 哥布林: 3
# 骷髅兵: 2
# Boss: 1
# 找出所有血量低于 30% 的敌人,给它们加上"虚弱"标记
for node in enemies:
if node is CharacterBody2D:
var health_value = node.get_meta("Health")
var max_health = node.get_meta("MaxHealth")
if health_value < max_health * 0.3:
node.set_meta("Weakened", true)
print("%s 已进入虚弱状态!" % node.name)注意事项
- 返回的数组是快照:调用时返回的是那一刻组内所有节点的列表。如果在遍历过程中有节点被添加或移除,列表不会自动更新。
- 不要在遍历中删除节点:如果在遍历返回的数组时调用
QueueFree()或RemoveChild(),可能导致遍历出错或崩溃。建议先收集要删除的节点,遍历完后再统一删除。 - 分组不存在时返回空数组:不会报错,也不会返回
null。所以你可以安全地直接遍历结果。 - 返回类型是
Array<Node>:数组中的元素类型是基类Node。如果你知道组内节点的具体类型,需要手动转换(C# 中用is和强制转换,GDScript 中用as或is)。 - 与
call_group的选择:如果你只是想让组内所有节点执行同一个方法,用CallGroup更简洁;如果你需要对每个节点做不同的判断或操作,用GetNodesInGroup更灵活。 - C# 差异:C# 中方法名用 PascalCase(
GetNodesInGroup),GDScript 中用 snake_case(get_nodes_in_group)。
