Claude Code × Unity Editor GUI実験レポート
-
2026年5月14日
こんにちは。
Cocone Engineering で クライアントエンジニア をしている 新井 です。
今回は、AIコーディングツール「Claude Code」に、Unity EditorのGUI(EditorWindow)12個・約5,000行をほぼ全て実装させる実験を行いました。 12日間の開発を通じて、初期生成は手動比5〜10倍の速度で完了する一方、バグ修正に全工数の50%を要するという結果が得られましたので、その詳細と知見をお伝えします。
はじめに
以前、別のUnityプロジェクトにおいてAIにコード生成を任せる実験を行い、AIとUnity開発を組み合わせる際の得意・不得意領域がある程度見えてきました。
その中で特に分かったのは、以下の点です。
- GUIやPrefab周りはUnity特有の構造が強く、AIは破綻しやすい
- 一方でEditor拡張はコードベースで完結するため、比較的安定する
- ただし、Editor拡張であってもロジックとビュー(GUI)を明確に分離した方が実装精度は高い
これらの結果を踏まえ、GUI(EditorWindow)を含めてAIに任せたらどうなるかを検証する第2段階として、今回の実験を実施しました。
狙いとしては、ScriptableObjectベースのマスターデータ管理パッケージの開発において、Unity Editor GUIも含めてAIにほぼ全実装を委譲し、その品質・バグ傾向・人間の介入量・開発速度を検証することです。
実験の概要
実験の目的
今回の実験では、AIにUnity Editor GUIの実装をどこまで任せられるかを確認することを主な目的としました。
具体的には、ScriptableObjectベースのマスターデータ管理パッケージの開発を題材として、 以下の4点を同一プロジェクトの一連の作業の中で検証します。
| 検証項目 | 内容 |
|---|---|
| 品質 | 生成されたGUIはそのまま実用に耐えるか |
| バグ傾向 | どのような種類のバグが発生しやすいか |
| 人間の介入量 | レビュー・テスト・UX調整など、人間が引き受けるべき作業はどこか |
| 開発速度 | 初期生成からバグ修正までを含めた、実質的な生産性は向上するか |
Unity Editor GUIは、EditorWindow や SerializedObject、IMGUIの描画パス (Layout / Repaint)など、Unity特有のAPIや暗黙知が多く要求される領域です。
ドキュメントだけでは拾いきれない制約も多く、AIにとっては比較的難易度の高い対象だと考えています。
そのため、この領域で実用品質に到達できるのであれば、より素直なロジック実装やテスト生成では当然成立するはず、という下限ベンチマークとしての位置づけで実験を設計しました。
実験条件
| 項目 | 内容 |
|---|---|
| 実験期間 | 2026/01/29 〜 2026/02/09(12日間) |
| 使用ツール | Claude Code (Claude Opus 4.6), Codex CLI |
| Unity Version | 6000.0+ |
| GUI技術 | Unity IMGUI (EditorWindow, EditorGUILayout) |
※ Codex CLI は、OpenAIが提供するターミナル上で動作するAIコーディングエージェントです。
本実験ではコードレビュー用途で使用しました。
対象パッケージの機能
開発したパッケージは、ScriptableObjectをベースとしたマスターデータ管理ツールです。主な機能は以下の通りです。
- テーブル定義(YAML)の作成・編集
- CSV/データのインポート・エクスポートと差分プレビュー
- レコードのCRUD操作
- SQL風のクエリ実行(JOIN、GROUP BY、集計関数を含む)
- バリデーション、スキーマ比較
- パフォーマンス計測・監視
- バックアップ管理
- テストデータ生成
実装規模
| カテゴリ | 数量 |
|---|---|
| EditorWindow | 12個 |
| Inspector / PropertyDrawer | 4個 |
| GUI関連コード合計 | 約5,000行 |
| Runtime コード | 約10,000行 |
| テストコード | 約3,000行 |
| 開発フェーズ | Phase 0 〜 Phase 10 |
作成されたEditorWindow一覧
| Window | 行数 | 概要 | AI生成 |
|---|---|---|---|
| DataEditorWindow | 908行 | レコード編集、CRUD操作 | ✅ |
| DiffViewerWindow | 548行 | インポート差分プレビュー | ✅ |
| SqlEditorWindow | 481行 | SQL入力、シンタックスハイライト、結果表示 | ✅ |
| BenchmarkWindow | 472行 | パフォーマンス計測 | ✅ |
| DatabaseBrowserWindow | 447行 | テーブル一覧、レコード閲覧 | ✅ |
| ValidationWindow | 378行 | バリデーション結果表示 | ✅ |
| SchemaCompareWindow | 328行 | スキーマ差分比較 | ✅ |
| TestDataGeneratorWindow | 306行 | テストデータ生成 | ✅ |
| TableEditorWindow | 285行 | テーブル定義YAML編集 | ✅(一部手動) |
| PerformanceWindow | 279行 | ランタイムパフォーマンス監視 | ✅ |
| BackupWindow | 279行 | バックアップ管理 | ✅ |
| StreamingImportWindow | 150行 | 大量データストリーミングインポート | ✅ |

