godot-signals-groups
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGodot Signals & Groups (4.x)
Godot 信号与节点组(4.x版本)
Decouple nodes with the observer pattern (signals) and act on many nodes at once
(groups), instead of hard-coding references between scenes. Targets Godot 4.3+.
通过观察者模式(信号)实现节点解耦,并通过节点组一次性操作多个节点,替代场景间硬编码引用。适用于**Godot 4.3+**版本。
When to use
适用场景
- Use when a node needs to tell others "something happened" (player died, item picked up, wave cleared) without holding direct references to them.
- Use when you need to address a whole category of nodes at once ("pause all enemies", "save every checkpoint").
When not to use: raw signal syntax basics → ; scene structure
and instancing → . For cross-scene global events, emit from an
autoload (see ).
godot-gdscriptgodot-nodes-scenesgodot-nodes-scenes- 当某个节点需要告知其他节点“发生了某件事”(比如玩家死亡、物品拾取、关卡波次完成),但无需持有这些节点的直接引用时使用。
- 当你需要一次性操作某一类节点时使用(比如“暂停所有敌人”、“保存所有 checkpoint”)。
不适用场景:信号基础语法 → 参考;场景结构与实例化 → 参考。跨场景全局事件可通过自动加载(autoload)节点发送(见)。
godot-gdscriptgodot-nodes-scenesgodot-nodes-scenesCore workflow
核心工作流程
- Decide the direction. A child/sub-scene should emit a signal upward; the parent connects to it. This keeps the child reusable and ignorant of who listens.
- Declare typed signals on the emitter; them when the event occurs.
emit() - Connect with a Callable (), optionally in the editor's Node dock. Use
sig.connect(_on_sig)for fire-once,CONNECT_ONE_SHOTto pass extra context.bind() - Use groups for broadcast: add nodes to a named group, then iterate
or
get_tree().get_nodes_in_group(...).call_group(...) - Disconnect when needed (e.g. before freeing a long-lived listener) and check
to avoid duplicate connections.
is_connected()
- 确定通信方向:子节点/子场景应向上发送信号;父节点负责连接信号。这样能保持子节点的可复用性,且无需知晓谁在监听。
- 在发送节点上声明类型化信号;当事件发生时调用发送信号。
emit() - 通过Callable连接信号(),也可在编辑器的Node面板中操作。使用
sig.connect(_on_sig)实现一次性连接,使用CONNECT_ONE_SHOT传递额外上下文参数。bind() - 使用节点组进行广播:将节点添加到命名组中,然后遍历或调用
get_tree().get_nodes_in_group(...)。call_group(...) - 必要时断开连接(比如释放长期存在的监听节点前),并通过检查避免重复连接。
is_connected()
Patterns
常见模式
1. Emit upward, connect from the parent
1. 向上发送信号,父节点连接
gdscript
undefinedgdscript
undefinedcoin.gd (reusable pickup — knows nothing about the player or HUD)
coin.gd(可复用的拾取物——无需知晓玩家或HUD的存在)
extends Area2D
signal collected(value: int)
func _on_body_entered(body: Node) -> void:
if body.is_in_group("player"):
collected.emit(10)
queue_free()
```gdscriptextends Area2D
signal collected(value: int)
func _on_body_entered(body: Node) -> void:
if body.is_in_group("player"):
collected.emit(10)
queue_free()
```gdscriptlevel.gd (the parent wires the coin to game state)
level.gd(父节点将金币与游戏状态关联)
func _ready() -> void:
for coin in get_tree().get_nodes_in_group("coins"):
coin.collected.connect(_on_coin_collected)
func _on_coin_collected(value: int) -> void:
GameState.add_score(value)
undefinedfunc _ready() -> void:
for coin in get_tree().get_nodes_in_group("coins"):
coin.collected.connect(_on_coin_collected)
func _on_coin_collected(value: int) -> void:
GameState.add_score(value)
undefined2. Connect flags: one-shot and bind extra arguments
2. 连接标记:一次性连接与绑定额外参数
gdscript
func _ready() -> void:
# Fire exactly once, then auto-disconnect.
$Door.opened.connect(_on_door_opened, CONNECT_ONE_SHOT)
# bind() appends arguments supplied at connect time (after the signal's own args).
$RedButton.pressed.connect(_on_button.bind("red"))
func _on_button(color: String) -> void:
print("Pressed the %s button" % color)gdscript
func _ready() -> void:
# 仅触发一次,之后自动断开连接。
$Door.opened.connect(_on_door_opened, CONNECT_ONE_SHOT)
# bind()会将连接时传入的参数追加到信号自身参数之后。
$RedButton.pressed.connect(_on_button.bind("red"))
func _on_button(color: String) -> void:
print("Pressed the %s button" % color)3. Groups: broadcast to many nodes
3. 节点组:向多个节点广播
gdscript
func pause_all_enemies() -> void:
# Call a method on every node in the "enemies" group (no-op if missing).
get_tree().call_group("enemies", "set_paused", true)
func count_enemies() -> int:
return get_tree().get_nodes_in_group("enemies").size()Add a node to a group from code or via the editor's Node > Groups tab:
gdscript
func _ready() -> void:
add_to_group("enemies") # remove_from_group("enemies") to leavegdscript
func pause_all_enemies() -> void:
# 调用"enemies"组中所有节点的set_paused方法(节点无该方法时无操作)。
get_tree().call_group("enemies", "set_paused", true)
func count_enemies() -> int:
return get_tree().get_nodes_in_group("enemies").size()可通过代码或编辑器的Node > Groups标签页将节点添加到组中:
gdscript
func _ready() -> void:
add_to_group("enemies") # 调用remove_from_group("enemies")可退出组4. Await a signal inline
4. 内联等待信号
gdscript
func open_chest() -> void:
$AnimationPlayer.play("open")
await $AnimationPlayer.animation_finished # pause until it emits
spawn_loot()gdscript
func open_chest() -> void:
$AnimationPlayer.play("open")
await $AnimationPlayer.animation_finished # 暂停执行直到信号发送
spawn_loot()Pitfalls
常见陷阱
- 3.x connect signature is gone. →
connect("died", self, "_on_died"). The target is implied by the Callable. The legacydied.connect(_on_died)works but the method-name string form does not.Object.connect("died", Callable(self, "_on_died")) - Duplicate connections fire handlers multiple times. Connecting again in after re-adding a node stacks callbacks. Guard with
_ready().if not sig.is_connected(cb): sig.connect(cb) - Connecting to a freed node errors. Disconnect long-lived listeners, or rely on Godot auto-disconnecting when the connected object is freed (it does for nodes).
- Groups are global to the SceneTree, not per-scene. Two levels using the same group name share membership. Namespace group names if that matters.
- silently ignores nodes lacking the method. Typos in the method name fail quietly — prefer a typed signal when the contract matters.
call_group - Signal args must match. Emitting with the wrong arg count/types raises an error; declare typed params and emit exactly those.
- 3.x版本的connect签名已移除。原写法需改为
connect("died", self, "_on_died")。目标对象由Callable隐式指定。旧版写法died.connect(_on_died)仍可使用,但字符串形式的方法名写法不再支持。Object.connect("died", Callable(self, "_on_died")) - 重复连接会导致处理函数多次触发。在节点重新添加后,若再次在中连接信号,会堆叠回调函数。可通过
_ready()进行防护。if not sig.is_connected(cb): sig.connect(cb) - 连接已释放的节点会报错。需断开长期存在的监听节点的连接,或依赖Godot在连接对象被释放时自动断开(节点对象会自动处理)。
- 节点组是SceneTree全局共享的,而非按场景划分。若两个关卡使用相同的组名,会共享成员。若需避免此问题,可为组名添加命名空间。
- 会静默忽略无对应方法的节点。方法名拼写错误会无提示地失败——当需要严格遵循约定时,优先使用类型化信号。
call_group - 信号参数必须匹配。发送信号时参数数量或类型错误会引发报错;需声明类型化参数,并严格按声明发送对应参数。
References
参考资料
- For connection flags, deferred connections, custom signal arguments, awaiting with
timeouts, and signals vs. direct calls trade-offs, read .
references/signal-patterns.md
- 关于连接标记、延迟连接、自定义信号参数、带超时的await以及信号与直接调用的权衡,可阅读。
references/signal-patterns.md
Related skills
相关技能
- — signal/
godot-gdscriptsyntax fundamentals.await - — autoloads for global event buses.
godot-nodes-scenes - — state machines that often drive and consume these events.
game-ai
- —— 信号/
godot-gdscript语法基础。await - —— 用于全局事件总线的自动加载节点。
godot-nodes-scenes - —— 常驱动并消费这些事件的状态机。
game-ai