一键导入
godot-add-signals
当 Godot 代码中存在通过 get_node()、get_parent() 或直接引用产生的紧耦合依赖时使用。 检测耦合模式并将其转换为基于 Signal 的通信方式。组件变得独立、可测试且可复用。 在改进架构的同时精确保留原有行为。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
当 Godot 代码中存在通过 get_node()、get_parent() 或直接引用产生的紧耦合依赖时使用。 检测耦合模式并将其转换为基于 Signal 的通信方式。组件变得独立、可测试且可复用。 在改进架构的同时精确保留原有行为。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
当 Godot 代码中存在相互冲突的操作导致未定义行为时使用。检测同一属性在多处设置 (_ready、_process、代码+编辑器)、同一 Signal 多次连接、冲突的物理模式、 竞争的动画等问题。自动通过明确的所有权归属解决冲突。
用于创建带有自定义面板、停靠栏和工具的 Godot 编辑器插件。生成 plugin.cfg 配置、 EditorPlugin 脚本模板、自定义编辑器 UI 组件,并集成 ProjectSettings。按照 Godot 4.x 最佳实践创建完整的插件结构。
当 Godot 代码中存在硬编码的游戏数据(如 const 数组、字典或内嵌值)时使用。检测内联数据 如敌人属性、物品定义、关卡配置等。自动提取为 .tres Resource 文件,使数据在编辑器中 可见、易于修改,并支持数据驱动的设计。
当构建 Godot 功能时,代码使用 .new() 创建节点而非使用场景时触发。 检测 Timer.new()、Area2D.new()、Sprite2D.new() 等代码创建的对象。 自动生成 .tscn 场景文件,更新父脚本使用 @onready 引用,并创建可复用的组件库。
当 Godot 项目在编辑器(.tscn)和代码(.gd)之间存在位置冲突、相机跟随背景、 或运行时位置与编辑器预览不匹配时使用。编排所有 3 个位置同步子技能: sync-static-positions、sync-camera-positions 和 sync-parallax。 每个操作针对特定的位置冲突类型。
在开发 Godot 游戏时需要为 GDScript 类、Signal、场景初始化和集成流程提供全面的测试覆盖时使用。 生成 GUT 框架单元测试、集成测试、Mock/Stub 辅助工具和 CI/CD 测试运行器配置。
| name | godot-add-signals |
| version | 3.0.0 |
| displayName | 用 Signal 替换耦合 |
| description | 当 Godot 代码中存在通过 get_node()、get_parent() 或直接引用产生的紧耦合依赖时使用。 检测耦合模式并将其转换为基于 Signal 的通信方式。组件变得独立、可测试且可复用。 在改进架构的同时精确保留原有行为。 |
| author | Asreonn |
| license | MIT |
| category | game-development |
| type | tool |
| difficulty | intermediate |
| audience | ["developers"] |
| keywords | ["godot","signals","decoupling","get-node","get-parent","architecture","gdscript","loose-coupling"] |
| platforms | ["macos","linux","windows"] |
| repository | https://github.com/asreonn/godot-superpowers |
| homepage | https://github.com/asreonn/godot-superpowers#readme |
| permissions | {"filesystem":{"read":[".gd",".tscn"],"write":[".gd",".tscn"]},"git":true} |
| behavior | {"auto_rollback":true,"validation":true,"git_commits":true} |
| outputs | Signal 定义、Signal 连接、解耦组件、git 提交 |
| requirements | Git 仓库, Godot 4.x |
| execution | 全自动执行,保留原有行为 |
| integration | godot-refactor 编排器的一部分,可与 godot-split-scripts 配合使用 |
组件之间通过 Signal 通信,而非直接引用。 耦合会使代码变得脆弱且难以测试。
查找如下模式:
# player.gd
func take_damage(amount):
health -= amount
get_node("../UI/HealthBar").update(health) # TIGHT COUPLING
get_parent().get_node("ScoreManager").reduce_score() # FRAGILE PATH
转换为:
# player.gd
signal health_changed(new_health)
func take_damage(amount):
health -= amount
health_changed.emit(health) # SIGNAL - NO COUPLING
# main.gd (or scene setup)
func _ready():
player.health_changed.connect(ui.health_bar.update)
player.health_changed.connect(score_manager.on_player_damaged)
识别以下模式:
get_node("../path") - 向上路径导航get_parent().something - 父节点依赖find_child("name") - 运行时搜索has_method() - 紧接口耦合旧代码中存在通过 get_node 链产生的意大利面条式依赖。
希望在没有完整场景树的情况下独立测试组件。
组件应该能在不同上下文中使用而无需修改。
场景结构的变更会破坏无关功能。
转换前(紧耦合):
# enemy.gd
extends CharacterBody2D
func die():
var player = get_node("../Player") # FRAGILE PATH
player.add_score(100)
var audio = get_parent().get_node("AudioManager") # TIGHT COUPLING
audio.play_sound("enemy_death")
queue_free()
转换后(基于 Signal):
# enemy.gd
extends CharacterBody2D
signal died(score_value: int)
signal death_sound_requested(sound_name: String)
func die():
died.emit(100)
death_sound_requested.emit("enemy_death")
queue_free()
# main.gd (orchestrator)
func _ready():
for enemy in enemies:
enemy.died.connect(player.add_score)
enemy.death_sound_requested.connect(audio_manager.play_sound)
一个发射器,多个监听器(生命值变化 → 更新 UI + 保存游戏 + 成就检查)。
宣布某事发生,而不关心谁在监听。
请求服务而不知道提供者是谁(request_ammo → 由谁处理弹药就由谁响应)。
状态变更时发出通知(entered_water、jumped、landed)。
识别耦合类型:
选择适当的解决方案:
可与以下技能配合使用:
以下情况不需要添加 Signal:
合理耦合的示例:
事件(过去时):
health_changeditem_collectedenemy_died请求(祈使语气):
damage_requestedplay_soundspawn_particle状态变更:
entered_stateexited_statestate_changed| 转换前(耦合) | 转换后(基于 Signal) |
|---|---|
get_node("../Player").damage() | damage_dealt.emit() → player 监听 |
get_parent().update_ui() | ui_update_requested.emit() → UI 监听 |
owner.score += 10 | score_changed.emit(10) → owner 监听 |
find_child("Camera").shake() | screen_shake_requested.emit() → camera 监听 |