🎮

uLoopMCP × Claude Code、AI駆動でUnityゲーム開発がどこまで自走できるか試してみた

に公開
2026/07/26

はじめに

「AIにUnityのゲームを作らせたい。でもUnity Editorの操作はちょっと厳しそうだな…」

そう思っていた時期が、自分にもありました。

AIにコードを生成させること自体は、もはや珍しくありません。ただ、Unityのゲーム開発ではコードを書くだけでは完結しないのが厄介なところです。Sceneへのオブジェクト配置、コンポーネントの設定、Play modeでの動作確認など、Unity Editor上のGUI操作が不可欠で、ここはプロンプトだけではどうにもなりません。

この「AIとUnity Editor間の壁」を取り払ってくれるのが、uLoopMCPというMCPサーバーです。

https://zenn.dev/m_hatayama/articles/91fb5be82c4e1b

MCPを介して、Claude CodeなどのAIエージェントが Unity Editorを直接操作 できるようになります。コンパイル、テスト実行、Scene構築、スクリーンショット取得まで、エディタ上の操作をAIに任せられるというもの。

MCPとは

MCP(Model Context Protocol)は、Anthropicが2024年11月に提唱した、AIツールと外部サービスをつなぐオープンな標準規格です。AIモデルが外部のツールやデータソースに安全にアクセスするための共通プロトコルとして策定されました。

https://www.anthropic.com/news/model-context-protocol

数時間ほど検証してみた結果、「かゆいところに手が届く」という印象で、AI駆動開発の可能性を強く実感しました。

この記事では、uLoopMCPのセットアップから、実際にブロック崩しゲームをプロンプトだけで構築するまでの流れを、体験ベースで紹介します。

uLoopMCPとは

uLoopMCPは、Unity EditorをAIが直接操作できるようにするMCPサーバーです。

https://github.com/hatayama/uLoopMCP

通常、AIにコードを生成させても「Unityに反映して動作確認する」部分は人間の手作業になります。uLoopMCPを使うと、このコード生成→コンパイル→Scene構築→動作確認のサイクルをAIが自律的に回せるようになります。

uLoopMCPはこのMCPを利用して、Claude Code、Cursor、GitHub CopilotなどのエージェントからUnity Editorの操作を可能にします。

利用可能なスキル

uLoopMCPが提供する主なスキル(コマンド)は以下の通りです。

スキル 機能
/uloop-compile コンパイル実行・エラー検出
/uloop-run-tests テスト実行
/uloop-get-logs ログ取得・失敗理由の明示
/uloop-get-hierarchy Scene上のHierarchy構造確認
/uloop-unity-search プロジェクト内Asset検索
/uloop-execute-dynamic-code C#コードの動的実行
/uloop-control-play-mode Play / Stop / Pause操作
/uloop-capture-window 任意のEditorWindowのキャプチャ

特に強力だと感じたのが /uloop-get-hierarchy と /uloop-capture-window です。AIがScene上のオブジェクト構造を把握しつつ、実際の画面を見て確認できるため、的外れな修正が激減します。

セットアップ

1. OpenUPMスコープの登録

Unity Editor の Edit > Project Settings > Package Manager から、OpenUPMのスコープを登録します。

Name: OpenUPM
URL: https://package.openupm.com
Scope(s): io.github.hatayama.uloopmcp

2. 必要ライブラリのインストール

Microsoft.CodeAnalysis.CSharp をインストールします。これは動的コード実行(/uloop-execute-dynamic-code)に必要なライブラリです。

Name: OpenUPM
URL: https://package.openupm.com
Scope(s): org.nuget

前述のScope(s)に org.nuget を追加してPackage Managerの「My Registries」からインストールします。

3. uLoopMCPパネルの起動

Unity Editorのメニューから uLoopMCP パネルを開きます。

4. エージェント選択と権限設定

パネル上で以下を設定します。

  • AIエージェントの選択:Claude Code、Cursor、GitHub Copilot等から選択
  • セキュリティレベル・権限設定:操作範囲を制御

今回は「Claude Code」を使用。セキュリティレベルは推奨設定の「Restricted」を選択。


