SceneTree.call_group
2026/4/14大约 5 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — SceneTree.call_group
SceneTree.call_group
定义
call_group 就像学校广播——校长在广播里喊一句"所有篮球队员到操场集合",所有篮球队员听到后就各自行动。你不需要一个一个去找人,只需要对着"篮球队"这个组喊一声就行。
在 Godot 中,你可以把节点放进"分组"(Group)里,比如把所有敌人放进 "enemies" 组,把所有可破坏物体放进 "destructibles" 组。然后通过 call_group 一次性地对组内所有节点调用同一个方法,而不需要你挨个找到每个节点单独调用。
这在需要"同时通知很多节点做同一件事"时非常有用:比如通知所有敌人"游戏暂停了"、通知所有可破坏物体"被炸弹炸了"。
函数签名
C#
public void CallGroup(StringName group, StringName method, params Variant[] args)GDScript
func call_group(group: StringName, method: StringName, ...) -> Variant参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
group | StringName | 是 | 要调用的分组名称,例如 "enemies"、"players" |
method | StringName | 是 | 要在组内所有节点上调用的方法名,例如 "take_damage" |
args | Variant[] | 否 | 传递给方法的参数,可以传任意数量的参数 |
返回值
无返回值(void)。该方法是对组内所有节点的广播式调用,不收集返回值。
代码示例
基础用法:对分组内所有节点调用方法
C#
public override void _Ready()
{
// 假设场景中有 3 个敌人节点,都被加入了 "enemies" 分组
// 现在通知所有敌人执行 "take_damage" 方法,并传入参数 10
GetTree().CallGroup("enemies", "TakeDamage", 10);
// 通知所有敌人暂停
GetTree().CallGroup("enemies", "SetPaused", true);
// 运行结果: 所有 enemies 组中的节点都收到了 TakeDamage(10) 和 SetPaused(true) 的调用
}GDScript
func _ready():
# 假设场景中有 3 个敌人节点,都被加入了 "enemies" 分组
# 现在通知所有敌人执行 "take_damage" 方法,并传入参数 10
get_tree().call_group("enemies", "take_damage", 10)
# 通知所有敌人暂停
get_tree().call_group("enemies", "set_paused", true)
# 运行结果: 所有 enemies 组中的节点都收到了 take_damage(10) 和 set_paused(true) 的调用实际场景:炸弹爆炸时伤害所有敌人
C#
using Godot;
public partial class Bomb : Area2D
{
[Export] public int ExDamage = 50;
public void Explode()
{
// 炸弹爆炸!通知所有敌人受到伤害
GetTree().CallGroup("enemies", "TakeDamage", ExDamage);
// 同时通知所有可破坏物体执行"被炸毁"方法
GetTree().CallGroup("destructibles", "Destroy");
// 播放爆炸特效后移除炸弹
GD.Print("炸弹爆炸!造成 " + ExDamage + " 点伤害");
// 运行结果: 炸弹爆炸!造成 50 点伤害
QueueFree();
}
}GDScript
extends Area2D
@export var ex_damage: int = 50
func explode():
# 炸弹爆炸!通知所有敌人受到伤害
get_tree().call_group("enemies", "take_damage", ex_damage)
# 同时通知所有可破坏物体执行"被炸毁"方法
get_tree().call_group("destructibles", "destroy")
# 播放爆炸特效后移除炸弹
print("炸弹爆炸!造成 %d 点伤害" % ex_damage)
# 运行结果: 炸弹爆炸!造成 50 点伤害
queue_free()进阶用法:批量控制 UI 元素和暂停通知
C#
using Godot;
public partial class GameManager : Node
{
private bool _isPaused = false;
public override void _Ready()
{
// 把所有敌人加入 "enemies" 组(也可以在编辑器中手动添加)
// 在编辑器中:选中节点 -> Node 面板 -> Groups -> 添加 "enemies"
}
public void TogglePause()
{
_isPaused = !_isPaused;
GetTree().Paused = _isPaused;
if (_isPaused)
{
// 暂停时:通知所有敌人停止移动
GetTree().CallGroup("enemies", "StopMoving");
// 通知所有 HUD 元素显示暂停画面
GetTree().CallGroup("hud", "ShowPauseMenu");
GD.Print("游戏已暂停");
// 运行结果: 游戏已暂停
}
else
{
// 恢复时:通知所有敌人恢复移动
GetTree().CallGroup("enemies", "ResumeMoving");
// 通知所有 HUD 元素隐藏暂停画面
GetTree().CallGroup("hud", "HidePauseMenu");
GD.Print("游戏已恢复");
// 运行结果: 游戏已恢复
}
}
public void OnGameOver()
{
// 游戏结束:通知所有敌人播放"胜利"动画
GetTree().CallGroup("enemies", "PlayVictoryAnimation");
// 通知所有可收集物品消失
GetTree().CallGroup("collectibles", "OnGameEnd");
}
}GDScript
extends Node
var _is_paused: bool = false
func _ready():
# 把所有敌人加入 "enemies" 组(也可以在编辑器中手动添加)
# 在编辑器中:选中节点 -> Node 面板 -> Groups -> 添加 "enemies"
pass
func toggle_pause():
_is_paused = not _is_paused
get_tree().paused = _is_paused
if _is_paused:
# 暂停时:通知所有敌人停止移动
get_tree().call_group("enemies", "stop_moving")
# 通知所有 HUD 元素显示暂停画面
get_tree().call_group("hud", "show_pause_menu")
print("游戏已暂停")
# 运行结果: 游戏已暂停
else:
# 恢复时:通知所有敌人恢复移动
get_tree().call_group("enemies", "resume_moving")
# 通知所有 HUD 元素隐藏暂停画面
get_tree().call_group("hud", "hide_pause_menu")
print("游戏已恢复")
# 运行结果: 游戏已恢复
func on_game_over():
# 游戏结束:通知所有敌人播放"胜利"动画
get_tree().call_group("enemies", "play_victory_animation")
# 通知所有可收集物品消失
get_tree().call_group("collectibles", "on_game_end")注意事项
- 方法必须存在:如果组内有节点没有定义你调用的方法,Godot 会报错。确保组内所有节点都能响应该方法,或者在方法名前加
_表示可选调用(GDScript 中不会因此崩溃,但仍建议确保方法存在)。 - 调用顺序不确定:
call_group不保证组内节点被调用的顺序,每次调用的顺序可能不同。如果需要按特定顺序处理节点,请使用GetNodesInGroup()手动遍历。 - 性能考虑:当组内节点数量非常多时(比如上千个),
call_group会比手动遍历列表稍慢,因为它需要通过字符串查找方法。如果每帧都需要调用,考虑直接持有节点引用。 - C# 中方法名用 PascalCase:在 C# 中调用时,
method参数要写 C# 风格的方法名(如"TakeDamage"),而不是 GDScript 风格的("take_damage")。这取决于目标节点脚本用的是 C# 还是 GDScript。 - 在编辑器中添加分组:选中节点 -> 右侧 Node 面板 -> Groups -> 输入分组名 -> Add。也可以在代码中通过
AddToGroup("group_name")动态添加。
