Unity でClaude Codeコーディングでシンプルなボードゲームを作成する
質問: ボードゲームを作りたい
全くUnityとかわからないんですが、ボードゲームのようなものを作りたいです。
Claude Codeのコーディングで、ボードゲームのようなものを作ってみます。
事前準備
Unity
こちらの記事 を参照して、Unityのプロジェクトを作成します。
Claude Code
こちらのの記事 を参照して、ClaudeデスクトップアプリケーションをインストールしてClaude Codeを利用できるようにします。
メモ
今回Claude Codeを利用していますが、おそらく、Codexでも同様の開発はできると思われます。使用モデルはOpus 4.8 です。
ボードづくり
はじめにフィールドとなるボードを作成します。今回は 100×100マスのボードとします。
Claude CodeでUnityプロジェクトのフォルダを作業フォルダとして次のプロンプトを実行します。
Prompt
ボードゲームライクなシミュレーションゲームを作る予定です。初めにベースとなるマップボードを作成したいです。
100x100マスのボードマップを実装してください。
この情報で不足があれば、逆質問してください。
次のような質問がありました。
質問
ボードの見た目・視点はどの形式にしますか?
→3D 平面グリッド
ボードの見た目・視点はどの形式にしますか?
→データ+表示の両方
各マス(セル)が持つべき情報は?(現時点の想定)
→座標 (x, y)
しばらくすると実装が完了します。
使い方メッセージ
Unityでの使い方
Unityエディタでプロジェクトを開き、スクリプトをコンパイルさせる
メニュー GameObject → Board Game → Board Grid (100x100) を選択(シーンに BoardGrid が追加されます)
Play を押すと、盤面が生成され、MainCameraが盤面全体を見下ろす角度へ自動配置されます
Unity Editorのウィンドウに移動し、[Game Object]メニューの[Board Game]の[Board Grid]の項目をクリックします。
実行します。中央にグリッドが表示できました。
グリッド選択
グリッドが表示されただけで何もできないので、クリックするとマスが選択できるようにします。
ついでにマスの位置にカメラが移動するようにします。
次のプロンプトを実行します。
Prompt
続いて、セルをクリックした際のフォーカスと、そのセルを中心にカメラを移動するロジックを実装してください。
現在はマップ全体を俯瞰するカメラなので、クリックした際に拡大して、そのセル周辺を表示できるようにしたいです。
しばらくすると実装が完了します。
使い方メッセージ
使い方
既に前回の BoardGrid をシーンに置いている場合は、その GameObject に BoardCameraController を追加してください(または一度削除して、メニューから再生成)。新規なら GameObject → Board Game → Board Grid (100x100) で両方付いた状態で生成されます。Play 後、マスをクリックすると寄り、右クリックで戻ります。
説明に従って、Board Gridを一旦削除し。再度Board Gridを配置します。
再度実行します。グリッドの全体が表示されました。
グリッド内のマスをマウスの左ボタンでクリックします。
クリックしたセルの境界線が黄色で選択され、選択したグリッドを中心に表示拡大されます。
別のグリッドをクリックすると、クリックしたグリッドが選択され、カメラが選択したセルが中心になるように移動します。
セルの選択と移動が実装できました。
ユニットの配置
駒(ユニット)を配置します。次のプロンプトを実行します。
Prompt
ユニットをマスに配置したいです。fbxデータを用意したのですが、どこに配置するのが良いですか?
以下のディレクトリが作成されます。今回はテクスチャやマテリアルは無いので、fbxファイルをModels/Units/に配置します。
メッセージ
Assets/
├── Art/
│ ├── Models/Units/ ← ★ ここに .fbx を入れる(生のモデルデータ)
│ ├── Materials/ ← マテリアル(色・質感)
│ └── Textures/ ← テクスチャ画像
└── Prefabs/Units/ ← ★ ゲームで配置する「ユニットPrefab」を作る
fbxモデルは以下を用意しました。Midjourneyでイラストを作成して、Tripo 3Dで変換して、3dsmaxでRetopologyしてポリゴンを整理したモデルです。
変換モデルなので、ポリゴンは汚いです。
ship_01
ship_02
続いて以下のプロンプトを実行します。
Prompt
fbxは静止モデルです。unit-01 を配置しました。このモデルを、グリッドの (10,10) の位置に表示したいです。
しばらくすると実装が完了します。
使い方メッセージ
1.シーンの BoardGrid オブジェクトを選択 → Add Component → Board Units
2.Inspector の Initial Units で要素を1つ追加し、
Prefab … Assets/Art/Models/Units/unit-01.fbx をドラッグ
X = 10, Y = 10
3.Play すると、Units 子オブジェクト配下に unit-01 (10,10) が セル(10,10)の中心 に生成されます
シーンのBoardGrid オブジェクトを選択して、Inspectorの[Board Units]の項目を開き、[初期配置 Initial Units]の項目の[+]ボタンをクリックします。項目が追加されますので、fbxファイルの項目をPreftabに設定し、X,Yのテキストボックスに配置したい座標を設定します。
(下図の画面では"Unit Id"が表示されていますが、これはもう少し後の実装後の画面キャプチャのため、表示されています。)
もう1項目追加し、ship_02 も画面に配置します。
ユニットの向きがおかしい
(向きを変える方法はこちらの記事で紹介します)
設定した、Prefabsのオブジェクトを[Board Units]の項目に設定します。
ユニットの位置微調整
ユニットが少し浮いている感を出したいので、次のプロンプトで調整します。
Prompt
グリッドよりもう少し上にユニットを表示したいです。
カメラのパース
Prompt
カメラのパースがきついのですが、もう少し遠近感を弱める設定にできますか?
ここまで作業して実行した画面が下図です。実行すると、グリッドの指定したX,Yの位置にユニットが表示されました。
ステータスウィンドウの実装
Prompt
セルを選択した際に、ユニットが存在している場合に、ステータスウィンドウを開くようにしたいです。
データ構造
今回のデータ構造は以下です。
画面のユニットの性能をunit.jsonで定義します。unit.json内にweaponsの項目があり、武器はweapon.jsonで定義することにします。
ユニットデータの作成
Prompt
ユニットデータのJSONファイルを作成して、ユニットの情報を記載してください。ユニット情報は以下です。
{
"id": "ship_01",
"team": "blue",
"class": "destroyer",
"hp": 500,
"max_hp": 500,
"armor": 30,
"speed": 8,
"weapons": ["pulse_laser", "missile"]
}
{
"id": "ship_02",
"team": "red",
"class": "destroyer",
"hp": 400,
"max_hp": 400,
"armor": 30,
"speed": 7,
"weapons": ["mega_beam", "missile"]
}
JSONファイルが、Assets\Resources\Units\units.json に作成され、情報が保存されます。
ウェポンデータの作成
Prompt
次はウェポン情報のJSONを作成して以下のデータを保存してください。
{
"id": "pulse_laser",
"type": "energy",
"damage": 35,
"range": 12,
"cooldown": 2,
"attenuation": 0.9,
}
{
"id": "mega_beam",
"type": "energy",
"damage": 45,
"range": 10,
"cooldown": 2,
"attenuation": 0.8,
}
{
"id": "missile",
"type": "real",
"damage": 20,
"range": 18,
"cooldown": 4,
"attenuation": 1,
}
JSONファイルが、Assets\Resources\Weapons\weapons.json に作成され、情報が保存されます。
JSON読み込み部分とユニットへの割り当て機構の作成
ユニット情報のJSONファイルが作成できましたので、これを読み込んで画面のユニットにステータスデータを
割り当てる部分を作成します。
Prompt
JSONを読み込んで、それぞれのユニットに属性データを割り当てられる仕組みを作成してください。
データのアサインはBoard Unitsで設定るのが現実的ですかね?
ステータスウィンドウにユニットデータを表示
Prompt
ステータスウィンドウにユニットデータを表示できるようにしてください。表示する内容の想定は以下です。
クラス: "Destroyer"
HP: 500/500
装甲: 30
移動: 7
武器
パルスレーザー
エネルギー兵器
攻撃力: 35
射程:12
クールダウン: 2
減衰率: 10%
ミサイル
エネルギー兵器
攻撃力: 20
射程:18
クールダウン: 4
減衰率: 0%
Prompt
ステータスウィンドウのデザインはいい感じにできますか?
実行して、ユニットをクリックします。ステータスウィンドウが表示されます。
コマンドの作成(移動)
Prompt
コマンドウィンドウを作成します。自分のユニットを選択した場合にコマンドウィンドウが表示されます。
コマンドウィンドウには、移動、攻撃の2つのボタンを配置してください。
今回は、移動のみを実装します。移動のボタンをクリックすると、ユニットの移動の数値の増すだけ進めますので、
移動可能範囲のセルの色を変えてください。移動範囲内のセルをクリックすると、ユニットはそのセルに向かって移動します。
ここまでを実装してください。なお、最初はBLUEのターンです。
ターンの実装
Prompt
一回移動したら相手のターンに変わるようにしたいです。
ターン終了時にカメラを引きます。
Prompt
・ターン終了時に初期の全体シーンに戻るようにしたいです。
・移動する際に、ユニットが移動している方向に向くようにして下さい。
カメラの微調整
Prompt
セルをクリックした際の画面ですが、もう少し引いて広い範囲が見えるようにしてほしいです。
コマンドの作成(攻撃)
Prompt
次に攻撃ボタンを実装します。攻撃ボタンをクリックすると、武器選択ウィンドウが表示され、武器を選択します。
武器が選択されると、射程範囲のセルが色が変わります。相手のユニットがいる場合に攻撃をします。
攻撃のダメージは以下の計算式とします。
実ダメージ = 基本ダメージ(damage) * (attenuation)*(距離) - (armor * 乱数(0.. 1))
ボードの縮小 (デバッグ用)
Prompt
デバッグのため、マスを16x16にしたいです。
ここは手動で、Board Grid (Script) の Width = 16 / Height = 16 に変更します。
ユニットの配置座標もblue (ship_01): (4, 4) red (ship_02): (11, 11) に変更します。
ダメージの表示
攻撃コマンドは実装できましたが、画面にダメージが表示されたほうが良いです。
Prompt
ダメージを画面に出したほうが良いですね。ダメージの数値が相手のユニットに浮かび上がるような処理を実装できますか?
ユニットの破壊
Prompt
HPが無くなると、ユニットがいなくなりますが、爆発するエフェクトは実装できますかね?何かリソースが必要ですか?
リソースは特に用意せず、Unity組み込みのパーティクルで実装されました。
実装メッセージ
リソースについて
不要です。Unity標準の ParticleSystem と組み込みスプライト(丸ドット UI/Skin/Knob.psd)を流用してコードだけで生成しています。
マテリアルもURPの Particles/Unlit を実行時生成。インポート作業はありません。
ゲームオーバーの実装
Prompt
良いですね。ユニットが全滅したら、BLUEの勝利です。OR REDの勝利です。のダイアログを出してゲームオーバーにします。ダイアログでOKを押すと初めの画面に戻ります。
ユニットステータスウィンドウのリッチ化
Prompt
ステータスウィンドウで、ユニットのFBXモデルを一番上に表示したいです。できれば回転させたいです。できますか?
Prompt
ステータスウィンドウのモデルをもう少し大きく表示したいです。枠のサイズはこのままで、カメラを寄るイメージです。できますか?
ステータスウィンドウに3Dのユニットが表示され回転するようになりました。
リリース版でのバグ取り
ここでリリース版を作成してプレイしてみましたが、うまく画面が表示されないです。以下のやり取りで不具合を修正します。
Prompt
リリース版の場合のみ、REDの移動の際に、移動可能セルが表示されないですが、原因わかりますか?
Prompt
Player.log を送付します。
C:\Users\<ユーザー名>\AppData\LocalLow\<会社名>\<プロダクト名>\Player.log の内容
Prompt
今度は、BLUEの移動セルも、攻撃の場合のセル着色も表示されなくなりました。
Prompt
REDダメージがボードの下に表示されているようで、数字が画面に出ません。
セルの着色もREDの移動がやはり表示されないです。リリース版のみで、Unityエディタではそのような動作にならないです。
Prompt
ダメージは手前に出るようになりましたが、REDの移動は相変わらず表示されないです。
C:\Users\<ユーザー名>\AppData\LocalLow\<会社名>\<プロダクト名>\Player.log の内容
カメラの微調整
Prompt
攻撃、移動、のコマンドを選択した際に、カメラを若干引いて、射程範囲内が入るようにしたいです。
ユニットの色変更
Prompt
REDならユニットを赤色、BLUEならユニットを青色にしたいのですが、可能ですか?
設計変更
ここでunit.json内にteamが記載されていることがちょっとまずいと考え、以下のプロンプトを実行します。
Prompt
unitのJSONにTeamが入っていますが、ここにはスペックの記述だけにして、所属は入れないほうが良いと考えています。将来的に複数ユニットになった場合に、同じユニット種でTeamが違うことがあると考えられるためです。この場合、どのように設計を変更するのが良いですか?単純に考えれば、BoardGridのX,YにTeamフィールドを追加する方針がありそうですが、もっと良い実装があればそれを採用したいです。
Teamの設定はBoardGridの[Initial Units]に設定することになりました。
BGM/SE
Prompt
BGMとSEを導入したいです。どこにファイルを配置すればよいですか?
フォルダが作成され、配置場所の案内があります。
実装メッセージ
Assets/Audio/
├─ BGM/ ← 戦闘BGM、タイトルBGM など
└─ SE/ ← 攻撃音、爆発音、UIクリック音 など
BGMはSunoで、SEはSuno Soundsで作成します。詳しくはこちらの記事 を参照してください。
BGMとSEのサウンドファイルを配置しました。
Prompt
BGMを入れてください。Assets/Audio/BGM/new-age.wav がサウンドファイルです。
BGMが設定できたら、SEを設定します。次のプロンプトを実行します。
Prompt
次のSEを設定します。
・ユニットをクリックしてステータスウィンドウが表示された際。select-beep
・ミサイルで攻撃した際。missile
・パルスレーザー、メガビームで攻撃した際 laser
・BLUEが勝利した際 victory-fanfare
・REDが勝利した場合 defeat-jingle
攻撃音はweapon,jsonに設定したほうが良いのであれば、書式の案内をお願いします。
抜けていたので、こちらも追加します。
Prompt
コマンドボタン(攻撃、移動)をクリックした場合も、select-beepを鳴らしてください。
Prompt
ユニットの破壊時のSEにexplodesを設定してください。
ユニットの移動音もあっても良いのですが、今回は無しにしました。
攻撃音はJSON側に設定できるよう、JSONファイルの書き換えもエージェント側で実施してもらえました。
{
"id": "pulse_laser",
"name": "パルスレーザー",
"type": "energy",
"damage": 35,
"range": 12,
"cooldown": 2,
"attenuation": 0.9,
"se": "laser"
},
ダメージをしっかり見せたい
ダメージの数字が出終わる前にターン終了でカメラを引いてしまう部分を修正します。
Prompt
攻撃のダメージが表示された瞬間にターンが切り替わりカメラが引かれてしまいます。
攻撃した後、相手のユニットにカメラを映して、ダメージの数字を見せてから、ターン切り替えでカメラを引く動作にしたいです。
ターンをわかりやすく
Prompt
どちらのターンかわかるように、画面の下部にRED,BLUEの帯を出したいです。
コマンドウィンドウに重なってしまうので、次のようにします。
Prompt
ターン表示の帯ですがコマンドウィンドウに重なるので、画面の上部に帯を移動してください。
タイトル画面
Prompt
タイトル画面を作成してください。"Mini Fleet Tactics" のタイトルと、スタートボタンを置いてください。
スタートボタンを押すと、現状のゲーム画面が始まる動作にしたいです。
Prompt
ゲームーオーバー時のボタンをクリックした際はタイトルに戻るようにしてください。
バグ修正
Prompt
リリース版で実行すると、ユニットの破壊ビジュアルが画面に表示されないように見えます。確認いただけますか。
クールダウンの実装
発射間隔を実装します。(もっと早めに実装しても良かったのですが。)
Prompt
武器のクールダウンを実装します。weaponスペックの "cooldown" のターンは武器を利用できなくしたいです。
"cooldown": 1 の場合は、毎ターン利用できますが、 "cooldown": 2 の場合は、次のターンは利用できなくしたいです。
武器選択のウィンドウで、グレーアウトにして選択できないようにします。
武器選択のウィンドウで、[あとnnターン]の表示を出したいです。
Webビルド用での不具合対処
Prompt
Web用ビルドだと日本語が表示されないです。何が原因でしょう?
フォントファイルが必要との回答があったので。
Prompt
フォントファイルの配置場所を教えてください。
実装メッセージ
Assets/Resources/Fonts/<フォント名>.ttf (.otf も可)
フォントの表示の改善
Prompt
ダメージのフォントサイズですが、文字を表示した後にカメラが寄るので、文字が大きくなってしまうようです。カメラが寄ってから、ダメージ文字を表示する動作にできますかね?
Prompt
ダメージの数値の文字ですが、まだ、ダメージの数値のジャギーが目立ちます。うまく対処できますか?
WorldSpace Canvas の dynamicPixelsPerUnit を上げる対処になりました。
エラーが発生したので対処してもらいます。
Prompt
Assets\Scripts\Board\DamagePopup.cs(37,20): error CS1061: 'Canvas' does not contain a definition for 'dynamicPixelsPerUnit' and no accessible extension method 'dynamicPixelsPerUnit' accepting a first argument of type 'Canvas' could be found (are you missing a using directive or an assembly reference?)
というエラーが出ています。
攻撃モーション
だいぶ無茶ぶりですが、以下のプロンプトを投げてみます。
Prompt
攻撃シーンですが、レーザーの線やミサイルっぽいエフェクトが出せますかね?
それっぽいモーションを実装してくれました。
SEタイミング調整
ちょっと爆発のSEのタイミングが遅いので調整します。
Prompt
爆発のSEですが、少し遅い印象です。爆発エフェクト開始のタイミングでSEを出したいです。
これは、オーディオファイル側に先頭無音部分があるためとのことです。Claude Codeがffmpegで先頭部分の無音をカットしてくれました。
実行画面
ここまでの実行画面です。
スタート画面です。
グリッドにユニットが配置されています。
クリックするとユニットが選択されてステータスウィンドウが表示されます。画面下部にはコマンドウィンドウも表示されます。
[移動]ボタンをクリックした状態です。移動できるセルが表示できています。
こちらは攻撃の場合
ダメージ表示です。
背景
背景を設定したいですが、どのように実装すればよいかわからないので聞いてみます。
Prompt
ボードの背景を設定したいのですが、どういう方法が良いでしょうか?
2Dの画像 →解像度が足りない気がする
3Dオブジェクト → 何を用意すればできますか?
プログラム描画 →可能でしょうか
その他の方法 → 何かありますか?
回答があり確認した結果、パノラマ・スカイボックスの実装になりました。
画像はプログラムで生成してプログラムで星を描画して解像度が足りるようにするとのこと。
Prompt
ボードを透過にして背景が見えるようにできますか?セルの線はそのまま表示したいです。
Prompt
背景の画像の解像度が足りない印象です。何とかなりますか?
星をテクスチャではなく「ジオメトリ(小さな板=ビルボード)」で描画する方式に変えました。
大きな惑星を置きたくなったので、fbxファイルを用意して配置してもらいます。
惑星のオブジェクトは下図です。
テクスチャは、GPT Image2で作成しました。惑星のイメージを画像で生成して、次のプロンプトを実行します。
Prompt
この画像の惑星の地表面をテクスチャマッピングするための地表の画像を作成してください。地表面のみの画像です。
n=4
アスペクト比を16:9にする
こちらの画像が生成できましたので、テクスチャとして利用します。
Prompt
Asset/art/models/background/star-01 このモデルをボードの下方に配置して惑星の周辺にいるようなシーンにしてください。
Prompt
次に、惑星が真下にあるため、もう少しずらして回転もさせたいです。どうやってずらせますか?
実装メッセージ
BackgroundProp の Offset From Board Center(盤面中心からのオフセット)を変えてください。
Prompt
実行中に Offset From Board Centerを変更してすぐ反映されるのですか?
実装メッセージ
現状は反映されません。 (中略)
調整しやすいよう、再生中の Offset / Scale / 傾き / 自転を毎フレーム反映するように変更します。
Prompt
Offset (X,Y,Z) = (10, -50, 30)
Scale = 75
Initial Euler(X,Y,Z)=(51, 54.3, 0)
でお願いします。
Prompt
star の外側の球ですが、大気の表現にしたいです。Unity側でパラメーターをセットするとよいとのことです。処理できますか?
実行画面
ここまでの実行画面です。
タイトル画面です。
背景が惑星になりました。
ステータスウィンドウなども表示できています。
問題なさそうです。
ちょっと惑星のわっかがしょぼいので、こちらは修正しようと思います。
デモ版
実際にプレイできます。とはいえ、ゲーム性がまだない、COMプレイヤーもないので、レーザーを打ち合うだけの運ゲームです。
まとめ
ゲームはプログラムだけでなく、アセット(画像、3Dモデル、BGM、SE)の準備があるため、かなり大変ですが、昨今のAIの技術進歩でものすごく効率よく準備できる状況になり、
比較的簡単にゲームが作れるようになった印象です。
ちなみに今回、コードはClaude Codeにコーディングさせており、人力では全く記述していません。
この後どうするのか
COMロジック
COMプレイヤーが欲しいので、COMプレイヤーを実装したいですが、現在の環境を鑑みるとLLMで実装したいです。
Gemma4を利用して、戦況とユニット配置とステータスを渡すと、次の行動を出すような仕組みを入れたいです。
LLMなので、現在の状況を踏まえて、セリフ(「ここで突撃よ!」など)も合わせて出すのもよさそうですが、実現可能か検証は必要そうです。
地形効果
現状はフラットなマップですが、隕石群のマスなどを用意して、防御効果が上がるなど戦略性が出る仕組み。
UI改善
HPバーがマップ上のユニットの上に見えたほうが良いです。
その後
COMロジックをllama.cpp (Gemma4 12B)に処理をするよう接続しました。またアクションロジックと同時に相手のキャラクターのセリフも出力する動作にしました。
セリフは Irodori-TTS サーバーでボイス化してゲーム内で再生する仕組みを実装しています。
サーバー側の設備が必要なため、実際にプレイできる環境の準備が難しいので、動画でデモが見れます。
VIDEO
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用