https://github.com/hatayama/uLoopMCP?tab=readme-ov-file#14-execute-dynamic-code---dynamic-c-code-execution

5. サーバー起動

上記設定確認後、「Start Server」をクリックすればセットアップ完了です。

これでMCP経由でAIエージェントからUnity Editorを操作できる状態になります。

MCP経由でSceneの状態を確認

実際にMCP経由で現在のScene内容が把握できるか、Claude Code上で確認してみました。

まっさらなUnityプロジェクトを見てもらうと、初期状態のHierarchy構造の情報が返ってきます。Scene内のGameObjectや、それぞれにアタッチされているコンポーネントまで列挙され、Claudeがプロジェクトの現状を正確に把握できていることがわかります。


VSCode上でScene確認しているところ

続いて、本格的な実装に入る前に、簡単なGameObjectの作成を試してみました。MCP経由でUnity Editorを操作できるか、まずは軽い動作確認です。


簡単なGameObjectの作成を指示

Unity Editor上でSceneにCubeが作成されました。自然言語でプロンプトを投げるだけで、Claudeが適切なuLoopMCPのスキルを選択・呼び出してくれることが確認できました。


Scene上にCubeが作成されたことを確認

ブロック崩しゲームを作ってみた

セットアップと簡単な操作連携が確認できたので、実際にゲームを作ってみました。お題は数字付きのブロック崩しゲームです。


こんな感じのやつ

Plan modeで仕様を策定

まず、Claude CodeのPlan modeを使って、大まかなゲームの仕様を策定しました。

Plan mode自体はClaude Code標準の機能で、uLoopMCP(MCP)とは無関係です。実装に入る前の設計フェーズとして活用しています。

https://code.claude.com/docs/ja/common-workflows#plan-mode-を使用して安全なコード分析を行う

簡単なブロック崩しを作る方針をプロンプトで指示。Claude Codeが仕様の構成要素を整理してくれるので、人間はフィードバックと方向性の決定に集中できます。

以下は、Claude CodeがPlan modeで作成した2D版の初期仕様書です。この後の改修で内容は変わっていますが、最初の時点でここまで整理してくれるのは頼もしいですね。

Claude Codeが作成した初期仕様書(2D版)

Balls and Bricks ブロック崩しゲーム 実装計画

Context

Unity 6 LTS (URP) の白紙プロジェクトに数字付きブロック崩しゲームを最小実装する。
ゲームスクリプトは0件のため完全新規構築。Physics2D + TextMeshPro を活用した 2D ゲーム。

ゲームルール

  • 画面下部からボールを複数発射(マウスでエイム → クリックで発射)
  • ブロックに書かれた数字 = HP(その回数ヒットで消える)
  • 全ボール回収後、ブロックが 1 行下降 → 最上段に新行追加
  • ブロックが最下段ライン到達 → ゲームオーバー

スクリプト構成(7ファイル)

Assets/Scripts/
├── GameConstants.cs   // 全定数・パラメータ集中管理(staticクラス)
├── GameManager.cs     // ステートマシン・ターン進行制御
├── BallLauncher.cs    // エイム・連射・ボール回収管理
├── Ball.cs            // ボール単体の物理・コールバック
├── Block.cs           // ブロック単体のHP・表示・消滅
├── BlockManager.cs    // グリッド生成・行下降・ゲームオーバー判定
└── UIManager.cs       // ターン数・ボール数表示・GameOver画面

ゲーム状態遷移

[Idle] ──マウスDownで有効方向─► [Aiming] ──マウスUp─► [Launching]
  ▲                                                          │
  │                                                    全球着地
  │                                                          ▼
  │◄──────────NextTurn(行下降+新行追加)──────────[Collecting]
  │                  │
              ゲームオーバー判定
                     │
                     ▼
                [GameOver] ──Restart─► [Idle]
状態 処理
Idle ターン開始待ち、UI更新
Aiming マウス追跡・LineRendererでエイムライン表示
Launching Coroutineで LAUNCH_INTERVAL 間隔に 1球ずつ発射
Collecting 全ボールが BottomFloor Trigger に入ると回収、先頭着地 X に集合
NextTurn ブロック行下降アニメ → 最上段新行スポーン → GameOver確認
GameOver ゲームオーバーパネル表示

