TechNeko
ノート一覧へ
LAB NOTE / 2026-09-21

Claude Code に Unity を直接操作させる:実スケール太陽系シミュレーター

Unity の入っていないマシンから、ブラウザで遊べる実スケールの太陽系まで。すべて AI エージェントがコマンドラインで作りました。技術方針、遭遇した問題、使ったモデルと消費トークンをそのまま記録します。

LIVE DEMO 全画面で開く

デモはブラウザ上で動きます。初回は約10MBの読み込みがあります。PC では マウス操作、スマートフォンでは 1本指で回転、2本指でズームできます。

これは何か

上のデモが完成品で、そのままブラウザで動きます。実スケールの太陽系:1 シーン単位 = 1 万 km、太陽の半径 69.6 単位、海王星の軌道 45 万単位、オールトの雲の外縁 15 億単位。36 天体(太陽、8 惑星、主要衛星 18、冥王星とカイパーベルトの準惑星 7、月)はすべて J2000 の軌道要素から位置を計算しており、日付も軌道傾斜角も離心率も実際の値です。

ドラッグで回転、ホイールでズーム、名前をクリックするとその天体まで飛びます。左上は選択中の天体の物理データ(NASA / JPL)、下のバーはズームと時間速度。スマートフォンでは 1 本指で回転、2 本指でズームです。

結論から

  • できる。 人がキーボードに触れずに、AI エージェント一体が Unity エディター内でコード記述・コンパイル・シーン構築・Play モード検証・スクリーンショット・git コミットの一連を完結できました。
  • 安くはない。 セッションは約 12 時間、モデル呼び出し 813 回、重み付け後の使用量は入力トークン約 7,700 万相当。
  • ボトルネックはモデルではなくツールチェーン。 モーダルダイアログ、バックグラウンドの間引き、サンドボックスの権限。人なら一目でわかるものが、コマンドラインのエージェントには見えません。

きっかけ

2026 年 9 月 16 日、Unity が AI エージェント向け公式プラグイン(31 スキル)と Unity CLI を公開しました。解説記事を読み、「Unity との連携は本当にどれほど簡単か」を自分の手で確かめたくなり、Unity 未導入の Windows マシンで Claude Code にゼロから始めさせました。

構成

項目内容
エージェントClaude Code(デスクトップ版)
モデルClaude Fable 5.1(claude-fable-5-1)、全編同一
エンジンUnity 6000.3.24f1、URP
接続Unity CLI 1.0.0-beta.10 + com.unity.pipeline 0.7.0
公式プラグインunity-agent-plugin 0.1.6-beta
人の役割要件提示、スクリーンショット確認、UAC のクリック、Hub でのライセンス認証

