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 がランタイムアセンブリに漏れてパック時に爆発、など。
本稿の主軸は 3 つだけ(タイトルと一致):
- Console / スタック → スクリプトとシーンオブジェクトを特定
- Build Settings、Missing Script、シリアライズ参照を照合
- Unity MCP で Cursor 内読み取り専用診断 → 確認後に最小修正
プラグインインストールやストア出荷の全手順は繰り返しません。IL2CPP stripping やネイティブプラグインは文末の拡張へ。
関連記事:
- Unity MCP インストール
- Claude Code と Cursor で Unity MCP を使う
- AI Studio からエクスポートした HUD を HP イベントに接続(正しい配線;本稿は「切れたらどう探すか」)
まず層を切り分ける
A. ビルドウィンドウ赤字(コンパイル / パック段階の失敗)
↓
B. パッケージは作れるが、実機起動でクラッシュ / 黒画面
↓
C. ゲームは入れるが、特定シーンや機能で実行時に落ちる
| 見える症状 | 層 | 本稿で先に見る |
|---|---|---|
Build 失敗、error CS… / 型が見つからない | A | ランタイムアセンブリが UnityEditor を誤参照、条件コンパイル、asmdef |
| 起動シーン入場直後 NRE / MissingReference | B/C | シーンがビルドに入っているか、Missing Script、Inspector の None |
特定の Resources.Load / アドティブシーンでのみ | C | パス大文字小文字、リソースがパッケージ内か、シーンがロード済みか |
Unity MCP は開いているエディターが得意:Console、Hierarchy、コンポーネントフィールド。実機の logcat / Xcode スタックは Cursor に貼る必要あり。または先に Development Build を打ち、可能なら Editor で同じ起動シーンを再現。
トラブルシュートループ(手動 + MCP)
失敗のたびに順番に。手動を飛ばして AI に Player を書き換えさせない。
ステップ 0:手動で現場を固定(約 2 分)
Cursor に頼る前に自分で:
- Unity バージョン、ターゲット(例 Android / IL2CPP)をメモ
- Window → General → Console をクリアし、Build または Development Build を 1 回
- 最初の関連 Error(スタック付き)をコピー——Warning の壁だけは不可
- File → Build Settings を開く:疑いのシーンにチェックがあるか、リスト 0 番が起動シーンか
- Prefab を編集した場合:インスタンスで Apply したか(未 Apply のオーバーライドは他人のパッケージに入らず、想定ディスク資産にも入らないことが多い)
ステップ 1:MCP 読み取り専用で Console 分類
今回のビルド / 直前の Play に関連する Console の 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 参照、「戦闘の書き換え」ではない
手動
- Build Settings に HUD のシーンが含まれるか
- シーンを開き
HudHealthViewのオブジェクトを選択、healthFill/playerHealthが None か - 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 → HP イベント。本稿が求めるのは:スタックでフィールドを固定してから再接続。
症状対照(主軸)
症状 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 は「なんとなく正常」
順番に調べ、並列の大改修はしない:
- シーンが Build Settings にない、または起動シーンの認識違い
- Missing Script / シリアライズ None(Prefab 未 Apply 含む)
- アドティブシーン未ロードのまま Find / アクセス
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 でスクリプトファイルが残っているか、asmdef/GUID 断裂がないか確認;空コンポーネント削除は一つずつ確認してから。
受け入れチェックリスト
- 同種の Error が Console から消える
- Editor Play で同じ落ちる操作(ステージ入場、ダメージ、UI 開く等)を再現
- ターゲット(またはローカル Player)へ Development Build を 1 回
- MCP 読み取り専用再確認:疑いフィールドが None / Missing でない
- Git diff は想定どおりの小さなシーン/Prefab/スクリプト変更のみ——「ついでリファクタ」なし
読み取り専用再確認:<オブジェクト一覧> の関連フィールドに None または Missing Script は残っているか?例外を列挙。編集しない。
プロンプトの赤線
| やらない | やる |
|---|---|
| 「とにかく Play できるように」 | 先に A/B/C 判定 + スタックでフィールド固定 |
参照の代わりに大量 Find | シリアライズフィールド修正または明示的注入 |
| 未確認で Build Settings 順序変更 | 先に現在の一覧と起動シーンを報告 |
| 「NRE がある」だけ | スタック先頭 20~40 行を貼る |
プロダクト境界
- Unity MCP:エディター内 Console、Hierarchy、スクリプトと参照——本稿の主軸に適合。
- AI Studio:UI 構造をエンジンへ;再エクスポートで参照が消えたら配線記事どおり再接続——ゲームプレイから UI を Find しない。
- 証明書、ストア、ベンダー ROM:ログテキストを Cursor に貼れば読み取り支援;MCP のシーン編集範囲外。
拡張:主軸外だがよくある
以下は「参照問題」と混ざりやすい——本稿の主軸を先に除外してから:
| 現象 | 方向 |
|---|---|
| Development OK、Release で落ちる | Managed Stripping / link.xml;MCP へ:「クラッシュスタックから strip された型を推測;link.xml を提案;まだファイルは書かない。」 |
| Android ネイティブクラッシュのみ(非マネージドスタック) | .so / 権限 / Gradle;logcat を貼って読み取り |
| メインスレッド外で Unity API | 非同期コールバックがメインスレッドに戻っているか確認 |
stripping と Missing Script を一度の「大リファクタ」にまとめない。
まとめ
- Editor OK / パッケージ NG → まず 参照 / ビルド入りシーン / パス / Editor API として調べる
- 手動で Build Settings と最初の Error を固定し、MCP 読み取り専用分類
- スタック → スクリプト行 → コンポーネントフィールド;確認後に最小再接続または空コンポーネント削除
Findやゲームプレイ書き換えで偽装修正しない- Development Build + 読み取り専用再確認で受け入れ
「現場固定 → 層分け → 三つセット → サンプル同様にフィールド固定」で回せば、実機の参照バグの多くはレビュー可能な小さな diff に収まる。
続きを読む
こちらの記事もおすすめです
2026年ゲーム開発のAI効率化:使えるAIプログラミングの組み合わせ
ゲーム開発のAI効率化実践:Cursor、Claude Code、Copilot の組み合わせ方、エンジン MCP と AI Studio の役割、Unity / Godot / Cocos チームが今週から回せるワークフロー。
- ゲーム開発AI
- AIプログラミング
- cursor
- claude-code
Godot 4 HUD と Theme:Control ツリー引き渡しと Play 受け入れ
Figma から Godot 4 へ載せた Theme・StyleBox・コンテナアンカー・minimum_size の受け入れ基準。Unity UGUI チェックリストと同型の 6 Play 手順と修正表。引き渡しガイド(Theme エディタチュートリアルではない)。
- game-ui-design
- game-dev-ai
- ui-to-engine
- godot
バトルポップアップ数字:引き継ぎ受け入れとエンジン実装
ポップアップのボケ、欠字、描画順、同屏カクつきの不合格基準。TMPとビットマップ数字の選び方、プールとCanvas順序、Unity UGUIの6ステップ、デザイン数字アートの渡し方。
- game-ui-design
- game-dev-ai
- ui-to-engine
- bitmap-font