← Về blog

Editor Chạy Tốt, Build Lỗi: Truy Vết Lỗi Console đến Script và Scene Refs với Unity MCP

Khi Play trong Editor ổn nhưng build Player/thiết bị lỗi hoặc NRE khi nạp scene: phân lớp A/B/C, dùng Cursor + Unity MCP để đọc Console, kiểm tra Build Settings và serialized refs—kèm mẫu stack, kiểm tra thủ công và sửa lỗi tối thiểu.

Đăng ngày
  • Unity MCP
  • Unity
  • Console
  • build
  • Android
  • Cursor
  • troubleshooting
  • AI game development

Các chủ đề có tiêu đề kiểu “Unity chạy trong Editor nhưng lỗi trên thiết bị / build” thường giống nhau: Play chạy tốt, sau đó build Player / thiết bị báo đỏ, crash, màn hình đen, hoặc ném NullReferenceException khi vào scene. Động cơ hiếm khi “hỏng”—đường dẫn Editor đã che giấu các khoảng trống về reference và nền tảng: scene không có trong danh sách build, serialized fields bị None trên đĩa, phân biệt hoa thường của đường dẫn, hoặc API UnityEditor bị rò rỉ vào assembly runtime cho đến lúc đóng gói.

Bài viết này có ba trụ cột (giống như tiêu đề):

  1. Console / stack → script và scene objects
  2. Kiểm tra Build Settings, Missing Script, serialized refs
  3. Chẩn đoán chỉ đọc trong Cursor qua Unity MCP → sửa lỗi tối thiểu sau khi xác nhận

Không có hướng dẫn cài plugin, không có hướng dẫn đăng bán đầy đủ. IL2CPP stripping và native plugins nằm ở phụ lục.

Liên quan:

Đầu tiên: lớp nào đã lỗi?

A. Cửa sổ Build đỏ (lỗi biên dịch / đóng gói)
        ↓
B. Build thành công; thiết bị chết hoặc màn hình đen khi khởi động
        ↓
C. Trò chơi khởi động; một scene hoặc tính năng nổ tung lúc runtime
Điều bạn thấyLớpKiểm tra đầu tiên ở đây
Build lỗi, error CS… / không tìm thấy typeARuntime assembly tham chiếu UnityEditor, #if sai, asmdef
NRE / MissingReference ở scene khởi độngB/CScene trong danh sách build, Missing Script, None trong Inspector
Chỉ lỗi khi Resources.Load / scene cộng thêmCPhân biệt hoa thường đường dẫn, asset trong gói, scene thực sự được tải

Unity MCP mạnh nhất khi editor đang mở: Console, Hierarchy, component fields. Stack từ logcat / Xcode trên thiết bị phải được dán vào Cursor—hoặc tạo Development Build và tái hiện với cùng scene khởi động trong Editor nếu có thể.

Vòng lặp xử lý sự cố (thủ công + MCP)

Đừng bỏ qua bước thủ công và yêu cầu AI viết lại Player.

Bước 0: Đóng băng scene bằng tay (~2 phút)

Trước khi dùng Cursor:

  1. Ghi chú phiên bản Unity và nền tảng mục tiêu (ví dụ: Android / IL2CPP)
  2. Xóa Window → General → Console, sau đó Build hoặc Development Build một lần
  3. Sao chép Error có liên quan đầu tiên (kèm stack)—không phải bức tường Warning
  4. Mở File → Build Settings: scene nghi ngờ có được chọn không? index 0 có phải scene khởi động không?
  5. Nếu bạn đã chỉnh sửa một Prefab instance: bạn đã Apply chưa? Các override chưa áp dụng thường không bao giờ được ghi vào asset trên đĩa mà bạn nghĩ là đã đóng gói

Bước 1: MCP đọc-only Console phân loại

Tóm tắt các lỗi Console liên quan đến build này / lần Play gần nhất (bỏ qua Info).
Phân loại thành compile / Missing Script / NullReference / tải tài nguyên.
Liệt kê đường dẫn script, dòng, tên GameObject cho mỗi lỗi nếu có.
Không sửa đổi bất kỳ asset nào.

Bước 2: Thủ công + MCP “bộ ba tham chiếu”

Đối với NRE runtime (B/C), chọn đối tượng trong stack trong editor và đối chiếu với MCP:

Thủ côngMCP prompt
Danh sách Build Settings (ảnh chụp màn hình hoặc đọc to)“Liệt kê đường dẫn scene trong Build Settings và cờ bật; nêu tên scene khởi động.”
Inspector: Missing Script / refs None”Trong scene <Tên>, liệt kê Missing Scripts; kiểm tra serialized fields trên <Object>.<Component> có None không. Chỉ bảng. Không sửa.”
Prefab asset so với scene instance”<X> là Prefab asset hay scene instance? Có override chưa áp dụng nào nếu thấy không? Chỉ báo cáo.”

Quy tắc: Gói sử dụng scene/Prefab trên đĩa. Các OnValidate tạm thời làm cho “trông ổn” trong Editor không được tính—tin tưởng giá trị serialized từ MCP/Inspector.

