技能 编程开发 Godot信号与组:解耦开发指南

Godot信号与组:解耦开发指南

v20260824
godot-signals-groups
本教程深入讲解如何在Godot 4.x中使用信号(Signals)和节点组(Groups)实现事件驱动和解耦的游戏逻辑。它教授开发者使用观察者模式,通过发射自定义信号来通知其他节点事件发生,或利用节点组对一批节点进行广播操作。这完美取代了场景间硬编码的节点引用,适用于实现玩家死亡、物品拾取或批量暂停敌人等全局事件处理。
获取技能
88 次下载
概览

Godot Signals & Groups (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.7.

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 → godot-gdscript; scene structure and instancing → godot-nodes-scenes. For cross-scene global events, emit from an autoload (see godot-nodes-scenes).

Core workflow

  1. 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.
  2. Declare typed signals on the emitter; emit() them when the event occurs.
  3. Connect with a Callable (sig.connect(_on_sig)), optionally in the editor's Node dock. Use CONNECT_ONE_SHOT for fire-once, bind() to pass extra context.
  4. Use groups for broadcast: add nodes to a named group, then iterate get_tree().get_nodes_in_group(...) or call_group(...).
  5. Disconnect when needed (e.g. before freeing a long-lived listener) and check is_connected() to avoid duplicate connections.

Patterns

1. Emit upward, connect from the parent

# coin.gd (reusable pickup — knows nothing about the player or 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()
# level.gd (the parent wires the coin to game state)
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)

2. Connect flags: one-shot and bind extra arguments

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)

3. Groups: broadcast to many nodes

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:

func _ready() -> void:
    add_to_group("enemies")        # remove_from_group("enemies") to leave

4. Await a signal inline

func open_chest() -> void:
    $AnimationPlayer.play("open")
    await $AnimationPlayer.animation_finished   # pause until it emits
    spawn_loot()

Pitfalls

  • 3.x connect signature is gone. connect("died", self, "_on_died")died.connect(_on_died). The target is implied by the Callable. The legacy Object.connect("died", Callable(self, "_on_died")) works but the method-name string form does not.
  • Duplicate connections fire handlers multiple times. Connecting again in _ready() after re-adding a node stacks callbacks. Guard with 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.
  • call_group silently ignores nodes lacking the method. Typos in the method name fail quietly — prefer a typed signal when the contract matters.
  • Signal args must match. Emitting with the wrong arg count/types raises an error; declare typed params and emit exactly those.

References

  • For connection flags, deferred connections, custom signal arguments, awaiting with timeouts, and signals vs. direct calls trade-offs, read references/signal-patterns.md.

Related skills

  • godot-gdscript — signal/await syntax fundamentals.
  • godot-nodes-scenes — autoloads for global event buses.
  • game-ai — state machines that often drive and consume these events.
信息
Category 编程开发
Name godot-signals-groups
版本 v20260824
大小 4.23KB
更新时间 2026-09-06
语言