← 返回部落格

Editor 能跑、建置掛了:用 Unity MCP 根據 Console 定位引用問題

針對 Unity「編輯器正常、真機/Player 建置失敗或進場景 NRE」:按 A/B/C 分層,用 Cursor + Unity MCP 讀 Console、核對 Build Settings 與序列化引用;含堆疊樣例、人手檢查項與最小修復。

發布於
  • Unity MCP
  • Unity
  • Console
  • build
  • Android
  • Cursor
  • troubleshooting
  • AI game development

「Unity works in editor, fails on device / build」類貼文裡,症狀高度重複:本機 Play 正常,一打 Player / 真機包 就建置紅字、閃退、黑屏,或進場景立刻 NullReferenceException。多數不是引擎壞了,而是編輯器路徑掩蓋了引用與平台差異——場景未進包、序列化欄位在磁碟上是 None、路徑大小寫、把 UnityEditor API 寫進執行時期組件,到打包或真機才爆。

本文主軸只有三條(與標題一致):

  1. Console / 堆疊 → 定位腳本與場景物件
  2. 核對 Build Settings、Missing Script、序列化引用
  3. 用 Unity MCP 在 Cursor 裡唯讀診斷 → 確認後最小修復

不重複外掛安裝,不寫完整上架流水線;IL2CPP 剝離、原生外掛等放文末擴充。

相關閱讀:

先分清:掛在哪一層

A. 建置視窗紅字(編譯 / 打包階段失敗)
        ↓
B. 包能打出,真機一開就閃退 / 黑屏
        ↓
C. 能進遊戲,進某場景或點某功能才炸(執行時期)
你看到的層本文優先查
Build 失敗,error CS… / 找不到類型A執行時期組件誤引用 UnityEditor、條件編譯、asmdef
進啟動場景立刻 NRE / MissingReferenceB/C場景是否進包、Missing Script、Inspector 裡 None
某 Resources.Load / 加性場景才掛C路徑大小寫、資源是否在包內、場景是否載入

Unity MCP 強項在已開啟的編輯器:讀 Console、掃 Hierarchy、看元件欄位。真機 logcat / Xcode 需你把堆疊貼進 Cursor;或先打 Development Build,盡量在 Editor 用同一啟動場景重現。

排障環(人手檢查 + MCP)

每次失敗按順序做,不要跳過「人手」直接讓 AI 重寫 Player。

步驟 0:人手固定現場(2 分鐘)

在 Cursor 開口前,自己先完成:

  1. 記下 Unity 版本、目標平台(如 Android / IL2CPP)
  2. Window → General → Console 清空,再 Build 或 Development Build 一次
  3. 複製第一條相關 Error(含堆疊),不要只丟 Warning 牆
  4. 開啟 File → Build Settings:嫌疑場景是否勾選;列表第 0 項是否為啟動場景
  5. 若改過 Prefab:實例上是否 Apply(未 Apply 的覆寫不會進別人的包,也常進不了你以為的磁碟資源)

步驟 1:MCP 唯讀分類 Console

彙總目前 Console 裡與本次建置/上次 Play 相關的 Error(忽略 Info)。
按「編譯錯誤 / Missing Script / NullReference / 資源載入」分類。
列出每條錯誤中的腳本路徑、行號、GameObject 名(若日誌有)。
不要修改任何資源。

步驟 2:人手 + MCP 核對「引用三件套」

對執行時期 NRE(B/C),在編輯器裡點開堆疊裡的物件,並讓 MCP 交叉驗證:

人手MCP 提示
Build Settings 場景列表截圖或口述「列出 Build Settings 中的場景路徑與是否啟用;指出啟動場景。」
選中嫌疑物件,看 Inspector 是否 Missing Script / 引用 None「在場景 <Name> 列出 Missing Script;檢查 <Object> 上 <Component> 各序列化欄位是否為 None。表格輸出。不要改。」
Prefab 模式 vs 場景實例是否一致「說明 <X> 是 Prefab 資源還是場景實例;實例上有無未 Apply 覆寫(若可見)。只報告。」

原則: 打包用的是磁碟上的場景/Prefab。Editor 裡靠 OnValidate 臨時賦值、「看起來有引用」,以 MCP/Inspector 讀到的序列化結果為準。

步驟 3:先診斷範本,確認後再改

