← Về blog

Kết nối HUD từ AI Studio với sự kiện máu bằng Unity MCP

Sau khi AI Studio xuất prefab HUD Unity, dùng Cursor + Unity MCP để đăng ký sự kiện máu, cập nhật thanh và chữ sát thương, kèm checklist Play-mode và sửa lỗi thường gặp.

Đăng ngày
  • Unity MCP
  • AI Studio
  • HUD
  • Unity
  • Cursor
  • AI game development
  • tutorial

HUD đã nằm trong Unity, thanh trông ổn, nhưng chiến đấu không làm nó chuyển động—thường prefab không sao và UI và gameplay không dùng chung sự kiện máu. Thiết kế đã xuất HUD chính dưới dạng Canvas / Prefab từ VberAI Studio. Gameplay nên dùng Unity MCP trong dự án đang mở để kết nối thay đổi PlayerHealth với Slider / Image.fillAmount, sau đó kiểm tra trong Play mode.

Bài viết này chỉ đề cập đến việc kết nối đó—không bao gồm xuất Figma hay cài đặt MCP.

BướcCông cụKết quả
Đưa cấu trúc HUD vào engineAI StudioPrefab HUD với tên ổn định
Gắn script, ràng buộc tham chiếu, chỉnh sceneCursor (hoặc Claude Code) + Unity MCPPlayerHealth ↔ HudHealthView
Chấp nhậnUnity PlayThanh thay đổi độ dài khi nhận sát thương / hồi máu

Liên quan:

Thống nhất tên trước khi tinh chỉnh

Sau khi xuất từ AI Studio, code phải tìm thanh qua đường dẫn hoặc tham chiếu tuần tự hóa. Trước khi xuất (hoặc ngay sau khi nhập), giữ tên ổn định:

Vai tròTên gợi ýGhi chú
Gốc HUDHUD_RootDuy nhất trong scene
Thanh máuHUD_HealthFillImage (Filled) hoặc nằm trong Slider.fillRect
Text giá trị (tùy chọn)HUD_HealthTextTextMeshProUGUI, ví dụ 80/100
Hiệu ứng sát thương (tùy chọn)HUD_DamageFlashImage toàn màn hình hoặc viền, mặc định trong suốt

Tránh tên mặc định của thiết kế như Rectangle 42 hoặc Group 3—cả MCP và script viết tay sẽ kế thừa sự lộn xộn.

Bước 1: Xác nhận HUD có trong scene

  1. Mở scene người chơi (ví dụ Game)
  2. Hierarchy nên hiển thị HUD_Root (hoặc tương đương) với Image / Slider máu bên dưới
  3. Canvas Render Mode và camera được thiết lập đúng (Screen Space - Overlay là đơn giản nhất)

Kiểm tra nhanh chỉ đọc qua MCP (không chỉnh sửa scene):

List GameObjects in the active scene whose names contain HUD, and the UI component types on them. Do not modify anything.

Nếu danh sách trống: xuất lại/đồng bộ từ AI Studio, hoặc kiểm tra Prefab đã được thả vào sai scene.

Bước 2: Gameplay phơi bày thay đổi máu—không bao giờ tìm UI

Giữ máu trên người chơi và phát qua sự kiện C# (hoặc UnityEvent). HUD chỉ đăng ký; nó không được điều khiển logic qua Find("Player").

Yêu cầu Unity MCP từ Cursor (đường dẫn có thể khớp với dự án của bạn):

Create Assets/Scripts/Combat/PlayerHealth.cs:
- maxHealth, currentHealth (float)
- event Action<float,float> OnHealthChanged(current, max)
- TakeDamage(float), Heal(float); clamp to 0..max
- If current<=0 after damage, fire OnHealthChanged again and optionally OnDied
- Attach to the scene Player; broadcast once in Start
Do not modify any HUD nodes.

Triển khai tham chiếu (tạo, sau đó xem xét):

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);
    }
}

Phím sát thương tạm thời cho việc kết nối (xóa sau):

Add temporary DebugDealDamage.cs on Player: pressing H deals 10 damage to PlayerHealth on the same object. Wiring acceptance only.

Bước 3: View HUD chỉ lắng nghe và cập nhật thanh

Thêm script view với tham chiếu tuần tự hóa. Không GameObject.Find mỗi frame trong Update.