Physics2D 設定

設定 値
Physics2D.gravity Vector2.zero(重力なし)
PhysicsMaterial2D(Ball用) Bounciness=1.0, Friction=0.0
Ball Rigidbody2D Dynamic, GravityScale=0, CollisionDetection=Continuous
Block Collider BoxCollider2D のみ(Rigidbody2D不要)
BottomFloor BoxCollider2D, isTrigger=true

速度正規化(Ball.FixedUpdate):反発で速度がずれるため毎フレーム BALL_SPEED に固定。

_rb.linearVelocity = _rb.linearVelocity.normalized * GameConstants.BALL_SPEED;

Layer設定:Ball(8) / Block(9) / Wall(10) を追加し、Ball同士の衝突を無効化。


シーン構成

SampleScene
├── Main Camera           → Orthographic, Size=6.5 に変更
├── --- Game ---
│   ├── GameManager.cs
│   └── UIManager.cs
├── --- Field ---
│   ├── Walls/
│   │   ├── TopWall     BoxCollider2D  (0, +6.5) size(9, 0.2)  Wall Layer
│   │   ├── LeftWall    BoxCollider2D  (-4, 0)   size(0.2, 14) Wall Layer
│   │   ├── RightWall   BoxCollider2D  (+4, 0)   size(0.2, 14) Wall Layer
│   │   └── BottomFloor BoxCollider2D  (0, -6.3) size(9, 0.2)  isTrigger Wall Layer
│   ├── BallLauncher     BallLauncher.cs + LineRenderer
│   ├── BlockContainer   BlockManager.cs  ← Blockはここ以下に生成
│   └── GameOverLine     LineRenderer(赤い警戒ライン y=-5.0)
└── Canvas (ScreenSpace-Overlay)
    ├── TurnLabel    TextMeshProUGUI
    ├── BallLabel    TextMeshProUGUI
    └── GameOverPanel (初期非表示)
        ├── GameOverText  TextMeshProUGUI
        └── RestartButton Button

プレハブ

Assets/Prefabs/
├── BallPhysicsMaterial.asset  (Bounciness=1, Friction=0)
├── Ball.prefab   SpriteRenderer + Rigidbody2D + CircleCollider2D + Ball.cs
└── Block.prefab  SpriteRenderer + BoxCollider2D + TextMeshPro(World) + Block.cs

主要パラメータ(GameConstants)

定数 値 説明
GRID_COLS 7 横列数
CELL_SIZE 1.0f セルサイズ(m)
BALL_SPEED 12.0f ボール速度
BALL_RADIUS 0.18f ボール半径
LAUNCH_INTERVAL 0.08f 連射間隔(秒)
INITIAL_BALLS 1 初期ボール数
BLOCKS_PER_ROW 5 1行のブロック数(ランダム配置)
GAMEOVER_Y -5.0f ゲームオーバーライン Y座標
BLOCK_SHIFT_DURATION 0.3f 行下降アニメ時間

実装ステップ(実行順序)

Phase 1: スクリプト作成(Bash)

  1. Assets/Scripts/ ディレクトリ作成
  2. 7つの .cs ファイルを順番に Bash で書き込み
    • GameConstants → GameManager → Ball → BallLauncher → Block → BlockManager → UIManager

Phase 2: コンパイル確認

  1. compile ツールで ErrorCount=0 を確認
  2. エラーがあれば get-logs(Error) → Bash で修正 → compile を繰り返す

Phase 3: アセット・物理設定(execute-dynamic-code)

  1. PhysicsMaterial2D 作成(Bounciness=1, Friction=0)を Assets/Prefabs/ に保存
  2. Physics2D.gravity = Vector2.zero
  3. TagManager にレイヤー追加(Ball:8, Block:9, Wall:10)
  4. Layer Collision Matrix 設定(Ball同士の衝突をOFF)

Phase 4: プレハブ作成(execute-dynamic-code)

  1. Ball.prefab 作成・保存
  2. Block.prefab 作成・保存(TextMeshPro世界座標 HP表示付き)

