← 返回博客

把 AI Studio 导出的 HUD 用 Unity MCP 绑到血量事件

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 MCPPlayerHealth ↔ HudHealthView
验收Unity Play受伤 / 回血时条长变化

相关阅读:

先约定:命名比「好看」更重要

AI Studio 导出后,程序要能用路径或序列化引用找到血条。导出前(或进工程后立刻)保证这些名字稳定:

GameObject / 组件用途建议命名说明
HUD 根HUD_Root场景里唯一
血条填充HUD_HealthFillImage(Filled)或挂在 Slider.fillRect 上
可选:数值文本HUD_HealthTextTextMeshProUGUI,如 80/100
可选:受伤闪红HUD_DamageFlash全屏或边框 Image,默认透明

避免把血条叫 Rectangle 42、组 3 这类设计稿默认名——MCP 和手写脚本都会跟着一起倒霉。

步骤 1:确认 HUD 已在场景里

  1. 打开含玩家的场景(例如 Game)
  2. Hierarchy 中应有 HUD_Root(或你的等价名),其下能看到血条 Image / Slider
  3. 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,按下面勾选(全部通过才算接线完成):

  1. 进场景瞬间:血条为满(或等于 current/max),不是空条或脏数据
  2. 按 H(或打到玩家):fillAmount 下降;若有文本,数字同步变
  3. 连续受伤到 0:条空;若实现了死亡逻辑,角色进入死亡态且 HUD 不再乱跳
  4. Heal:条回升(可临时加按键或道具)
  5. 退出 Play 再进:引用仍在,不出现 Missing Script

验收提示示例:

我正在 Play 模式接线验收。根据 Console:若有 NullReferenceException,定位是 PlayerHealth 还是 HudHealthView,并说明是哪个序列化字段为 None。先诊断,提出最小修复,等我确认后再改。

常见断点(按出现频率)

现象优先查
Play 后条不动OnHealthChanged 未订阅;或受伤没走到 TakeDamage
一进 Play 就 NREhealthFill / playerHealth 仍是 None
条反向或跳变Image 不是 Filled;或用了错误的 Rect(边框当填充)
文本不更新绑错 TMP;或字体资源缺失导致组件本身报错
AI 改坏了别的对象提示里写「只改 HUD_Root / Player,禁止动关卡几何」

原则:玩法改血量,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 清单验收,而不是「脚本生成成功」就算完

做完这一段,你就有一条可重复的「界面进引擎 → 事件接线 → Play 验收」闭环;后面背包、蓝条、Boss 条都可以复制同一模式。

你可能还会喜欢这些文章