← ブログへ

AI Studio からエクスポートした HUD を Unity MCP で HP イベントに接続する

AI Studio が Unity HUD プレハブをエクスポートしたあと、Cursor + Unity MCP で HP イベントを購読し、HP バーとダメージ数字を更新。Play モードでの受け入れチェックリストとよくある断点の切り分けも解説します。

公開日
  • Unity MCP
  • AI Studio
  • HUD
  • Unity
  • Cursor
  • AI game development
  • tutorial

HUD は Unity に入っているのに「バーはあるのに戦闘で減らない」——多くの場合、プレハブが壊れているのではなく、UI 層とゲームプレイ層が同じ HP イベントを共有していないだけです。デザイン側は VberAI Studio でメイン HUD を Canvas / Prefab としてエクスポート済み。ゲームプレイ側は Unity MCP を使い、開いているプロジェクトで PlayerHealth の変化を Slider / Image.fillAmount に接続し、Play モードで検証します。

本稿はその配線だけを扱います。Figma からのエクスポートや MCP のインストールは繰り返しません。

ステップツール成果物
HUD 構造をエンジンへAI Studio安定した名前付き HUD Prefab
スクリプト追加、参照バインド、シーン編集Cursor(または Claude Code)+ Unity MCPPlayerHealth ↔ HudHealthView
受け入れUnity Playダメージ / 回復でバー長が変化

関連記事:

先に決める:見た目より命名が重要

AI Studio エクスポート後、コードはパスまたはシリアライズ参照で HP バーを見つける必要があります。エクスポート前(またはインポート直後)に、次の名前を安定させてください。

GameObject / 用途推奨名備考
HUD ルートHUD_Rootシーン内で一意
HP バー塗りつぶしHUD_HealthFillImage(Filled)または Slider.fillRect 配下
任意:数値テキストHUD_HealthTextTextMeshProUGUI、例 80/100
任意:ダメージフラッシュHUD_DamageFlash全画面または枠 Image、既定は透明

Rectangle 42 や グループ 3 のようなデザイン既定名は避けてください。MCP も手書きスクリプトも巻き添えになります。

ステップ 1:HUD がシーンにあることを確認

  1. プレイヤーのいるシーンを開く(例:Game)
  2. Hierarchy に HUD_Root(または同等名)があり、その下に HP 用 Image / Slider があること
  3. Canvas の Render Mode とカメラの関係が正しいこと(Screen Space - Overlay が最も簡単)

MCP で読み取り専用スモークテスト(シーンは変更しない):

アクティブなシーンで名前に HUD を含む GameObject と、それに付いている UI コンポーネントの型を一覧してください。何も変更しないでください。

一覧が空なら:AI Studio から再エクスポート / 同期するか、Prefab を誤ったシーンに置いていないか確認してください。

ステップ 2:ゲームプレイ側は「HP 変化」だけ公開し、UI を Find しない

HP はプレイヤー側に置き、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 で現在 HP を一度ブロードキャスト
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 ビューは「イベントを聞いてバーを更新」だけ

ビュースクリプトを追加し、HP バーはシリアライズ参照で持つ。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. シーンを保存
完了後、この 2 コンポーネントのシリアライズフィールドに None が残っていないか一覧表示。

読み取り専用の再確認:

HudHealthView と PlayerHealth の参照を検査:missing script や None フィールドはあるか?シーンは変更せず、報告のみ。

ステップ 5:Play 受け入れチェックリスト

Play に入り、以下をすべて満たしてから配線完了とする:

  1. シーン入場直後:バーが満タン(または current/max と一致)、空バーや古いデータではない
  2. H キー(またはプレイヤーにヒット):fillAmount が減る;テキストがあれば数字も同期
  3. 連続ダメージで 0:バーが空;死亡ロジックがあればキャラが死亡状態になり HUD が暴れない
  4. Heal:バーが回復(一時キーまたはアイテムで可)
  5. Play 終了して再入場:参照が残り、Missing Script が出ない

受け入れプロンプト例:

Play モードで HUD 配線を受け入れ検証中。Console に NullReferenceException があれば、PlayerHealth か HudHealthView のどちらか、どのシリアライズフィールドが None かを特定してください。まず診断し、最小修正を提案。編集は私の OK 後に。

よくある断点(発生頻度順)

現象まず確認
Play 後バーが動かないOnHealthChanged 未購読;またはダメージが TakeDamage に届いていない
Play 入場直後に NREhealthFill / playerHealth がまだ None
バーが逆またはジャンプImage が Filled でない;枠 Rect を塗りつぶしに使っている
テキストが更新されないTMP の割り当てミス;フォントアセット欠落でコンポーネント自体がエラー
AI が別オブジェクトを壊したプロンプトに「HUD_Root / Player のみ変更、レベルジオメトリは触らない」と明記

原則:ゲームプレイが HP を変え、UI はイベントを聞くだけ。PlayerCombat 内で Find("HUD_HealthFill") しないこと——次の AI Studio 再エクスポートで名前が変わると戦闘スクリプトも壊れます。

HUD の再エクスポートと共存するには

デザインが AI Studio で HUD を改訂して再エクスポートしたとき:

  1. 可能な限り HUD_HealthFill / HUD_Root などの約束名を維持
  2. 再インポート後はステップ 4 の参照チェックだけ再実行;MCP に PlayerHealth を書き換えさせない
  3. ビュースクリプトはプロジェクトに残す;Prefab バリアントのシリアライズ参照が消えたら再バインド

境界を一文のプロンプトにまとめる例:

今回は UI Prefab の参照欠落だけを直す。Assets/Scripts/Combat 以下のゲームプレイスクリプトは一切変更しない。

まとめ

  1. AI Studio が HUD 構造を Unity に届ける
  2. PlayerHealth が (current, max) をブロードキャスト
  3. HudHealthView が購読して fillAmount / テキストを更新
  4. Unity MCP がコンポーネント追加、シリアライズ参照の入力、Console に基づく最小修正を担当
  5. キーダメージ + Play チェックリストで受け入れ。「スクリプト生成成功」では終わらない

ここまでで、「UI をエンジンへ → イベント配線 → Play 受け入れ」の繰り返し可能なループが完成します。バッグ、MP バー、ボス HP バーも同じパターンで展開できます。

こちらの記事もおすすめです