← Kembali ke blog

Godot 4: Letakkan Peraturan Isyarat dalam Prompt Anda Supaya MCP Menyambung Bar Kesihatan

Sebelum meminta Godot MCP dalam Cursor, takrifkan kontrak isyarat health_changed supaya HUD bersambung tanpa laluan get_node yang dalam—templat prompt, sampel GDScript, anti-corak, dan penerimaan Play.

Diterbitkan
  • Godot MCP
  • Godot 4
  • signals
  • HUD
  • GDScript
  • Cursor
  • AI game development
  • tutorial

Kegagalan “AI rosakkan scene saya” yang paling biasa dalam Godot bukanlah ralat sintaks—ia adalah skrip bar kesihatan yang mengkodkan secara keras:

$"/root/Game/Player/HitPoints".hp  # atau get_node("../../Player/...")

Ubah semula pokok atau jadikan Player sebagai scene anak, dan laluan itu mati. Godot MCP mengikut prompt anda dengan setia—jika anda tidak melarang laluan keras, model akan terus menciptanya.

Siaran ini melakukan satu tugas: dalam Cursor (atau Claude Code), nyatakan kontrak isyarat dahulu, kemudian biarkan MCP menyambung kesihatan pemain ke bar HUD. Tiada panduan pemasangan, tiada binaan platformer penuh.

LangkahApa yang anda lakukan
1Namakan isyarat, argumen, pemancar / penerima
2Prompt MCP dengan kekangan untuk mengedit skrip dan sambungan
3Terima dalam Play; baiki prompt menggunakan anti-corak

Berkaitan:

Latar belakang: Organisasi scene — scene anak sepatutnya mendedahkan isyarat / eksport, bukan laluan dalam.

Mengapa peraturan isyarat perlu dalam prompt

PendekatanJangka pendekSelepas penyusunan semula
get_node("../Player/Health")PantasSelalunya rosak
@onready var bar = %HealthBar (nama unik)Baik dalam satu sceneMasih rapuh merentas scene
signal health_changed(current, max) + connectDua baris tambahanPokok HUD dan Player boleh berubah secara bebas

MCP tidak mempunyai “memori seni bina” yang kekal melainkan anda mengulangi kekangan. Blok kontrak yang boleh ditampal lebih murah daripada membersihkan laluan keras daripada setiap diff.

Rangka nod minimum

Anda tidak memerlukan UI penuh. v1 hanya memerlukan:

Game (Node2D / Node)
├── Player (CharacterBody2D)  ← player_health.gd
│   └── ...
└── HUD (CanvasLayer)
    └── HealthBar (ProgressBar atau TextureProgressBar)  ← hud_health.gd

Penamaan:

NodeNama cadanganNota
Akar PlayerPlayerMemiliki skrip kesihatan
Lapisan HUDHUDCanvasLayer
BarHealthBarProgressBar; HP mutlak atau max_value = 1 nisbah

Jika HUD berasal dari AI Studio, namakan semula kepada ID Inggeris yang stabil sebelum menyambung.

Kontrak isyarat (tampal di bahagian atas setiap prompt)

Anggap ini sebagai undang-undang projek:

[Kontrak isyarat — kesihatan]
1. Hanya skrip kesihatan pada Player yang memancarkan:
   signal health_changed(current: float, max_health: float)
   Penamaan masa lampau / selesai; argumen sentiasa (current, max_health).
2. Skrip bar HUD hanya menyambung isyarat itu dan mengemas kini ProgressBar; tiada get_node ke Player dari HUD.
3. Dilarang: NodePath merentas scene yang dalam, Autoload sebagai bas kesihatan (tidak perlu di sini), mengundi untuk Player dalam _process.
4. Utamakan sambungan isyarat editor, atau @export Node / NodePath pada HUD kemudian .connect — jangan sekali-kali kod keras "/root/...".
5. Kerosakan dan penyembuhan hanya menukar nilai pada Player dan memancarkan; UI tidak pernah mengubah HP.

Blok itu adalah inti artikel ini: kontrak sebelum pelaksanaan.

Langkah 1: Ujian asap baca sahaja

Senaraikan nama anak di bawah akar scene yang sedang diedit. Jangan ubah suai sebarang fail atau nod.

Hanya tulis selepas anda melihat Player dan HUD (atau padanan anda).

Langkah 2: Player memancarkan sahaja

Tambahkan selepas kontrak:

[Kontrak isyarat — kesihatan] (tampal blok penuh)

Dalam res://scripts/player_health.gd (cipta jika tiada) dan lampirkan pada Player:
- @export var max_health: float = 100.0
- var current: float
- signal health_changed(current: float, max_health: float)
- Dalam _ready: current = max_health; pancarkan health_changed sekali
- take_damage(amount), heal(amount); kekang 0..max_health; pancarkan selepas setiap perubahan
- Jangan rujuk HUD; jangan get_node ke UI
Simpan dan laporkan jenis argumen isyarat.

