Godot 4: 프롬프트에 시그널 규칙을 넣어 MCP가 체력 바를 연결하게 하세요
Cursor에서 Godot MCP에 요청하기 전에 health_changed 시그널 계약을 정의하여 HUD가 깊은 get_node 경로 없이 연결되도록 하세요—프롬프트 템플릿, GDScript 샘플, 안티패턴, Play 승인 포함.
- Godot MCP
- Godot 4
- signals
- HUD
- GDScript
- Cursor
- AI game development
- tutorial
Godot에서 “AI가 내 씬을 망쳤다”는 가장 흔한 실패는 문법 오류가 아니라, 하드코딩된 체력 바 스크립트입니다:
$"/root/Game/Player/HitPoints".hp # 또는 get_node("../../Player/...")
트리를 다시 부모-자식 관계로 바꾸거나 Player를 자식 씬으로 인스턴스화하면 그 경로는 죽습니다. Godot MCP는 프롬프트를 충실히 따릅니다—하드 경로를 금지하지 않으면 모델은 계속 그런 경로를 만들어냅니다.
이 글은 한 가지 작업만 합니다: Cursor(또는 Claude Code)에서 시그널 계약을 먼저 명시하고, MCP가 플레이어 체력을 HUD 바에 연결하도록 하는 것입니다. 설치 안내나 전체 플랫포머 빌드는 다루지 않습니다.
| 단계 | 수행할 작업 |
|---|---|
| 1 | 시그널, 인자, 발신자/수신자 이름 지정 |
| 2 | 제약 조건과 함께 MCP에 스크립트 및 연결 편집 요청 |
| 3 | Play에서 승인; 안티패턴을 사용하여 프롬프트 수정 |
관련 자료:
배경: 씬 구성 — 자식 씬은 깊은 경로 대신 시그널/export를 노출해야 합니다.
시그널 규칙이 프롬프트에 있어야 하는 이유
| 접근 방식 | 단기적 | 재구성 후 |
|---|---|---|
get_node("../Player/Health") | 빠름 | 종종 깨짐 |
@onready var bar = %HealthBar (고유 이름) | 한 씬에서는 괜찮음 | 씬 간에는 여전히 취약 |
signal health_changed(current, max) + connect | 두 줄 추가 | HUD와 Player 트리가 독립적으로 변경 가능 |
MCP는 제약 조건을 반복하지 않는 한 지속적인 “아키텍처 메모리”가 없습니다. 붙여넣기 가능한 계약 블록은 모든 diff에서 하드 경로를 정리하는 것보다 저렴합니다.
최소 노드 구조
전체 UI는 필요 없습니다. v1에는 다음만 필요합니다:
Game (Node2D / Node)
├── Player (CharacterBody2D) ← player_health.gd
│ └── ...
└── HUD (CanvasLayer)
└── HealthBar (ProgressBar 또는 TextureProgressBar) ← hud_health.gd
이름 지정:
| 노드 | 권장 이름 | 참고 |
|---|---|---|
| Player 루트 | Player | 체력 스크립트 소유 |
| HUD 레이어 | HUD | CanvasLayer |
| 바 | HealthBar | ProgressBar; 절대 HP 또는 max_value = 1 비율 |
HUD가 AI Studio에서 생성된 경우, 배선 전에 안정적인 영어 ID로 이름을 바꾸세요.
시그널 계약 (모든 프롬프트 상단에 붙여넣기)
이것을 프로젝트 규칙으로 취급하세요:
[시그널 계약 — 체력]
1. Player의 체력 스크립트만 다음 시그널을 방출합니다:
signal health_changed(current: float, max_health: float)
과거형/완료형 이름; 인자는 항상 (current, max_health).
2. HUD 바 스크립트는 해당 시그널만 연결하고 ProgressBar를 업데이트합니다; HUD에서 Player로 get_node 금지.
3. 금지: 깊은 크로스 씬 NodePath, Autoload를 체력 버스로 사용(여기서는 불필요), _process에서 Player 폴링.
4. 에디터 시그널 연결 또는 HUD의 @export Node/NodePath 후 .connect 선호 — 절대 "/root/..." 하드코딩 금지.
5. 데미지와 힐은 Player의 값만 변경하고 시그널을 방출합니다; UI는 HP를 변경하지 않습니다.
이 블록이 이 글의 핵심입니다: 구현 전에 계약.
1단계: 읽기 전용 스모크 테스트
현재 편집 중인 씬의 루트 아래 자식 이름을 나열하세요. 파일이나 노드를 수정하지 마세요.
Player와 HUD(또는 해당하는 것)가 보일 때만 쓰기 작업을 진행하세요.
2단계: Player만 방출
계약 뒤에 추가:
[시그널 계약 — 체력] (전체 블록 붙여넣기)
res://scripts/player_health.gd에 생성(없으면)하고 Player에 연결:
- @export var max_health: float = 100.0
- var current: float
- signal health_changed(current: float, max_health: float)
- _ready에서: current = max_health; health_changed를 한 번 방출
- take_damage(amount), heal(amount); 0..max_health로 클램프; 변경 후마다 방출
- HUD를 참조하지 마세요; UI로 get_node 금지
저장하고 시그널 인자 타입을 보고하세요.
참조 구현:
extends Node
class_name PlayerHealth
signal health_changed(current: float, max_health: float)
@export var max_health: float = 100.0
var current: float
func _ready() -> void:
current = max_health
health_changed.emit(current, max_health)
func take_damage(amount: float) -> void:
if amount <= 0.0 or current <= 0.0:
return
current = maxf(0.0, current - amount)
health_changed.emit(current, max_health)
func heal(amount: float) -> void:
if amount <= 0.0 or current <= 0.0:
return
current = minf(max_health, current + amount)
health_changed.emit(current, max_health)
임시 데미지 키 (나중에 삭제):
Player에 임시 debug_damage.gd 추가: H 키를 누르면 같은 노드(또는 부모)의 PlayerHealth.take_damage(10) 호출. 배선 승인 전용. HUD는 건드리지 마세요.
스크립트가 Player 루트에 있다면 extends Node를 해당 타입(예: CharacterBody2D)으로 변경하거나, PlayerHealth를 자식 Health로 만드세요—프롬프트에서 하나를 선택하여 MCP가 마운트 지점을 추측하지 않게 하세요.
3단계: HUD가 export 참조를 통해 구독
[시그널 계약 — 체력] (전체 블록 붙여넣기)
res://scripts/hud_health.gd를 HUD 또는 HealthBar에 생성:
- @export var player_health: PlayerHealth
- @onready var bar: ProgressBar = $HealthBar # 스크립트가 HUD에 있을 때만; 경로는 HUD 하위 트리 내부 유지
- _ready: assert player_health != null; player_health.health_changed.connect(_on_health_changed)
- _on_health_changed(current, max_health): bar.max_value = max_health; bar.value = current
(또는 비율: max_value = 1; value = current / max_health)
- 금지: Player로 get_node; 금지: /root 절대 경로
그런 다음 에디터에서 export player_health를 Player의 PlayerHealth(또는 Health 자식)에 할당. 씬 저장.
참조:
extends CanvasLayer
@export var player_health: PlayerHealth
@onready var bar: ProgressBar = $HealthBar
func _ready() -> void:
assert(player_health != null, "인스펙터에서 PlayerHealth를 할당하세요")
player_health.health_changed.connect(_on_health_changed)
func _on_health_changed(current: float, max_health: float) -> void:
bar.max_value = max_health
bar.value = current
HUD 내부의 $HealthBar는 괜찮습니다—같은 하위 트리입니다. 금지되는 것은 Player로 가는 깊은 경로입니다.
MCP를 통한 에디터 “노드 → 시그널 연결”도 괜찮습니다:
에디터를 통해 연결: Player (PlayerHealth) health_changed → HUD 스크립트 _on_health_changed. NodePath 문자열을 직접 작성하지 마세요.
4단계: Play 승인 체크리스트
- 진입 시: 바가 가득 참(또는 올바른 비율)
- H 키 누름:
bar.value감소 - 0까지: 바가 비어 있음; UI는
current를 쓰지 않아야 함 heal후: 바가 증가Player를 예:Entities아래로 다시 부모-자식 관계 변경 후 다시 Play: export 참조가 유지되면 바는 여전히 업데이트됨—이것이 하드 경로보다 나은 점입니다
재부모화 후 깨지면 빈 export를 수정하세요—MCP에게 “또 다른 get_node”를 요청하지 마세요.
승인 프롬프트:
Play 오류에서 진단: 시그널이 발생하지 않으면 connect를 확인; player_health가 null이면 export만 수정. 절대 get_node 절대 경로로 "수정"하지 마세요. 먼저 진단하고, 제 OK를 기다린 후 편집하세요.
안티패턴: 프롬프트를 변경하고, 병합하지 마세요
| 안티패턴 | 왜 해로운가 | 프롬프트에 추가 |
|---|---|---|
get_node("/root/Game/Player") | 루트 경로 변경 | ”No /root 또는 절대 NodePath” |
get_parent().get_node("Player") | 형제 결합 | ”HUD는 Player 형제 레이아웃을 가정하지 않아야 함” |
Autoload GlobalHealth.hp | 전역 쓰레기통 | ”이 작업에 새 Autoload 금지” |
HUD _process에서 Player 찾기 | 느리고 취약 | ”폴링 금지; 시그널만” |
시그널 이름 update / set_hp | 모호하고 충돌 위험 | ”시그널은 health_changed여야 함” |
수동 작성은 고성능 이동 및 복잡한 전투 수학에서 여전히 우세합니다; 체력 바 배선은 보일러플레이트이므로 계약된 MCP 프롬프트가 일반적으로 더 저렴합니다. Godot MCP vs 수동 스크립팅 참조.
재사용 가능한 “계약 + 작업” 구조
마나/보스 바에 이름을 바꿔 사용하세요:
[시그널 계약]
- 발신자: <노드/스크립트>
- signal <이름>(...)
- 수신자: <HUD 메서드>
- 금지: 절대 NodePath, Autoload 버스, _process 폴링
[작업]
1. …
2. …
3. 씬 저장; 새 시그널과 연결 방법(에디터 / .connect) 나열
요약
- 하드 경로는 프롬프트 구멍이지, “MCP가 Godot을 못함”이 아닙니다
- 편집을 요청하기 전에
health_changed(current, max_health)를 붙여넣으세요 - Player는 방출만; HUD는 연결하고
ProgressBar만 업데이트 - 객체 간 연결은
@export또는 에디터 시그널 연결 사용—/root/...금지 - Player를 재부모화하고 바를 확인하여 승인—“스크립트 생성 OK”가 아니라
이제 붙여넣기 가능한 Godot MCP 프롬프트 규칙 세트가 생겼습니다; 인벤토리, 퀘스트 로그, 킬 카운터도 같은 패턴을 재사용할 수 있습니다.
계속 읽기
이 글도 추천합니다
게임 UI 디자인: 전통적 워크플로우 vs AI 아트 + VberAI Studio 분할
PS/Figma 수동 슬라이싱과 VberAI Studio를 비교합니다. UI 가져오기 또는 AI 생성, 레이어 자동 분할, 레이어드 PSD 또는 이미지 세트 내보내기까지. 효과, 단계, 데모 영상.
- game-ui-design
- game-ui-designer-flow
- ui-slicing
- AIGC
Godot 4 HUD와 테마: Control 트리 핸드오프와 Play 승인
Figma가 Godot 4로 넘어올 때 Theme, StyleBox, 컨테이너 앵커, minimum_size 검증. Unity UGUI 체크리스트에 대응하는 6단계 Play와 수정 라우팅. 핸드오프 가이드.
- game-ui-design
- game-dev-ai
- ui-to-engine
- godot
플로팅 데미지 숫자: 핸드오프 승인과 엔진 구현
팝업이 흐려지거나, 글리프가 빠지거나, 정렬이 틀리거나, 끊길 때의 실패 기준; TMP vs 비트맵 숫자 선택, 풀과 Canvas 순서, Unity UGUI 승인 단계, 디자인 숫자 아트 연결법.
- game-ui-design
- game-dev-ai
- ui-to-engine
- bitmap-font