用 Unity MCP 將 AI Studio 匯出的 HUD 綁到血量事件
AI Studio 匯出 Unity HUD 預製體後,用 Cursor + Unity MCP 掛上血量事件、更新血條與傷害數字,並提供可在 Play 模式驗收的步驟與常見斷點排查。
- Unity MCP
- AI Studio
- HUD
- Unity
- Cursor
- AI game development
- tutorial
HUD 進了 Unity 卻「看起來有血條、打怪不掉血」——多數時候不是預製體壞了,而是介面層和玩法層沒有共用同一套血量事件。設計側已經在 VberAI Studio 裡把主 HUD 匯出成 Canvas / Prefab;玩法側要用 Unity MCP 在已開啟的專案裡把 PlayerHealth 的變化接到 Slider / Image.fillAmount,並用 Play 模式驗收。
本文只做這一段接線,不重複「怎麼從 Figma 匯出」或「怎麼裝 MCP」。
| 步驟 | 工具 | 產出 |
|---|---|---|
| HUD 結構進引擎 | AI Studio | 帶穩定命名的 HUD Prefab |
| 掛腳本、綁引用、改場景 | Cursor(或 Claude Code)+ Unity MCP | PlayerHealth ↔ HudHealthView |
| 驗收 | Unity Play | 受傷 / 回血時條長變化 |
相關閱讀:
先約定:命名比「好看」更重要
AI Studio 匯出後,程式要能用路徑或序列化引用找到血條。匯出前(或進專案後立刻)保證這些名字穩定:
| GameObject / 元件用途 | 建議命名 | 說明 |
|---|---|---|
| HUD 根 | HUD_Root | 場景裡唯一 |
| 血條填充 | HUD_HealthFill | Image(Filled)或掛在 Slider.fillRect 上 |
| 可選:數值文字 | HUD_HealthText | TextMeshProUGUI,如 80/100 |
| 可選:受傷閃紅 | HUD_DamageFlash | 全螢幕或邊框 Image,預設透明 |
避免把血條叫 Rectangle 42、組 3 這類設計稿預設名——MCP 和手寫腳本都會跟著一起倒霉。
步驟 1:確認 HUD 已在場景裡
- 開啟含玩家的場景(例如
Game) - Hierarchy 中應有
HUD_Root(或你的等價名),其下能看到血條 Image / Slider - Canvas 的 Render Mode 與相機關係正確(Screen Space - Overlay 最簡單)
對 MCP 做唯讀冒煙測試(不要改場景):
列出目前作用中場景裡名稱包含 HUD 的 GameObject,以及它們掛的 UI 元件類型。不要修改任何內容。
若列表為空:先回到 AI Studio 匯出/同步,或檢查 Prefab 是否拖進了錯誤場景。
步驟 2:玩法側只暴露「血量變化」,不直接 Find UI
把血量放在玩家上,用 C# event(或 UnityEvent)廣播。HUD 只訂閱,不反向 Find("Player") 改邏輯。
在 Cursor 裡讓 Unity MCP 建立腳本(路徑可按專案調整):
在 Assets/Scripts/Combat/PlayerHealth.cs 建立元件:
- maxHealth、currentHealth(float)
- 事件 Action<float,float> OnHealthChanged(current, max)
- 方法 TakeDamage(float)、Heal(float);數值夾在 0~max
- 受傷後若 current<=0,再發一次 OnHealthChanged,並可選 OnDied
- 把腳本掛到場景裡的 Player 上;Start 時廣播一次目前血量
不要修改任何 HUD 節點。
參考實作(可讓模型產生後你再審一遍):
using System;
using UnityEngine;
public class PlayerHealth : MonoBehaviour
{
[SerializeField] float maxHealth = 100f;
float currentHealth;
public event Action<float, float> OnHealthChanged;
public event Action OnDied;
void Awake() => currentHealth = maxHealth;
void Start() => OnHealthChanged?.Invoke(currentHealth, maxHealth);
public void TakeDamage(float amount)
{
if (amount <= 0f || currentHealth <= 0f) return;
currentHealth = Mathf.Max(0f, currentHealth - amount);
OnHealthChanged?.Invoke(currentHealth, maxHealth);
if (currentHealth <= 0f) OnDied?.Invoke();
}
public void Heal(float amount)
{
if (amount <= 0f || currentHealth <= 0f) return;
currentHealth = Mathf.Min(maxHealth, currentHealth + amount);
OnHealthChanged?.Invoke(currentHealth, maxHealth);
}
}
臨時驗收傷害可以先掛一個除錯鍵(正式專案再刪):
給 Player 加臨時 DebugDealDamage.cs:按 H 鍵對同物體上的 PlayerHealth 造成 10 點傷害。僅用於接線驗收。
步驟 3:HUD 視圖只負責「聽事件 → 改條」
再建視圖腳本,序列化引用血條,不要在 Update 裡每幀 GameObject.Find。
建立 Assets/Scripts/UI/HudHealthView.cs:
- 序列化 Image healthFill(Filled,Horizontal)
- 可選 TMP_Text healthText
- 序列化 PlayerHealth playerHealth(或執行時在 Awake 訂閱場景中的唯一 PlayerHealth)
- OnEnable 訂閱 OnHealthChanged;OnDisable 取消訂閱
- 回呼裡:healthFill.fillAmount = current/max;文字寫成 $"{current:0}/{max:0}"
- 把腳本掛到 HUD_Root;把 HUD_HealthFill 的 Image 拖到 healthFill 欄位
- 把場景 Player 上的 PlayerHealth 拖到 playerHealth 欄位
參考實作:
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class HudHealthView : MonoBehaviour
{
[SerializeField] PlayerHealth playerHealth;
[SerializeField] Image healthFill;
[SerializeField] TMP_Text healthText;
void OnEnable()
{
if (playerHealth == null) return;
playerHealth.OnHealthChanged += HandleHealthChanged;
// 若訂閱晚於 Start,可再主動拉一次;此處依賴 PlayerHealth.Start 已廣播
}
void OnDisable()
{
if (playerHealth == null) return;
playerHealth.OnHealthChanged -= HandleHealthChanged;
}
void HandleHealthChanged(float current, float max)
{
float t = max > 0f ? current / max : 0f;
if (healthFill != null) healthFill.fillAmount = t;
if (healthText != null) healthText.text = $"{Mathf.CeilToInt(current)}/{Mathf.CeilToInt(max)}";
}
}
若 Image 不是 Filled:讓 MCP 改 Image Type = Filled、Fill Method = Horizontal,再綁 fillAmount。若你用的是 Slider,把視圖改成寫 slider.value = t(minValue=0,maxValue=1)即可,原則相同。
步驟 4:用 Unity MCP 完成序列化引用(別手點漏欄位)
腳本編譯通過後,在 Cursor 下明確寫入意圖:
在目前場景:
1. 確認 Player 上有 PlayerHealth;HUD_Root 上有 HudHealthView
2. 將 HudHealthView.healthFill 指到名為 HUD_HealthFill 的 Image
3. 將 HudHealthView.playerHealth 指到 Player 上的 PlayerHealth
4. 若存在 HUD_HealthText,指到對應 TMP_Text
5. 儲存場景
完成後列出這兩個元件的序列化欄位是否還有 None。
再做一次唯讀核對:
檢查 HudHealthView 與 PlayerHealth 的引用:有沒有 missing script 或 None 欄位?不要改場景,只報告。
步驟 5:Play 驗收清單
進入 Play,按下面勾選(全部通過才算接線完成):
- 進場景瞬間:血條為滿(或等於
current/max),不是空條或髒資料 - 按 H(或打到玩家):
fillAmount下降;若有文字,數字同步變 - 連續受傷到 0:條空;若實作了死亡邏輯,角色進入死亡態且 HUD 不再亂跳
- Heal:條回升(可臨時加按鍵或道具)
- 退出 Play 再進:引用仍在,不出現 Missing Script
驗收提示範例:
我正在 Play 模式接線驗收。根據 Console:若有 NullReferenceException,定位是 PlayerHealth 還是 HudHealthView,並說明是哪個序列化欄位為 None。先診斷,提出最小修復,等我確認後再改。
常見斷點(按出現頻率)
| 現象 | 優先查 |
|---|---|
| Play 後條不動 | OnHealthChanged 未訂閱;或受傷沒走到 TakeDamage |
| 一進 Play 就 NRE | healthFill / playerHealth 仍是 None |
| 條反向或跳變 | Image 不是 Filled;或用了錯誤的 Rect(邊框當填充) |
| 文字不更新 | 綁錯 TMP;或字型資源缺失導致元件本身報錯 |
| AI 改壞了別的物件 | 提示裡寫「只改 HUD_Root / Player,禁止動關卡幾何」 |
原則:玩法改血量,UI 只聽事件。不要在 PlayerCombat 裡直接 Find("HUD_HealthFill")——下次 AI Studio 重匯改名,戰鬥腳本會一起斷。
和「重匯 HUD」怎麼和平共處
設計在 AI Studio 改了一版 HUD 再匯出時:
- 盡量保留
HUD_HealthFill/HUD_Root等約定名 - 重匯後只重跑步驟 4 的引用檢查;不要讓 MCP 重寫
PlayerHealth - 視圖腳本留在專案裡,Prefab 變體上的序列化引用丟了就再綁一次
邊界清單可以記成一句提示詞:
這次只處理 UI Prefab 引用遺失:不要改動 Assets/Scripts/Combat 下任何玩法腳本。
小結
- AI Studio 負責把 HUD 結構送進 Unity
PlayerHealth廣播(current, max)HudHealthView訂閱並改fillAmount/ 文字- Unity MCP 負責掛元件、填序列化引用、按 Console 做最小修復
- 用按鍵傷害 + Play 清單驗收,而不是「腳本產生成功」就算完
做完這一段,你就有一條可重複的「介面進引擎 → 事件接線 → Play 驗收」閉環;後面背包、藍條、Boss 條都可以複製同一模式。
繼續閱讀
你可能還會喜歡這些文章
Godot 4:用信號規範提示詞,讓 MCP 把血條接到玩家血量
在 Cursor 裡向 Godot MCP 下指令前先寫清信號契約:用 health_changed 連 HUD,避免深層 get_node 硬路徑;含提示詞模板、GDScript 範例、反例與 Play 驗收。
- Godot MCP
- Godot 4
- 信號
- HUD
用 Godot MCP 做 2D 平台跳躍:移動、關卡與敵人怎麼落地
以 Godot 4 平台跳躍可玩原型為目標:用 MCP 推進 CharacterBody2D、TileMap 與敵人邏輯;HUD/標題 UI 需要時再用 VberAI Studio 生成並匯出。
- Godot MCP
- 2D platformer
- Godot 4
- GDScript
VberAI 原位切圖:遊戲 UI 設計圖一鍵導入 Unity / Godot / Cocos
VberAI Studio 對整屏遊戲 UI 設計圖做原位切圖,保留佈局與尺寸,一鍵匯出到 Unity、Godot、Cocos。
- vberai
- ai-studio
- inplace-slice
- game-ui