Pelaksanaan rujukan:

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)

Kunci kerosakan sementara (padam kemudian):

Tambahkan debug_damage.gd sementara pada Player: menekan H memanggil PlayerHealth.take_damage(10) pada nod yang sama (atau induk). Penerimaan pendawaian sahaja. Jangan sentuh HUD.

Jika skrip terletak pada akar Player, tukar extends Node agar sepadan (cth. CharacterBody2D), atau jadikan PlayerHealth sebagai anak Health—pilih satu dalam prompt supaya MCP tidak meneka titik lekap.

Langkah 3: HUD melanggan melalui rujukan eksport

[Kontrak isyarat — kesihatan] (tampal blok penuh)

Cipta res://scripts/hud_health.gd pada HUD atau HealthBar:
- @export var player_health: PlayerHealth
- @onready var bar: ProgressBar = $HealthBar  # hanya jika skrip pada HUD; laluan kekal dalam subtree 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
  (atau nisbah: max_value = 1; value = current / max_health)
- Dilarang: get_node ke Player; dilarang: laluan mutlak /root
Kemudian tetapkan player_health eksport kepada PlayerHealth Player (atau anak Health) dalam editor. Simpan scene.

Rujukan:

extends CanvasLayer

@export var player_health: PlayerHealth
@onready var bar: ProgressBar = $HealthBar

func _ready() -> void:
	assert(player_health != null, "Tetapkan PlayerHealth dalam inspector")
	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

$HealthBar di dalam HUD adalah baik—subtree yang sama. Yang dilarang ialah laluan dalam merentas ke Player.

Editor “Node → Connect a Signal” melalui MCP juga baik:

Sambung melalui editor: Player (PlayerHealth) health_changed → skrip HUD _on_health_changed. Jangan tulis rentetan NodePath secara manual.

Langkah 4: Senarai semak penerimaan Play

  1. Semasa masuk: bar penuh (atau nisbah betul)
  2. Tekan H: bar.value menurun
  3. Ke 0: bar kosong; UI tidak boleh menulis current
  4. Selepas heal: bar naik
  5. Ubah semula Player di bawah cth. Entities dan Play semula: bar masih dikemas kini jika rujukan eksport kekal—itu kemenangan berbanding laluan keras

Jika ia rosak selepas ubah semula, baiki eksport kosong—jangan minta MCP untuk “get_node lain”.

Prompt penerimaan:

Diagnosa daripada ralat Play: jika isyarat tidak pernah berbunyi, periksa sambungan; jika player_health null, hanya baiki eksport. Jangan "baiki" dengan laluan get_node mutlak. Diagnosa dahulu; tunggu OK saya sebelum mengedit.

Anti-corak: ubah prompt, jangan gabung

Anti-corakMengapa ia menyakitkanTambah pada prompt
get_node("/root/Game/Player")Kekacauan laluan akar”Tiada /root atau NodePath mutlak”
get_parent().get_node("Player")Gandingan adik-beradik”HUD tidak boleh menganggap susun atur adik-beradik Player”
Autoload GlobalHealth.hpLaci sampah global”Tiada Autoload baharu untuk tugas ini”
HUD _process memburu PlayerPerlahan dan rapuh”Tiada pengundian; isyarat sahaja”
Isyarat dinamakan update / set_hpKabur, mudah bertembung”Isyarat mesti health_changed”

Penulisan tangan masih menang untuk pergerakan laluan panas dan matematik pertempuran kompleks; pendawaian bar kesihatan adalah boilerplate di mana prompt MCP berkontrak biasanya lebih murah. Lihat Godot MCP vs skrip manual.

Rangka “kontrak + tugas” yang boleh diguna semula

Tukar nama untuk bar mana / bos:

[Kontrak isyarat]
- Pemancar: <nod/skrip>
- signal <nama>(...)
- Penerima: <kaedah HUD>
- Dilarang: NodePath mutlak, bas Autoload, pengundian _process

[Tugas]
1. …
2. …
3. Simpan scene; senaraikan isyarat baharu dan cara ia bersambung (editor / .connect)
  1. Laluan keras adalah lubang prompt, bukan “MCP tidak boleh Godot”
  2. Tampal health_changed(current, max_health) sebelum meminta suntingan
  3. Player hanya memancarkan; HUD hanya menyambung dan mengemas kini ProgressBar
  4. Pautan silang objek menggunakan @export atau sambungan isyarat editor—bukan /root/...
  5. Terima dengan mengubah semula Player dan melihat bar—bukan dengan “skrip dijana OK”

Anda kini mempunyai set peraturan prompt Godot MCP yang boleh ditampal; inventori, log pencarian, dan pembilang bunuh boleh menggunakan corak yang sama.

Panduan lain yang mungkin anda suka