Agent Skills
返回列表
💻

Godot 信号与分组

开发编程 更新于 2026.08.30

将以下提示词粘贴到你的 AI 对话框中:

请根据 https://skillhub.cn/install/skillhub.md,安装 @user_3c6cb52e/godot-signals-groups-c522。

技能介绍

要解决的具体问题

在 Godot 项目里,如果你习惯让节点之间直接持有彼此的引用——比如玩家直接调用敌人的 take_damage(),主场景直接保存每一个检查点——很快会发现两个问题:一是场景耦合得厉害,换个父节点就得到处改代码;二是当需要批量操作某一类节点(比如“暂停所有敌人”“保存所有检查点”)时,只能到处遍历查找,代码又散又慢。Godot Signals & Groups 技能就是为了打破这种硬连接,让节点之间通过信号通信、通过分组广播。

核心能力与关键步骤

信号:让子节点说话,父节点倾听

  • 由子节点或子场景 声明类型化信号,在事件发生时 emit();父节点负责 connect(),而不是反过来。
  • 子节点因此可复用、不用关心谁在监听;父节点控制何时响应。
  • 支持 CONNECT_ONE_SHOT(只触发一次)、bind() 附加额外上下文,甚至可以 await 信号内联等待。
  • 用 is_connected() 做保护,避免在 _ready() 里重复连接导致回调叠加触发。

分组:把一类节点放进命名集合

  • 通过 add_to_group("enemies") 或编辑器的 Node > Groups 面板把节点加入具名分组。
  • 运行时用 get_tree().get_nodes_in_group("enemies") 遍历,或用 call_group("enemies", "pause") 批量调用方法。
  • 分组名在整个 SceneTree 中全局有效,不是按场景隔离的,所以跨场景用同一个名字会互相“串台”。

连接与断开

  • 连接时用 Callable(sig.connect(_on_sig)),目标隐含在 Callable 里,不要再写 3.x 时代的 connect("died", self, "_on_died") 字符串形式。
  • 如果监听者是长生命周期对象,释放前要主动 disconnect(),否则连到已释放节点会报错;Godot 会在被连接对象本身被释放时自动断开,但不能依赖它处理你手动 free() 的情况。

适用边界与注意点

  • 目标版本是 Godot 4.3+;3.x 的旧式连接签名已废弃,虽然 Object.connect("died", Callable(...)) 还能用,但方法名字符串形式不再支持。
  • 重复连接是常见问题:节点被重新添加进树时,_ready() 里的连接会再执行一次,导致回调被调用多次,务必先判断 if not sig.is_connected(cb)。
  • call_group 会静默忽略没有该方法的节点,方法名写错不会报错,所以在契约重要时优先用类型化信号而不是分组方法广播。
  • 信号参数必须匹配:声明了几个类型化参数,emit() 就要传几个、类型对上,否则运行时报错。
  • 信号和直接调用之间需要权衡:跨场景全局事件建议从 autoload 发出(参见 godot-nodes-scenes),而不是让每个子节点自己到处广播。
  • 分组名需要命名空间化(比如 boss_enemies、minor_enemies),否则两个层级用了同名会共享成员,排查起来很痛苦。

使用场景

  • 子场景需要通知父节点事件(如玩家死亡、拾取物品),但不想让子节点知道谁在监听
  • 游戏需要批量操作同一类节点(如暂停所有敌人、保存所有检查点),不想逐个遍历引用
  • 信号需要只触发一次或附带额外参数,并且要防止重复连接导致回调多次执行
  • 从 Godot 3.x 迁移到 4.x,旧的字符串式信号连接代码需要更新为 Callable 形式

适合人员

  • 正在用 Godot 4.x 开发游戏,遇到节点间硬连接导致场景难以复用和重构的工程师
  • 需要对同一类节点进行批量操作,但不想写散落各处的遍历和查找逻辑的开发者
  • 从 Godot 3.x 升级到 4.x,需要修正信号连接语法和处理重复连接问题的维护者
  • 正在设计跨场景全局事件总线,需要决定信号和分组使用边界的架构师