開発タイムライン

Day 1(1/29): Phase 0〜7 一気通貫
| 時刻 | 内容 | 備考 |
|---|---|---|
| 09:09 | Initial commit | 既存コードの投入 |
| 11:53 | CLAUDE.md・ロードマップ作成 | AIにプロジェクトの方針を伝達 |
| 12:15 | Phase 0: CSVParser修正 | テスト修正含む |
| 13:11 | Phase 1: MVP完了 | TableAsset, Database, TableEditorWindow |
| 14:12 | Phase 2: SecondaryKey完了 | IndexBuilder, QueryResult |
| 14:30 | Phase 3: CSV Import/Export完了 | DiffViewerWindow |
| 15:09 | Phase 4: SQL Editor完了 | SqlEditorWindow, DatabaseBrowserWindow |
| 16:33 | Phase 6: Validation完了 | ValidationWindow |
| 16:46 | Phase 7: Performance完了 | BenchmarkWindow, PerformanceWindow |
1日で7フェーズ、7つのEditorWindowが生成されました。 ただし、この時点では「動くが壊れている」状態のものが多数ありました。
Day 2(1/30): Phase 8〜10 + テーブルエディタ
| 内容 | 備考 |
|---|---|
| Phase 8: 追加ツール | BackupWindow, DataGeneratorWindow, SchemaCompareWindow |
| Phase 9: 高度SQL機能 | JOIN, GROUP BY, 集計関数 |
| Phase 10: テスト拡充 | SQL実行テスト |
| テーブルエディタ(定義YAML) | 途中まで |
Day 3-4(1/31-2/1): バグ修正
| 日付 | 修正内容 |
|---|---|
| 1/31 | テーブルエディタ完成、タイポ・文字化け修正 |
| 2/1 | DatabaseBrowserWindow – 非publicフィールド取得失敗 |
| 2/1 | SchemaCompareWindow – バグ修正 |
| 2/1 | SqlEditorWindow – 結果が表示されないバグ |
| 2/1 | DataEditorWindow – DateTime型カラム編集サポート追加 |
| 2/1 | コードクリーンアップ – private+SerializeField前提に修正 |
Day 5-6(2/2-2/3): 大規模リファクタリング + バグ修正
| 内容 | 備考 |
|---|---|
| SqlEditorWindowのバグ修正 | COUNT結果が(null)、GROUP BY表示が型名になってしまう |
| SqlEditorWindowのテスト追加 | バグが多かったため重点的に対応 |
| SqlExecutorの分割リファクタリング | 1ファイル2,000行超 → 5ファイルに分割 |
| 複合インデックス機能実装 | PRレビュー → 修正のサイクル |
| ドキュメント・サンプル作成 | — |
発見された主要なバグ
カテゴリ別バグ集計
| カテゴリ | 件数 | 深刻度 |
|---|---|---|
| データ取得の失敗 | 4件 | 高 |
| 表示のバグ | 5件 | 中〜高 |
| 型・名前の不一致 | 3件 | 中 |
| ロジックの誤り | 3件 | 高 |
| その他 | 2件 | 低 |
代表的なバグ詳細
【Bug 1】
SqlEditorWindow – COUNT結果が
(null)
症状: SELECT COUNT(*) FROM ItemTable の結果が (null) と表示される。
原因: GetFieldValue メソッドが ResultRow(集計結果専用の型)を想定していませんでした。AIが生成した SqlExecutor は集計結果を独自の ResultRow で返しますが、表示側の SqlEditorWindow は通常のレコード型しか想定していませんでした。
教訓: AIは個々のコンポーネントを正しく生成しますが、コンポーネント間のインターフェース整合性に弱い傾向があります。
【Bug 2】 DatabaseBrowserWindow – 非publicフィールドの取得失敗
症状: テーブルのレコードを閲覧すると、全フィールドが空欄で表示される。
原因: リフレクションで GetProperties() を使用していましたが、レコードクラスのフィールドは [SerializeField] private であり、プロパティはread-only getterのみでした。
BindingFlags.NonPublic の指定が必要でした。
教訓: CLAUDE.md(AIへの指示ファイル)で「private field + read-only accessor」パターンを明記していたにもかかわらず、AIがリフレクションコードでこの制約を考慮しませんでした。
コーディング規約を記述しただけでは、GUI側のリフレクションコードには適用されないことがあります。
【Bug 3】
GROUP BY結果のカラム名が
<BackingField>
症状: SELECT Category, COUNT(*) FROM ItemTable GROUP BY Category の結果ヘッダーが <Category>k__BackingField と表示される。
原因: C# の自動プロパティのバッキングフィールド名がそのまま出力されていました。
教訓: AIはC#の内部実装詳細(バッキングフィールド名)を理解していない場合があります。
【Bug 4】 SchemaCompareWindow – 比較結果が不正
症状: 同一スキーマを比較しても差分が表示される。
原因: フィールドの比較時にアクセス修飾子を含めてしまっていました。
【Bug 5】 SqlEditorWindow – JOINの結果ヘッダーが展開されない
症状: SELECT * FROM ItemTable JOIN EventTable の結果カラムが展開されず、テーブル名にワイルドカードがそのまま表示される。
原因: SELECT * のワイルドカード展開がJOIN時に実装されていませんでした。
AIの得意・不得意
AIが得意だったこと
■ 大量のボイラープレート生成
12個のEditorWindowの基本構造(OnGUI、メニュー登録、レイアウト)はすべて正しく生成されました。
EditorGUILayout のAPI使用も概ね適切でした。
■ テスト駆動での修正
バグを報告してテスト結果を貼り付けると、高い精度で修正コードを生成できました。
テストの追加も適切でした。
■ リファクタリング
2,000行超の SqlExecutor.cs を5つのファイルに分割するリファクタリングは、一度の指示で正確に実行されました。
■ コード生成(ClassGenerator)
YAML定義からC#レコードクラスを生成する処理は、属性の組み合わせ([SerializeField, CsvColumn, PrimaryKey, SecondaryKey])を正しく処理できました。
AIが苦手だったこと
■ コンポーネント間の整合性
個々のクラスは正しく生成されますが、複数のクラスが連携する部分でバグが発生しました。
特に、データ処理層と表示層の型の受け渡しや、Runtimeコード(private field)とEditorコード(リフレクションでの取得)の整合性が問題になりました。
■ Unity固有のエッジケース
SerializeField + private フィールドのリフレクション、IMGUIの描画タイミング(Layout/Repaintイベントの区別)、C#バッキングフィールド名の内部表現など、Unity特有の知識が必要な部分で問題が発生しました。
■ 実際の画面を見ての調整
AIは画面を見ることができないため、レイアウトの微調整やUXの改善は人間が行う必要がありました。
生成されたGUIは「機能的に動く」ものの「使いやすい」とは限りません。
■ 既存コードの暗黙の制約の理解
CLAUDE.mdに記述したコーディング規約は「新規コードの生成」には適用されましたが、「既存コードとの連携時」には無視されることがありました。
定量的分析
開発速度
| 指標 | 値 |
|---|---|
| 全EditorWindow初版完成 | 2日 |
| バグ修正完了 | 追加4日 |
| GUI関連コード総量 | 約5,000行 |
| バグ修正コミット数 | 15件 |
| リファクタリングコミット数 | 8件 |
バグ修正にかかった工数の割合
初期生成は高速でしたが、バグ修正に初期生成の1.5倍以上の時間がかかりました。