Bước 3: Mẫu chẩn đoán, sau đó xác nhận

[Ràng buộc]
- Chẩn đoán và đề xuất kế hoạch tối thiểu; chờ tôi đồng ý trước khi sửa
- Không giả vờ sửa bằng cách dùng GameObject.Find hàng loạt
- Chỉ đụng đến script/Prefab/scene liên quan đến Error này

[Bối cảnh]
- Editor Play: OK / hỏng (trung thực)
- Nền tảng / build: …
- Scene khởi động trong Build Settings: …
- Console / stack thiết bị (thô):
<paste>

[Trả lời]
1. Lớp A / B / C
2. 1–2 nguyên nhân gốc hàng đầu (không có trong build / None ref / Missing Script / hoa thường / Editor API…)
3. Đối tượng và tên field tôi nên kiểm tra
4. Các bước sửa tối thiểu (vẫn chưa thực hiện)

Bước 4: Ghi tối thiểu + kiểm tra lại

Áp dụng bản sửa tối thiểu đã xác nhận: chỉ <object.field> hoặc vài dòng trong <đường dẫn script> cho Error này.
Lưu scene/Prefab.
Sau đó kiểm tra lại chỉ đọc: fields vẫn None? Error tương tự vẫn còn trong Console?

Ví dụ thực tế: stack → field

Log Player/thiết bị tổng hợp nhưng thực tế (thay đường dẫn cho dự án của bạn).

Log

NullReferenceException: Object reference not set to an instance of an object
  at HudHealthView.HandleHealthChanged (System.Single current, System.Single max) [0x00000] in Assets/Scripts/UI/HudHealthView.cs:42
  at PlayerHealth.TakeDamage (System.Single amount) [0x00000] in Assets/Scripts/Combat/PlayerHealth.cs:28
  at DebugDealDamage.Update () [0x00000] in Assets/Scripts/Debug/DebugDealDamage.cs:15

Lớp

  • Đến được Update → không phải A (biên dịch OK)
  • Chết khi nhận sát thương → C (runtime); nghi ngờ UI refs, không phải “viết lại combat”

Thủ công

  1. Scene chứa HUD có trong Build Settings không?
  2. Chọn đối tượng HudHealthView; healthFill / playerHealth có None không?
  3. Chỉnh sửa Prefab: đã Apply chưa?

MCP

Chỉ đọc: mở scene chứa HUD.
1. Tìm các đối tượng có HudHealthView
2. Báo cáo healthFill, playerHealth (và các field tương tự) có None / Missing không
3. Không sửa
Nếu None: kế hoạch tối thiểu là gán lại refs và lưu—không thay đổi TakeDamage.

Sửa tối thiểu (sau khi OK)

  • Kéo Image HUD_HealthFill → healthFill; PlayerHealth của Player → playerHealth
  • Lưu; Development Build; nhận sát thương lần nữa

”Sửa” tồi (đừng làm)

// Phản mẫu: Find che giấu None — vẫn hỏng khi đổi tên / tải cộng thêm
healthFill = GameObject.Find("HUD_HealthFill").GetComponent<Image>();

Kết nối đúng: HUD → sự kiện health. Ở đây: xác định field từ stack, sau đó gán lại.

Ma trận triệu chứng (trụ cột)

Triệu chứng 1: Build đỏ — không tìm thấy type / UnityEditor

Nguyên nhân có thểThủ côngMCP
Script runtime dùng API EditorFile có nằm ngoài Editor/ không?”Tìm UnityEditor. ngoài thư mục Editor; chỉ liệt kê đường dẫn.”
#if đảo ngược, Player thiếu typesKiểm tra UNITY_EDITOR bao quanh”Những type nào tồn tại trong Editor so với Player cho file này?”
Khoảng trống asmdefMở .asmdef đang lỗi”Liệt kê refs asmdef; cái nào thiếu?”

Phản mẫu (API Editor trong assembly runtime → build Player lỗi):

using UnityEngine;
using UnityEditor; // Lỗi build nếu không phải assembly Editor

public class BadBake : MonoBehaviour
{
    [MenuItem("Tools/Bad")] // phụ thuộc thêm UnityEditor
    static void Run() { }
}

Sửa A: toàn bộ file trong Editor/

Assets/Scripts/Editor/BakeTools.cs   ← chỉ biên dịch trong Editor

Sửa B: cô lập trong file (chỉ khi bắt buộc dùng chung file)

using UnityEngine;

public class RuntimeSafe : MonoBehaviour
{
    public void DoGameplay() { /* hiển thị cho Player */ }

#if UNITY_EDITOR
    [ContextMenu("Debug/Fill Refs")]
    void EditorOnlyFill()
    {
        // Chỉ Editor — không coi đây là dữ liệu runtime đóng gói từ Awake
    }
#endif
}

Sạch hơn nữa: script chỉ dành cho Editor + asmdef để assembly runtime không bao giờ kéo theo refs Editor.