Phase 5: シーン組み立て(execute-dynamic-code)

  1. Camera → Orthographic 変換
  2. Walls / BottomFloor GameObject 作成・配置
  3. BallLauncher GameObject 作成(LineRenderer付き)
  4. BlockContainer GameObject 作成
  5. GameOverLine(LineRenderer赤ライン)作成
  6. Canvas + UI要素構築
  7. GameOverPanel 構築(初期非表示)
  8. Inspector 参照配線(SerializedObject)
  9. シーン保存(EditorSceneManager.SaveScene)

Phase 6: 動作確認

  1. compile で最終エラーチェック
  2. control-play-mode(Play) で起動
  3. get-logs(Error) で実行時エラー確認
  4. capture-window(Game) でスクリーンショット確認
  5. control-play-mode(Stop)

検証ポイント

  • Play で起動後、ブロックが画面上部に 3 行表示される
  • マウスで上方向にエイムするとガイドラインが表示される
  • クリックでボールが発射され壁・ブロックで跳ね返る
  • ブロックのテキスト数字がヒットごとにデクリメントされる
  • HP=0 のブロックが消える
  • 全ボール回収後、ブロックが1行下降して新行が追加される
  • ブロックがゲームオーバーラインを越えるとGameOver画面が表示される
  • Restart ボタンで再スタートできる

2D版の実装

仕様が固まったら、Claude Codeに実装を指示します。

GameObjectの生成・Scene構築

実装計画に従い、Claude Codeがスクリプトを生成。

コンパイルエラーの確認、修正を進めてくれます。

そしてuLoopMCP経由でScene上にGameObjectを作成していきます。壁、ボール発射台、ブロックコンテナなど、仕様書に沿った構成要素が次々とSceneに配置されます。

GameObjectが生成されていく様子
GameObjectが生成されていく

自律的な開発サイクル

ここからが uLoopMCP の真骨頂です。Claude Codeが以下のサイクルを自律的に繰り返してくれました。

  1. スクリプトの生成・編集
  2. /uloop-compile でコンパイル → エラーがあれば自動修正
  3. /uloop-control-play-mode でPlay実行
  4. /uloop-capture-window でGameViewのスクリーンショット取得
  5. スクリーンショットを見て問題を判断 → コードを修正して再度コンパイル

この一連の流れが、人間の介入なしで進みます。AIが自分でPlayして、自分で画面を見て、自分で直すという、なかなかに未来感のあるワークフローです。


Claude CodeがPlay実行してスクショを確認している様子

最小限の動作状態を達成

最初の段階で「最小限の機能が動く状態」が出来上がりました。

ボールの発射、壁での反射、ブロックへの衝突判定など、基本的なゲームループが動作します。


最小動作状態のゲーム画面

機能追加・改善

ここからは、プロンプトで追加の指示を出しながら改善を重ねていきます。「ブロックにHP表示を入れて」「ゲームオーバー画面を追加して」のように、自然言語で機能を足していけます。

改善を繰り返すことで、だいぶそれっぽい形になりました。

3D版への拡張

2D版の実装がある程度固まった後、3D版も同様にプロンプトで作成してみました。

以下は、Claude Codeが作成した3D版の仕様書です。2D版と同様、この後の改修で内容は変わっています。

Claude Codeが作成した仕様書(3D版)

Balls and Bricks 3D ブロック崩しゲーム 実装計画

Context

Unity 6 LTS (URP) プロジェクトに数字付きブロック崩しゲームの 3D 版を実装する。
2D 版をベースに XZ 平面上で動作する 3D バージョンへ拡張。Rigidbody + TextMeshPro を活用した 3D ゲーム。

ゲームルール

  • 手前側からボールを複数発射(マウスでエイム → リリースで発射)
  • ブロック天面に書かれた数字 = HP(その回数ヒットで消える)
  • 全ボール回収後、ブロックが 1 行手前に下降 → 最奥に新行追加
  • ブロックが最手前ライン到達 → ゲームオーバー

スクリプト構成(9ファイル)