コミット分析
| 種類 | 件数 |
|---|---|
| 機能実装(Phase X完了) | 10件 |
| バグ修正 | 15件 |
| リファクタリング | 8件 |
| ドキュメント・資料 | 5件 |
| テスト追加 | 4件 |
| その他 | 5件 |
バグ修正パターンと推奨ワークフロー
バグ修正パターンの分析
【パターン1】 「テスト結果を渡して修正」(成功率: 高)
テスト結果やエラーログを直接渡すパターンです。
AIが最も得意とするパターンで、バグの特定と修正が高精度で行われました。
【パターン2】 「症状を伝えて修正」(成功率: 中)
画面の症状を言葉で伝えるパターンです。
AIが画面を見られないため、原因の推測精度が下がります(当たる確率は60%程度)。
【パターン3】 「コードレビューで発見」(成功率: 高)
Codex CLIでコードレビューを実行し、その結果をフィードバックするパターンです。
構造的な問題の発見に有効でした。

推奨ワークフロー
実験を通じて見えてきた、AIにGUI実装を任せる際の推奨ワークフローです。
【Step 1】 設計方針の明文化
CLAUDE.mdにコーディング規約を記述するだけでなく、リフレクション時のフィールドアクセス方法やデータの受け渡し方法(型、フォーマット)も明記します。
【Step 2】 インターフェースファーストで実装
まずデータ層のインターフェースを定義し、GUIはインターフェースに依存する形で生成させます。
モック不要なテストを先に書かせることも有効です。
【Step 3】 段階的な生成と検証
一度に全Windowを生成するのではなく、1つのWindow生成 → 動作確認 → 次のWindowのサイクルで進めます。動作確認はテストコードで自動化します。
【Step 4】 AIへのフィードバック
バグ報告はテスト結果かエラーログで渡します(言葉での説明より精度が高いため)。
スクリーンショットよりもテストが有効です。
Unity Test Runnerとの連携課題
現状の課題
AIに実装を委譲する場合、テスト駆動開発に近いイテレーションで進めることで事故率を大きく下げられるという結論に至りました。
しかし、UnityにおいてTDDを実践しようとすると、Test Runnerの実行結果をXMLでエクスポートしたり、失敗したテスト結果を手動でコピーしたりと、人手の介在が必要になります。
現状、AIエージェントに自動化させる場合の現実的な手順は以下の通りです。
- Unityを一度終了する
- バッチモードでTest Runnerを実行する
- 出力されたXMLをAIに読み込ませる
- 修正を行わせる
- Unityを再起動し、実機確認を行う
特にUnityの起動・終了は、小規模プロジェクトであっても無視できない時間的コストがあり、イテレーション速度を大きく下げる要因となります。
改善案:Unity × MCPサーバー
この問題を解決するための案として、Unity内にMCPサーバーを実装し、Test Runnerを直接操作可能にする方法が考えられます。MCP(Model Context Protocol)は、AIエージェントが外部ツールと連携するためのプロトコルです。
この構成が実現できれば、フローは以下のように簡略化されます。
- MCPサーバー経由でTest Runnerを実行
- テスト結果を即座に取得
- AIに修正させる
- 実機確認を行う
Unityの再起動を挟まずに済むため、イテレーション速度を維持したまま、AI主導の開発ループを回せるようになります。
実際の検証結果
上記の改善案をもとに、MCPサーバーにいくつかの機能を追加して検証を行いました。
具体的には以下のような機能です。
- Unity上の画面スクリーンショットの撮影機能
- ヒエラルキー上の構造や各コンポーネントに設定されている内容・データ構造の取得機能
- 各種オブジェクトの生成機能
なお、本実験のEditor拡張はコードベースで完結するIMGUIを使用していますが、このMCPサーバーによる検証はGameObjectベースで構築するuGUIを対象としています。
uGUIはヒエラルキー上にオブジェクトとして存在するため、MCPサーバーを通じた構造の取得やオブジェクト生成との相性が良いと考えられます。
その結果、トークン消費量はかなり大きくなるものの、ゼロベースからのGUI(uGUI)構築に関しては70%程度の精度で自動実装できることが確認できました。
ただし、バグが完全になくなるわけではなく、やはり最終的には人の手によるテストやレビューを行わないとバグが残ってしまうという課題は解消されませんでした。AIの活用によって開発速度は大幅に向上しますが、品質保証の工程を省略できるわけではないという点は、本実験全体を通じて一貫した結論です。
実験全体の結果
12日間の実験を通じて、12個のEditorWindow・約5,000行のGUIコードを2日で初版生成し、追加4日間のバグ修正・リファクタリングを経て、Asset Storeへの出品に耐える品質まで到達することができました。
定量的な観点では、初期生成は手動実装の5〜10倍の速度で進んだ一方、バグ修正にも全工数の約50%を要しました。
バグの傾向としては、個々のクラスの内部実装は概ね正しく生成されるものの、
- 複数コンポーネントを横断する型・データの受け渡し
- Unity固有の暗黙知(
[SerializeField] privateのリフレクション取得など) - 画面を見ないと気づけないレイアウトや表示の崩れ
といった箇所で破綻するパターンが顕著でした。
一方で、テスト結果やコードレビュー結果を直接渡せばAIは高い精度で修正を返してくれること、2,000行超のクラス分割のような大規模リファクタリングや、属性付きコードの生成といったボイラープレート的な作業では極めて高い精度を発揮することも確認できました。
総合すると、本実験で得られたのは「AIに任せきりにはできないが、人間がレビュー・テスト・UX調整を担い、AIがコードを書くという分業が成立すれば、これまで採算の合わなかった社内ツールやパッケージ開発に対しても現実的な投資判断ができるラインに到達している」という手応えです。
まとめ
本実験を通じて、AIにUnity Editor GUIの実装を任せることは「可能」だが、「完成品」は出てこないということが明確になりました。
最終的な評価は以下の通りです。
| 項目 | 評価 |
|---|---|
| 開発速度 | ⭐⭐⭐⭐⭐(手動比で5〜10倍速) |
| 初期品質 | ⭐⭐(動くが壊れている部分が多い) |
| バグ修正精度 | ⭐⭐⭐⭐(テストベースなら高精度) |
| UX品質 | ⭐⭐(機能的だが洗練されていない) |
| 総合的な生産性 | ⭐⭐⭐⭐(バグ修正込みでも手動より速い) |

