AI にコードを書かせるだけなら簡単です。難しいのは、書いたものが本当に動くかを AI 自身に確かめさせるところでした。
Unity CLI を使うと、ここまで AI が自分で回せます。
手順 01
書き換えて再コンパイル
エラーの文言を読んで直す
手順 02
テストを流す
EditMode / PlayMode
手順 03
Play モードで動かす
状態を読み、画面を保存
手順 04
WebGL ビルド
サイズとエラーを受け取る
以下、実際に使ったコマンドと、そのとき返ってきた内容を残します。
この記事の前提
Unity 6.6(6000.6.0f1)+ Unity CLI 1.0.0-beta.9 + com.unity.pipeline 0.7.0-exp.1。Windows 11 で、Claude Code から実行しました。確認日は2026年9月16日です。
1. コードを書き換えたら、まず反映させる
外部のエディター(AI)でファイルを書いただけでは、Unity は気づかないことがあります。確実なのはこの順番でした。
unity command eval 'UnityEditor.AssetDatabase.Refresh(); return "ok";'
unity command recompile
unity command recompile_status
recompile_status は idle triggered compiling completed up_to_date のいずれかを返します。エラーがあるときは、こう返ってきます。
{"status":"completed","failed":true,"errors":["…error CS1736…"]}エラーの文言がそのまま返るので、AI はこれを読んで自分で直せます。 私の1本目では、テストの既定引数にプロパティを使っていて CS1736 が出ましたが、そのまま修正まで進みました。
⚠️ コンソールの表示は過去のものも残る
console コマンドは、すでに直したはずの古いエラーも返します。現在の状態は console_status の groundTruth(compilationFailed と consoleErrors)で判断してください。ここを間違えると、直したのに直っていないと誤解します。
2. テストを流す(PlayMode は非同期)
unity command run_tests --mode EditMode
EditMode はそのまま結果が返ります(私の環境では44件で数秒)。問題は PlayMode です。待たずに「0件」で返ってきます。
そのまま実行(0件で返る)
run_tests --mode PlayMode
→ {"Summary":{"Total":0,...}}非同期で実行して状態ファイルを読む
run_tests --mode PlayMode --async_tests true
→ {"result":"running",
"StatusPath":"Temp/pipeline_test_status.json"}あとは Temp/pipeline_test_status.json を、"status": "completed" になるまで読みます。整形済みの JSON なので、コロンのあとに空白が入ります。空白なしの文字列で待つと永遠に終わりません(実際にやりました)。
3. Play モードで実際に動かす
ここが一番おもしろいところです。AI はゲームを「遊べません」が、ゲームの関数を直接呼んで状態を読むことはできます。
unity command editor_play
# ゲームを開始してボールを発射する
unity command eval 'var b = UnityEngine.Object.FindFirstObjectByType<GameBootstrap>(); b.StartNewGame(); b.LaunchBall(); return "ok";'
# 3秒後に状態を読む
unity command eval 'var s = …; return $"score={s.Score} lives={s.Lives} bricks={s.RemainingBricks}";'
unity command editor_stop
実際に返ってきたのはこれです。
score=10 lives=2 bricks=39
発射から3秒、パドルを操作しなければ、ブロックを1個壊してボールが落ちる。仕様どおりに動いていることが、画面を見なくても分かりました。
画面も保存できる
unity command capture_game_view --save_path "Assets/Temp/title.png" --source screen
⚠️ 保存先の落とし穴が2つ
- プロジェクトの外は指定できません(400 で拒否されます)
- 相対パスは
Assets/からの相対です。気づかないうちにスクリーンショットがゲームのアセットとして取り込まれ、git の差分に出ます
さらに、--source を省略するとカメラからの撮影になり、画面に重ねた UI(スコアなど)が写りません。--source screen を付けると Game ビューそのものが撮れます。
4. ビルドまで回す
# まず検証だけ
unity command build --target WebGL --outputPath Builds/WebGL --dry_run true
→ {"status":"dry_run","valid":true,"validationErrors":[]}
# ビルド対象の切り替え(再インポートが走るので confirm が要る)
unity command switch_build_target --target WebGL --confirm true
unity command switch_build_target_status
# 本番
unity command build --target WebGL --outputPath Builds/WebGL --confirm true
unity command build_status
build は即座に {"status":"queued","buildId":…} を返し、build_status で追いかける形です。完了するとビルドレポートが JSON でまとめて返ります。
私の環境での実測はこうでした(初回)。
45秒
ビルド対象の切り替え
再コンパイル完了まで110秒
8:33
WebGL ビルド
初回
10.1MB
出力の合計
のちに 7.37MB まで削減
0
エラー
警告は1件(下)
サイズはその後、設定とパッケージの整理で 27.3% 減らしました(Webビルドの軽量化)。
警告の中身は「Pipeline の設定アセットが無いので、ビルドしたゲームでは Pipeline が無効になる」というものでした。Pipeline はエディター専用なので、これで正常です。
ビルドは待つ
初回の WebGL ビルドは長いです。比較で動かしていた別のエージェントは、6分の時点で「固まった」と判断してビルドのプロセスを殺してしまいました。AI に任せるなら、タイムアウトを長めに設定しておくか、build_status を素直に待たせてください。
5. ビルド後に git の差分が出る
WebGL ビルドのあと、URP の設定2ファイルと ProjectSettings.asset がエディターによって書き換えられていました。シェーダーの事前絞り込みの記録などです。ビルドのたびに出る差分なので、知らないと毎回驚きます。
まとめ:AI に渡す手順の型
- 1
ファイルを書く
- 2
反映させてコンパイル
AssetDatabase.Refresh()→recompile→recompile_status(エラーがあれば直す) - 3
EditMode テスト
run_tests --mode EditMode - 4
PlayMode テスト
run_tests --mode PlayMode --async_tests true→ 状態ファイルを読む - 5
Play モードで確かめる
editor_play→evalで操作と状態の確認 →capture_game_view --source screen→editor_stop - 6
ビルド
switch_build_target --confirm true→build --confirm true→build_status
この型を指示に入れておくと、AI は「書いて終わり」ではなく「動くまで」を自分で回せます。
ここで踏んだ問題をまとめて読むならWindowsの落とし穴14個、導入の手順はUnityをAIに触らせる5つの方法にあります。