Assets/Scripts/Game3D/
├── GameConstants3D.cs   // 全定数・パラメータ集中管理(staticクラス)
├── GameManager3D.cs     // ステートマシン・ターン進行制御
├── BallLauncher3D.cs    // エイム・連射・ボール回収管理
├── Ball3D.cs            // ボール単体の物理・コールバック
├── Block3D.cs           // ブロック単体のHP・表示・消滅
├── BlockManager3D.cs    // グリッド生成・行下降・ゲームオーバー判定
├── BallBonus3D.cs       // ボーナスボール(触れるとボール+1)
├── FloatingText3D.cs    // ダメージ数値やボーナス "+1" のフロートテキスト
└── UIManager3D.cs       // ターン数・ボール数表示・GameOver画面

ゲーム状態遷移

[Idle] ──マウスDragでZ>0.15─► [Aiming] ──マウスUp─► [Launching]
  ▲                                                        │
  │                                                  全球着地
  │                                                        ▼
  │◄──────────NextTurn(行下降+新行追加)──────────[Collecting]
  │                  │
              ゲームオーバー判定
                     │
                     ▼
                [GameOver] ──Restart─► [Idle]
状態 処理
Idle ターン開始待ち、UI更新
Aiming マウス追跡・LineRendererでエイムライン表示(黄→白グラデーション)
Launching Coroutineで LAUNCH_INTERVAL 間隔に 1球ずつ発射
Collecting 全ボールが ReturnFloor3D Trigger に入ると回収、先頭着地 X に集合
NextTurn ブロック行下降アニメ → 最奥新行スポーン → GameOver確認
GameOver ゲームオーバーパネル表示(フェードイン+スケールアニメ)

Physics 設定

設定 値
Rigidbody(Ball用) useGravity=false, FreezePositionY+FreezeRotation, ContinuousDetection, Interpolate
PhysicsMaterial(BallPhysics3D) 壁・床・ブロック共通のバウンス設定
Block Collider BoxCollider のみ(Rigidbody不要)
ReturnFloor3D BoxCollider, isTrigger=true

速度正規化(Ball3D.FixedUpdate):反発で速度がずれるため毎フレーム BALL_SPEED に固定。

vel = _rb.linearVelocity;
vel.y = 0f;
// Z成分が小さすぎる場合は最小値にクランプ(水平往復防止)
if (Mathf.Abs(vel.z) < GameConstants3D.BALL_MIN_VEL_Z)
    vel.z = GameConstants3D.BALL_MIN_VEL_Z * Mathf.Sign(vel.z == 0f ? 1f : vel.z);
_rb.linearVelocity = vel.normalized * GameConstants3D.BALL_SPEED;

Layer設定:Ball(11) を追加し、Ball同士の衝突を無効化。


シーン構成

BallBricks3D
├── Main Camera           → Perspective, FOV=60, Position(0, 12, -8), Pitch≈27.5°
├── Directional Light     → Rotation(40.8°, -23.5°, 6.3°), Intensity=1.2
├── --- Game ---
│   ├── GameManager3D.cs
│   └── UIManager3D.cs
├── --- Field ---
│   ├── Floor             Plane mesh, Position(0, 0, 0.5), Scale(0.75, 1, 1.2)
│   ├── BackWall          BoxCollider  Position(0, 0.5, 5.6) Size(7.4, 1, 0.2)
│   ├── LeftWall          BoxCollider  X=-3.5
│   ├── RightWall         BoxCollider  X=+3.5
│   ├── LeftWall_Visual   描画用壁メッシュ
│   ├── RightWall_Visual  描画用壁メッシュ
│   ├── ReturnFloor3D     BoxCollider  Position(0, 0.5, -5.5) Size(7, 0.5, 0.5) isTrigger
│   ├── BallLauncher3D    BallLauncher3D.cs + LineRenderer
│   └── BlockContainer3D  BlockManager3D.cs ← Blockはここ以下に生成
└── Canvas (ScreenSpace-Overlay)
    ├── TurnLabel    TextMeshProUGUI  "TURN X"
    ├── BallLabel    TextMeshProUGUI  "x N"
    ├── RestartButton Button
    └── GameOverPanel (初期非表示)
        ├── GameOverText    TextMeshProUGUI
        └── FinalTurnLabel  TextMeshProUGUI  "SURVIVED N TURNS!"