Triệu chứng 2: NRE trên thiết bị khi vào scene; Editor Play “có vẻ ổn”

Kiểm tra theo thứ tự—không viết lại hàng loạt song song:

  1. Scene không có trong Build Settings hoặc scene khởi động sai
  2. Missing Script / serialized None (bao gồm Prefab chưa Apply)
  3. Scene cộng thêm chưa được tải trước khi Find / truy cập
  4. Đường dẫn Resources.Load phân biệt hoa thường (Editor macOS thường không phân biệt; Android thì có)
1. Báo cáo scenes trong Build Settings, cờ bật, index khởi động
2. Liệt kê tất cả Missing Scripts trong scene <X>
3. Kiểm tra public refs trên GameManager / Player / HUD dọc theo đường khởi động có None không
Chỉ báo cáo; không sửa.
Trong EditorTrong góiNguyên nhân điển hình
Refs trông đã setRuntime NoneOverride instance chưa áp dụng; sửa nhầm file scene
Find hoạt độngThiết bị nullĐối tượng trong scene chưa tải; tên không khớp
Resources.Load hoạt độngThiết bị nullPhân biệt hoa thường; asset không nằm trong Resources/
// Trên đĩa: Assets/Resources/UI/HealthBar.png
// Thường lỗi trên Android (sai hoa thường):
Resources.Load<Sprite>("ui/healthbar");
// Khớp đường dẫn dưới Resources, ví dụ:
Resources.Load<Sprite>("UI/HealthBar");
Tìm chuỗi đường dẫn Resources.Load / Addressables.LoadAssetAsync;
lập bảng phân biệt hoa thường so với đường dẫn thực tế. Chưa sửa code.

Triệu chứng 3: Console ngập Missing Script

Quét scene <X> và Prefab <đường dẫn>:
Liệt kê đường dẫn GameObject có Missing Script.
Với mỗi mục: đề xuất gắn lại script gốc hoặc xóa component rỗng (từ tên/GUID còn sót nếu thấy).
Không tự động xóa hàng loạt.

Thủ công: xác nhận file script vẫn tồn tại và asmdef/GUID không bị hỏng; xác nhận từng cái một trước khi xóa component rỗng.

Danh sách kiểm tra nghiệm thu

  1. Các Error khớp biến mất khỏi Console
  2. Editor Play đi qua cùng đường lỗi (vào level, nhận sát thương, mở UI…)
  3. Một Development Build đến nền tảng đích (hoặc Player cục bộ)
  4. MCP kiểm tra lại chỉ đọc: các field nghi ngờ không còn None / Missing
  5. Git diff chỉ là thay đổi nhỏ mong đợi ở scene/Prefab/script—không refactor lan man
Kiểm tra lại chỉ đọc: có None hoặc Missing Script nào trên <danh sách đối tượng> không? Liệt kê ngoại lệ. Không sửa.

Ranh giới prompt

Không nênNên
”Chỉ cần làm Play chạy”Phân lớp A/B/C + xác định field từ stack
Dùng Find hàng loạt thay vì refsSửa serialized fields hoặc injection rõ ràng
Sắp xếp lại Build Settings không được yêu cầuBáo cáo danh sách hiện tại và scene khởi động trước
”Có NRE”Dán 20–40 dòng stack đầu tiên

Ranh giới sản phẩm

  • Unity MCP: Console, Hierarchy, scripts, refs trong editor—trụ cột của bài viết này.
  • AI Studio: cấu trúc UI vào engine; gán lại sau khi xuất lại theo bài kết nối—không dùng Find UI từ gameplay.
  • Chứng chỉ, cửa hàng, ROM OEM: dán nội dung log vào Cursor để được trợ giúp đọc; ngoài phạm vi chỉnh scene của MCP.

Phụ lục: phổ biến nhưng ngoài trụ cột

Loại trừ trụ cột của bài viết này trước:

Triệu chứngHướng giải quyết
Development OK, Release chếtManaged Stripping / link.xml; MCP: “Đoán types bị strip từ crash stack; đề xuất link.xml; chưa ghi file.”
Crash native Android (unmanaged).so / quyền / Gradle; dán logcat để đọc
API Unity ngoài luồng chínhKiểm tra callback async trả về luồng chính

Không gộp stripping và Missing Script thành một “viết lại lớn.”

Tóm tắt

  1. Editor OK / gói hỏng → xử lý refs / scenes trong build / đường dẫn / Editor API trước
  2. Thủ công đóng băng Build Settings + Error đầu tiên, sau đó MCP đọc-only phân loại
  3. Stack → dòng script → component field; gán lại hoặc xóa component rỗng sau khi xác nhận
  4. Không dùng Find hoặc viết lại gameplay như sửa giả
  5. Nghiệm thu với Development Build + kiểm tra lại chỉ đọc

Chạy “đóng băng → phân lớp → bộ ba tham chiếu → xác định field như mẫu” và hầu hết lỗi ref trên thiết bị sẽ thu về một diff nhỏ dễ xem xét.

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