【約束】
- 先診斷與最小方案,等我確認後再改
- 禁止用大面積 GameObject.Find 冒充修復
- 只動與本條 Error 直接相關的腳本/Prefab/場景

【現場】
- Editor Play:正常 / 異常(如實填)
- 平台與建置:…
- Build Settings 啟動場景:…
- Console / 裝置堆疊(原文):
<貼上>

【請回答】
1. 屬於 A / B / C 哪一層
2. 最可能的 1~2 個根因(未進包 / None 引用 / Missing Script / 大小寫 / Editor API…)
3. 要我核對的物件與欄位名
4. 最小修復步驟(仍先不執行)

步驟 4:確認後最小寫入 + 複查

按確認方案執行最小修復:僅修 <物件.欄位> 或 <腳本路徑> 中與本 Error 相關的幾行。
儲存場景/Prefab。
然後唯讀複查:相關欄位是否仍為 None;Console 是否還有同類 Error。

完整樣例:從一條 NRE 堆疊到欄位

下面是一段仿真實裝置/Player 日誌(結構常見;路徑按你專案替換)。

日誌

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

判層

  • 能進 Play/包並執行到 Update → 不是 A(編譯已過)
  • 一受傷就炸 → C(執行時期),嫌疑是 UI 引用,不是「重寫戰鬥」

人手

  1. Build Settings 是否包含該 HUD 所在場景
  2. 開啟場景,選中掛 HudHealthView 的物件,看 healthFill / playerHealth 是否為 None
  3. 若在 Prefab 上改過:是否 Apply

給 MCP

唯讀:開啟含 HUD 的場景。
1. 找到掛有 HudHealthView 的物件
2. 報告 healthFill、playerHealth(及同類)欄位是否為 None / Missing
3. 不要修改
根據結果:若為 None,最小方案應是重新指定引用並儲存,而不是改 TakeDamage 邏輯。

最小修復(確認後)

  • 把 HUD_HealthFill 的 Image 拖回 healthFill,Player 上的 PlayerHealth 拖回 playerHealth
  • 儲存場景;Development Build 再走一次受傷

錯誤「修復」(不要做)

// 反例:用 Find 掩蓋 None —— 真機改名或加性載入後仍會掛
healthFill = GameObject.Find("HUD_HealthFill").GetComponent<Image>();

正確方向與接線步驟見 HUD 綁血量事件;本文只要求:先用堆疊釘住欄位,再綁回去。

症狀對照(主軸)

症狀 1:建置紅字,找不到類型 / UnityEditor

可能根因人手給 MCP
執行時期腳本引用了 Editor API看報錯檔案是否在非 Editor/ 目錄「搜尋非 Editor 資料夾中的 UnityEditor.;只列路徑。」
#if 寫反,Player 缺類型核對 UNITY_EDITOR 包裹「說明該檔案在 Editor 與 Player 下哪些類型可見。」
asmdef 未引用開啟報錯組件的 .asmdef「列出該 asmdef 引用,說明缺哪一個。」

反例(執行時期組件裡誤用 Editor API,Player 建置必掛):

using UnityEngine;
using UnityEditor; // 若檔案不在 Editor 組件,建置失敗

public class BadBake : MonoBehaviour
{
    [MenuItem("Tools/Bad")] // 進一步依賴 UnityEditor
    static void Run() { }
}

正解 A:整檔放進 Editor 資料夾

Assets/Scripts/Editor/BakeTools.cs   ← 僅編輯器編譯

正解 B:同一檔案內隔離(僅當必須同檔時)

using UnityEngine;

public class RuntimeSafe : MonoBehaviour
{
    public void DoGameplay() { /* Player 可見 */ }

#if UNITY_EDITOR
    [ContextMenu("Debug/Fill Refs")]
    void EditorOnlyFill()
    {
        // 僅編輯器;不要在 Awake 裡依賴這裡的結果當打包資料
    }
#endif
}

更乾淨的做法是 Editor 專用腳本 + asmdef,避免執行時期組件被 Editor 引用拖死。

症狀 2:真機進場景 NRE,Editor Play「好像正常」

按順序查,不要並聯大改:

  1. 場景未進 Build Settings 或啟動場景不是你想的那一個
  2. Missing Script / 序列化 None(含 Prefab 未 Apply)
  3. 加性場景未載入 就 Find / 存取物件
  4. Resources.Load 路徑大小寫(macOS Editor 常不敏感,Android 敏感)