プレハブ

Assets/Prefabs3D/
├── BallPhysics3D.asset    (PhysicMaterial)
├── Ball3D.prefab          Sphere(0.36) + Rigidbody + SphereCollider + Ball3D.cs
├── Block3D.prefab         Cube(0.9) + BoxCollider + Block3D.cs + 子:HPLabel(TMP, 天面回転90°)
└── BallBonus3D.prefab     Sphere(0.5) + SphereCollider(isTrigger) + BallBonus3D.cs  金色

主要パラメータ(GameConstants3D)

定数 値 説明
GRID_COLS 7 横列数
CELL_SIZE 1.0f セルサイズ(m)
GRID_ORIGIN_X -3.5f col 0 の左端 X
GRID_TOP_Z 4.5f row 0 の中心 Z(最奥)
INITIAL_ROWS 5 初期行数
BLOCKS_PER_ROW 5 1行の最大ブロック数
GAMEOVER_Z -3.5f ゲームオーバーライン Z座標
BLOCK_SHIFT_DUR 0.3f 行下降アニメ時間(秒)
BALL_HEIGHT 0.5f ボールの Y 座標(地面から半径分)
BALL_SPEED 12.0f ボール速度
BALL_MIN_VEL_Z 0.2f Z速度の最小絶対値(水平往復防止)
LAUNCH_INTERVAL 0.08f 連射間隔(秒)
INITIAL_BALLS 1 初期ボール数
LAUNCH_Z -4.5f ランチャーの Z 位置
AIM_LINE_LENGTH 5.0f エイムライン長さ
WALL_X 3.5f 左右壁の
BACK_WALL_Z 5.5f 奥壁の Z

ブロック配置・難易度スケーリング

初期配置(Initialize)

row HP 範囲 ブロック数 ボーナス確率
0 [1, 1] 3 20%
1 [1, 2] 3 20%
2 [1, 3] 3 20%
3 [1, 4] 3 20%
4 [1, 5] 3 20%

ターンごとの新行スポーン(SpawnNewRow)

minHp      = max(1, turn - 1)
maxHp      = turn + 1
blockCount = min(BLOCKS_PER_ROW, max(3, 2 + turn / 2))
bonusChance = min(1.0, 0.2 + turn × 0.05)
ターン HP 範囲 ブロック数 ボーナス確率
1 [1, 2] 3 25%
4 [3, 5] 4 40%
6 [5, 7] 5 50%
10 [9, 11] 5 70%
16+ [15, 17] 5 100%

検証ポイント

  • Play で起動後、ブロックが XZ 平面上に 5 行表示される
  • マウスで奥方向にエイムするとガイドラインが表示される
  • リリースでボールが発射され壁・ブロックで跳ね返る
  • ブロック天面の数字がヒットごとにデクリメントされる
  • HP=0 のブロックが消滅エフェクトとともに消える
  • ボーナスボール(金色)に触れるとボール数+1、"+1" テキストが浮かぶ
  • 全ボール回収後、ブロックが1行手前に下降して新行が追加される
  • ブロックが Z=-3.5 以下に到達するとGameOver画面が表示される
  • Restart ボタンまたはクリックで再スタートできる
  • ターンが進むにつれブロック数(3→5)とHP範囲が増加する
  • ボーナス出現率がターン経過で上昇する(20%→100%)

カジュアルゲームを企画する際、2Dでいくか、3Dでいくかの検討を行うことはよくあります。プロトタイプの段階で両方のバージョンを用意できると、見た目の印象やプレイ感の違いを比較しやすく、方向性の判断がしやすくなります。

雑なプロンプトでも、一発目で出てきたものは土台がほぼできていました。

2D → 3D化に際し、ブロックが壁にめり込んでいたり、ボールが正しく反射されなかったりしていたので、そのあたりは自分で動作確認しつつ修正を投げました。

従来は両方作るだけでもそれなりの工数がかかりましたが、uLoopMCPならプロンプトで指示するだけなので、このあたりの調整・検証コストが大幅に下がります。