Create Assets/Scripts/UI/HudHealthView.cs:
- Serialize Image healthFill (Filled, Horizontal)
- Optional TMP_Text healthText
- Serialize PlayerHealth playerHealth (or resolve the unique PlayerHealth at Awake)
- OnEnable subscribe OnHealthChanged; OnDisable unsubscribe
- In the callback: healthFill.fillAmount = current/max; text $"{current:0}/{max:0}"
- Attach to HUD_Root; assign HUD_HealthFill Image to healthFill
- Assign Player's PlayerHealth to playerHealth

Tham chiếu:

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;
        // If you subscribe after Start, pull once; here we rely on 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)}";
    }
}

Nếu Image không phải Filled: yêu cầu MCP đặt Image Type = Filled, Fill Method = Horizontal, sau đó gán fillAmount. Với Slider, ghi slider.value = t (minValue=0, maxValue=1)—cùng mẫu.

Bước 4: Để Unity MCP điền tham chiếu tuần tự hóa

Sau khi biên dịch, hãy nói rõ trong Cursor:

In the active scene:
1. Confirm Player has PlayerHealth; HUD_Root has HudHealthView
2. Point HudHealthView.healthFill at the Image named HUD_HealthFill
3. Point HudHealthView.playerHealth at Player's PlayerHealth
4. If HUD_HealthText exists, assign the TMP_Text
5. Save the scene
Then list any remaining None serialized fields on those two components.

Kiểm tra chỉ đọc:

Inspect HudHealthView and PlayerHealth references: any missing scripts or None fields? Report only—do not edit the scene.

Bước 5: Checklist chấp nhận Play

Vào Play và đánh dấu tất cả các mục sau trước khi coi là hoàn tất:

  1. Khi vào: thanh đầy (hoặc khớp current/max), không trống/không cũ
  2. Nhấn H (hoặc đánh người chơi): fillAmount giảm; text cập nhật nếu có
  3. Sát thương về 0: thanh trống; trạng thái chết ổn định; HUD không nhấp nháy
  4. Hồi máu: thanh tăng (phím tạm hoặc vật phẩm)
  5. Thoát Play và vào lại: tham chiếu vẫn hợp lệ; không có Missing Script

Lời nhắc chấp nhận:

I am accepting HUD wiring in Play mode. If Console shows NullReferenceException, say whether it is PlayerHealth or HudHealthView and which serialized field is None. Diagnose first, propose the minimal fix, wait for my OK before editing.

Điểm hỏng thường gặp

Triệu chứngKiểm tra đầu tiên
Thanh không bao giờ chuyển động trong PlayOnHealthChanged chưa đăng ký; hoặc sát thương không gọi TakeDamage
NRE khi vào PlayhealthFill / playerHealth vẫn None
Thanh ngược hoặc nhảyImage không Filled; dùng sai Rect làm fill
Text kẹtSai TMP; thiếu font asset trên component
AI chỉnh sai đối tượngNhắc: “Only touch HUD_Root / Player; do not move level geometry”

Quy tắc: gameplay thay đổi máu; UI chỉ lắng nghe. Không Find("HUD_HealthFill") bên trong PlayerCombat—lần xuất lại AI Studio đổi tên sẽ phá vỡ cả chiến đấu.

Sống chung với việc xuất lại HUD

Khi thiết kế xuất lại từ AI Studio:

  1. Giữ tên HUD_HealthFill / HUD_Root khi có thể
  2. Sau khi nhập lại, chỉ chạy lại kiểm tra tham chiếu bước 4—không để MCP viết lại PlayerHealth
  3. Giữ script view trong dự án; gán lại nếu tham chiếu Prefab variant bị xóa

Lời nhắc ranh giới một dòng:

This pass only fixes lost UI Prefab references. Do not change any gameplay scripts under Assets/Scripts/Combat.

Tóm tắt

  1. AI Studio cung cấp cấu trúc HUD vào Unity
  2. PlayerHealth phát (current, max)
  3. HudHealthView đăng ký và cập nhật fillAmount / text
  4. Unity MCP gắn component, điền tham chiếu tuần tự hóa, áp dụng sửa lỗi Console tối thiểu
  5. Chấp nhận với phím sát thương + checklist Play—không phải “script generated successfully”

Điều đó khép lại một vòng lặp lặp lại: UI vào engine → kết nối sự kiện → chấp nhận Play. Túi đồ, thanh mana và thanh boss có thể sao chép cùng mẫu.

Các bài hướng dẫn bạn có thể thích