Unity CLI の仕組みは単純です。pipeline パッケージがエディター内で HTTP サーバーを立て、CLI がコマンドを送り、エディターがメインスレッドで実行して結果を返します。エージェントが最も使ったのは eval_file(任意の C# 実行)、recompileeditor_playcapture_game_view です。

技術方針

実スケール。 10 桁の幅があり、float では震えます。

フローティングオリジン。 位置はすべて double で計算し、注視中の天体を常にワールド原点に置き、他はその相対で配置。カメラは常に原点付近にあるので float の精度で足ります。注視先を切り替える際は、まずカメラの日心座標を求めてから新しい原点で表現し直すため、カメラが飛びません。

照明。 太陽から海王星までの光量比は 900:1。ポイントライトでは内惑星が白飛びするか外惑星が真っ黒になります。惑星と環には、太陽方向を使う減衰なしのランバート照明を自作 URP シェーダーで実装。太陽の位置は毎フレーム C# からグローバルシェーダー変数へ書き込みます。

軌道。 完全なケプラー要素:軌道長半径、離心率、傾斜角、昇交点経度、近日点経度、J2000 平均経度。ケプラー方程式はニュートン法で解き、衛星の軌道面は各惑星の赤道面に合わせて傾けます:土星 28°、天王星は 98° で横倒し、トリトンは 130° の逆行。各天体の黄道面からの高度角を読み出して NASA の傾斜角と突き合わせて検証しました。

カイパーベルトとオールトの雲。 第 1 版は 11 万個のポイントスプライトで、ローエンド GPU には重すぎました。ボリュームレンダリングに変更:境界球の裏面フラグメントで視線に沿って 40 ステップのレイマーチを行い、ガウス密度(ベルトは環状、雲は球殻)を積算。縁は自然にフェードします。粒感のために実際の点を 1.4 万個だけ残し、可視範囲外ではレンダラーごとオフにします。

テクスチャ。 惑星マップは Solar System Scope(CC BY 4.0)。2K の元画像はプロジェクト外に置き、プロジェクトには 1K 版のみ、インポート時に Crunch 圧縮。ビルド後のテクスチャ合計は 3 MB 未満。衛星と準惑星は手続き生成のマップです。

ブラウザ版。 Brotli 圧縮に JS 解凍フォールバックを付け、サーバーのヘッダー設定に依存しません。WebGL2 には逆 Z がないため、ニア/ファー面をカメラ距離に追従させ比率を 10⁷ 以内に抑えました。合計 12.9 MB。

タイムライン

段階内容
環境Unity CLI、Unity 6、pipeline パッケージ、ライセンス、公式プラグインの導入
スモークテストその場で跳ねるボール。記述 → コンパイル → Play → 計測 → 撮影 → コミットのループを確認
太陽系 v18 惑星 + 月、フローティングオリジン、自作シェーダー、手続き的テクスチャ、太陽エフェクト、環
修正同一平面の円軌道 → ケプラー軌道。冥王星、カイパーベルト、オールトの雲を追加
性能11 万スプライト → ボリューム霧 + 1.4 万点
コンテンツ衛星 18、準惑星 7、実写テクスチャ、地球の雲、3 言語 UI、スライダー、タッチ、天体データパネル
公開WebGL モジュール導入、ビルド、サイトへ埋め込み、ブラウザでのマウス入力修正

遭遇した問題と解決策

1. Store 版 Unity CLI がサンドボックスで動く。 winget で入る CLI は Microsoft Store の MSIX。昇格が必要なインストーラーを起動できず unity install は失敗、ライセンスクライアントの名前付きパイプにも接続不可。解決:CLI のキャッシュにあるダウンロード済みインストーラーを管理者権限でサイレント実行し、ライセンスは Hub で手動認証。後の WebGL モジュール導入でも同じ壁、同じ解法でした。

2. バックグラウンドではコマンドが処理されない。 ウィンドウのフォーカスが外れるとメインスレッドのコマンドが全て 30 秒でタイムアウト。ドキュメント通り set_autotick を実行しても Play モードはフレーム 1 で停止。エディターの Interaction Mode を No Throttling にしてようやく解消。

3. eval のメインスレッド 5 秒制限。 シーン構築は当初 8 秒以上かかり毎回タイムアウト。AssetDatabase.StartAssetEditing でアセット作成をまとめ(8 秒 → 1.5 秒)、長い処理は --detach でジョブ投入して job wait する形に変更。

4. モーダルダイアログが全てを止める。 保存時にエディターが「ファイルが外部で変更された」と判断し Reload / Ignore ダイアログを表示。全コマンドがタイムアウトし、ログには「timed out」しか出ません。エージェントにダイアログは見えない。解決:Win32 API でウィンドウを列挙してダイアログを見つけ BM_CLICK を送信。その後、保存順序を変えて再発を防止。

5. ゼロベクトル一つがフレーム全体を壊す。 散乱円盤トーラスの法線計算で、入力が小さすぎて Unity の Vector2.normalized がゼロを返却。シェーダー内で NaN となり、加算合成で NaN がフレーム全体に広がって黒地に白い楕円だけに。オブジェクトを一つずつオフにして撮影比較し特定。等価な乗算形に書き換え double で手動正規化して修正。

6. Play 中の再コンパイル。 ユーザーが Play 中にエージェントがスクリプトを再コンパイル。ドメインリロードで静的シングルトンが消え Awake は再実行されず、毎フレーム例外。遅延解決に変更。

7. ブラウザでマウスが効かない。 ブラウザでは Unity がタッチスクリーンデバイスを登録します。コードは押下中の指の数ではなくタッチスロット数(常に 0 より大きい)を見ていたため、毎フレーム タッチ分岐に入って早期リターン。エディターにタッチデバイスがないので気づけませんでした。

8. 見えないこと。 スクリーンショットがエージェント唯一の目です。CLI の往復は約 2 秒、1 回の検証で 5〜8 枚撮ります。既定のキャプチャはポストプロセスと UI を含まないカメラ出力で、--source screen が必要でした。

9. ブラウザに中国語・日本語のフォントがない。 デスクトップ版は CJK 表示にシステムフォントを借りますが、ブラウザには借りるフォントがなく、UI は英語固定にせざるを得ませんでした。Noto Sans CJK の完全版は 16 MB で同梱は不可能。最初は使用中の 368 文字を静的アトラスに焼き込みましたが、Unity の IMGUI は静的フォントだと最後に描いた文字列を全ラベルに表示してしまい、UI 全体が同じ一行になりました。最終的な解決:fontTools でその 368 文字だけにサブセット化(173 KB)し、動的フォントとして同梱。インポート規則スクリプトがローカライズ表から文字一覧を生成するので、UI 文言を足したらサブセットを再実行するだけです。

使用量

セッションは 2026-09-20 05:26〜17:19 UTC。ユーザー不在の空白時間を含みます。

項目
モデル呼び出し813 回
出力トークン283 万
キャッシュ読み取り3 億 2,700 万
キャッシュ書き込み510 万
未キャッシュ入力2.2 万
重み付け合計(読み ×0.1、書き ×2、出力 ×5)約 7,700 万

重み付け後の内訳:コードファイルの読み書き 35%、毎ターンのシステム指示とツール一覧の再読 26%、思考と返答 25%、シェル操作(Unity CLI、git、node)10%、その他(スクリーンショット送信、ブラウザ、Web 調査)4%。ツール呼び出し:Edit 153、PowerShell 123、Read 109、Write 41、WebFetch 15、ブラウザ 13、WebSearch 7。サブエージェントは未使用。

数字の読み方。 キャッシュ読み取りが大半を占めるのは、毎回の呼び出しがそれまでの会話全体を含むためで、キャッシュヒット後は 0.1 倍で課金されます。実際に「新しく生み出した」のは出力 283 万トークンで、この記事の約 1,500 倍。同じ範囲を熟練の Unity エンジニアがやれば 3〜5 営業日程度で、その相当部分が同じ落とし穴に費やされるでしょう。

うまくいったこと

  • 全ステップをスクリーンショットで検証。モデルの「できました」を信用しない。
  • 細かい git コミット。機能ごとに 1 コミットで、いつでも戻せる。
  • 定型操作をスクリプト化(コンパイル、ビルド、Play、撮影、エラー確認)。後半の反復が格段に速くなった。
  • 落とし穴をメモリに記録。同じ問題に二度時間を使わない。

うまくいかなかったこと

  • 最初のカイパーベルトは性能を考えず 11 万点を積み上げた。
  • タッチ分岐の条件が誤っていて、デスクトップでは見えず、公開後に発覚。
  • ユーザーの Play 中に数回再コンパイルし、エラーを見せてしまった。

次にやること

  • 大気散乱のグロー、環の影。
  • エージェント 2 体の協調:一方が計画と審査、もう一方が実装。
  • Unity CLI の補助スクリプトを再利用可能なスキルに整理。

地球 土星 カイパーベルト


本記事は Claude Fable 5.1 がこのセッションの完全な記録から執筆しました。使用量の数字はセッションログを直接集計したものです。

ノート一覧へ
TOP