今回の実験を通じて私個人が受けた印象を率直に書くと、Editor GUIの領域に限っていえば、Claude Code(Claude Opus 4.6)はまるで「優秀なインターンエンジニア」と協働しているかのような感覚でした。
大量のコードを高速で書いてくれる一方で、レビュー・テスト・UXの仕上げは依然として人間が引き受ける必要があり、いわゆる「核心的な役割」をそのまま委ねられるラインには、 少なくともEditor GUIに関しては届いていない、というのが本実験での実感です。
ただし、これはあくまで本実験を行った時点(Claude Opus 4.6世代)での所感である点は強調しておきたいところです。
AIの進化スピードを踏まえると、Editor GUIのようにUnity固有の暗黙知が絡む領域であっても、扱える範囲は今後さらに広がっていくはずですし、すでに別の領域では、インターン的なサポートの段階を超えてAIに開発を委ねているプロジェクトも存在します。
そう考えると、本実験で見えてきた本質的な変化は、人間の役割が「コードを書く人」から「品質ゲートを通す人」へシフトしつつあるという点なのかもしれません。
「AIに全部任せる」場合でも、人間側のレビュー設計力が成果を左右します。
特にUnity開発においては、Unityの構造的に特殊な領域をどこまでAIに任せるかを意識的に設計する必要があると、強く感じました。
ここまで読んでいただきありがとうございました。
付録: 技術スタック
| 技術 | 用途 |
|---|---|
| Unity IMGUI | Editor GUI |
| EditorWindow | 各種ツールウィンドウ |
| EditorGUILayout | レイアウト管理 |
| PropertyDrawer | カスタムインスペクター |
| SerializedObject | Undoサポート |
| Reflection | フィールド値の動的取得 |
| YamlDotNet | テーブル定義の読み書き |
| NUnit | テスト |