ここで実感したのが、/uloop-get-hierarchy と /uloop-capture-window の強さです。

AIがScene内のHierarchy構造やオブジェクトの状態を正確に把握できるため、3D化に伴う座標やスケールの調整も、的確な修正を出してくれます。

やや苦戦する箇所もありましたが、動作確認&修正の繰り返しを自律的に行ってくれるため、手動での確認作業時間が減りました。

しばらく様子を見ていると、いい感じに3D版のゲームが仕上がりました。

基本的な動作もバッチリです。

テストの自動作成・実行

プロジェクト内のファイルを見たところ、ゲームの実装だけでなく、テストの自動作成・実行も実施してくれていました。

/uloop-run-tests でテスト結果を取得し、失敗したケースはAIが自動でコードを修正。テスト駆動的なワークフローがプロンプトだけで回るのは新鮮な体験でした。

検証結果

数時間の検証で、以下の成果物がプロンプトのみで構築できました。

  • 2D/3D 合計18スクリプトを生成
  • Sceneオブジェクト全体をプロンプトから構築
  • スクリプト生成 → コンパイル → Scene構築 → 動作確認の自動化サイクルが確立

バグ修正、バランス調整、UI修正も自然言語の指示で完結します。「ボールの速度をもう少し上げて」「ブロックの色を段階ごとに変えて」のような指示が、そのままゲームに反映される体験は、かなりインパクトがありました。

所感

よかった点

  • フィードバックと意思決定に集中できる:コード実装やデバッグの手作業から解放され、ゲームの方向性やバランスの判断に集中できる
  • Hierarchy・Sceneの状態を把握できるのが強い:AIが「今のSceneがどうなっているか」を理解した上で修正してくれるため、やり取りの精度が高い
  • 自然言語でイテレーションが回る:「ここをこう変えて」→ 修正 → 確認 → 「次はこれを」のサイクルが非常にスムーズ
  • 複数Unity並列接続にも対応:複数プロジェクトを同時に扱える柔軟性もある
  • 動的コード実行:/uloop-execute-dynamic-code により、AIが書いたコードをコンパイル不要で動的に実行できる。Unity 6.2以降のAI Assistantと同様の機能

https://x.com/m_hatayama/status/1963076235279700260

注意点・課題

  • セキュリティレベルの設定は、プロジェクトの性質に応じて適切に管理する必要がある
  • PlayModeテスト実行中はDomain Reloadが強制的にOFFになる(テスト完了後に復元される)。この間、static変数がリセットされない点に注意(詳細)
  • 既存プロジェクト、大規模プロジェクトでの実用性については、さらなる検証が必要

まとめ

uLoopMCPは、AIエージェントにUnity Editorの操作権限を渡すことで、プロンプトだけでゲーム開発の一連のサイクルを回せるMCPサーバーです。

数時間の検証でしたが、Scene内で使用するprefab類がプロンプトのみで構築できたのは素直に驚きました。従来の「AIにコードを生成させて、手動でUnityに反映して、動作確認して…」というフローと比べると、開発体験が根本的に変わります。

もちろん、本格的なゲーム開発にそのまま適用するには課題もありますが、プロトタイピングやアイデア検証のフェーズでは十分に実用的です。人間はゲームデザインや体験設計に集中し、実装の手作業はAIに任せるという開発スタイルが、現実的な選択肢になりつつあると感じました。

Unity × AI駆動開発に興味がある方は、ぜひ試してみてください。

https://zenn.dev/unsoluble_sugar/articles/bf666326e854d1

また、Unity CLI Loopを使ってチュートリアルのE2Eテスト自動化基盤を構築した検証記事も書きました。AIエージェントでゲーム内操作まで自動化するイメージが気になる方は、こちらも合わせてご覧ください。

https://zenn.dev/unsoluble_sugar/articles/2a1f9e08ac9980

参考

https://github.com/hatayama/uLoopMCP

https://zenn.dev/m_hatayama/articles/91fb5be82c4e1b

https://zenn.dev/tkada/articles/00b32b7f41a2ed

Discussion