1. 報告 Build Settings 場景列表與啟用狀態、啟動場景索引
2. 在場景 <X> 列出全部 Missing Script
3. 檢查啟動路徑上 GameManager / Player / HUD 的公開引用是否為 None
只報告,不修改。
編輯器裡包裡常見原因
引用看著有執行 None實例覆寫未 Apply;改錯場景檔
Find 得到真機 null物件在未載入場景;名稱不一致
Resources.Load 成功真機 null路徑大小寫;資源不在 Resources/
// 磁碟:Assets/Resources/UI/HealthBar.png
// Android 上常失敗(大小寫不一致):
Resources.Load<Sprite>("ui/healthbar");
// 應與 Resources 下相對路徑一致,例如:
Resources.Load<Sprite>("UI/HealthBar");
搜尋專案中 Resources.Load / Addressables.LoadAssetAsync 的路徑字串,
與實際檔案相對路徑做大小寫對照表。不要改程式碼。

症狀 3:Console 刷 Missing Script

掃描場景 <X> 與 Prefab <path>:
列出 Missing Script 的物件路徑。
對每個給出「重掛原腳本」或「刪除空元件」建議(根據殘留腳本名/GUID 若可見)。
先不要批次自動刪除。

人手:在 Project 視窗確認腳本檔還在、沒有改組件定義導致 GUID 斷裂;一條條確認再刪空元件。

驗收清單

  1. 同類 Error 從 Console 消失
  2. Editor Play 走同一條會炸操作(進關、受傷、開介面等)
  3. 打一次 Development Build 到目標平台(或本機 Player)
  4. MCP 唯讀複查 嫌疑欄位不再為 None / Missing
  5. Git diff 僅含預期的場景/Prefab/腳本小改,沒有「順手重構」
唯讀複查:<物件列表> 上相關欄位是否仍有 None 或 Missing Script?列出異常項。不要修改。

提示詞紅線

不要要
「隨便修到能 Play」先判 A/B/C + 堆疊釘欄位
大面積 Find 代替引用修序列化欄位或顯式注入
未確認就改 Build Settings 順序先報告目前列表與啟動場景
只說「有個 NRE」貼堆疊前 20~40 行

產品邊界

  • Unity MCP:編輯器內 Console、Hierarchy、腳本與引用——適合本文主軸。
  • AI Studio:UI 結構進引擎;重匯弄丟引用時按接線文重綁,不要在玩法裡 Find UI。
  • 憑證、商店、廠商 ROM:把日誌文字貼進 Cursor 即可協助閱讀,不在 MCP 改場景範圍內。

擴充:不在主軸但仍常見

以下易與「引用問題」攪在一起,先排除本文主軸再查:

現象方向
Development 正常、Release 掛Managed Stripping / link.xml;對 MCP:「根據崩潰棧猜測被裁類型,提議 link.xml,先不寫檔案。」
僅 Android 原生崩潰(非託管棧).so / 權限 / Gradle;貼 logcat 給模型閱讀
非主執行緒碰 Unity API查非同步回呼是否回到主執行緒

不要把 stripping 和 Missing Script 合成一次「大重構」。

小結

  1. Editor 能跑、包掛了:先當 引用 / 進包場景 / 路徑 / Editor API 查
  2. 人手固定 Build Settings 與第一條 Error,再讓 MCP 唯讀分類
  3. 用堆疊釘到腳本行 → 元件欄位,確認後最小綁回或刪空元件
  4. 禁止用 Find 和重寫玩法冒充修復
  5. 以 Development Build + 唯讀複查驗收

按「現場 → 分層 → 三件套 → 樣例同款釘欄位」跑,多數真機引用問題會收成可審查的小 diff。

你可能還會喜歡這些文章

ChinaJoy 2026:VberAI 在 W5 展區的現場觀察

記錄 VberAI 參加 2026 ChinaJoy(上海新國際博覽中心 W5):國內外訪客與決策者到訪,宣傳冊首日發完,俄羅斯客戶密集諮詢,以及與韓國 3D 資產公司交流、下月遊戲 3D 資產生成能力與對接意向。

  • ChinaJoy
  • VberAI
  • AI Studio
  • 3D資產
閱讀全文