AIゲーム開発研究室
Unity AI Agentでどんぐり取得数とUIを実装する
AIゲーム開発研究室
ゲーム開発ドキュメント
Unity AI Agentでどんぐり取得数とUIを実装する
前回は、画像生成AIによって制作したポンの5枚のアクション素材をUnityへ組み込み、左右移動と上下キャッチアクションを実装しました。
その過程では、アニメーションのループでキャラクターが一瞬消える問題や、キャラクターと前景との描画順の問題も発生しました。
それらを人間が実際のゲーム画面から発見し、Unity AI Agentへ修正を指示することで解決しました。
今回は、ゲームそのものをもう一段階進めます。
次に実装するのは、
どんぐりをキャッチした数を記録し、ゲーム画面に表示する機能
です。
まず既存の実装を調査する
今回、いきなりUnity AI Agentへ新しい機能を実装させることはしませんでした。
「森のどんぐり大作戦」では、すでにパンタが落下するどんぐりを籠でキャッチする仕組みを以前の実験で制作しています。
しかし、どこまで実装されているのかを人間が記憶だけで判断して、新しい処理を追加すると、すでに存在する機能を重複して作ってしまう可能性があります。
そこで最初にUnity AI Agentへ、
まだ何も変更せず、現在のプロジェクトを調査する
よう日本語で指示しました。
調査対象は、
Panta
BasketCatchArea
Acorn
AcornSpawner
関連するCollider、Rigidbody2D、スクリプト
既存UI
です。
Unity AI Agentが既存システムを調査する
Unity AI Agentによる調査の結果、パンタにはすでに、
BasketCatchArea
という籠の当たり判定用GameObjectが存在していることが確認されました。
そこには、
BoxCollider2D
と、
BasketCatchArea.cs
が設定されています。
さらに、パンタの移動方向やアニメーション状態に応じて、籠のコライダー位置を自動的に調整する処理も実装されていました。
落下するどんぐりには、
Rigidbody2D
CircleCollider2D
FallingAcorn.cs
が設定されています。
そして最も重要なのは、以前実装したキャッチ処理が、そのまま残っていたことです。
パンタの籠にどんぐりが入ると、
接触を検知する
↓
キャッチ成功と判断する
↓
どんぐりをDestroyする
ところまでは、すでに完成していました。
つまり今回、恐れていた当たり判定をもう一度作る必要はありませんでした。
既存システムを作り直さない
今回のUnity AI Agentの調査では、
既存のキャッチ判定、籠の追従、どんぐりの消去処理は作り直す必要がない
という判断が示されました。
これは重要です。
AI Agentを利用すると、つい、
「これを実装してください」
と新しい機能をそのまま作らせたくなります。
しかしゲーム開発が進むほど、プロジェクト内部にはすでに多くのGameObject、Component、Script、設定が存在しています。
そこで新しい処理を追加する前に、
AI Agent自身に現在のプロジェクトを調査させる
という工程を入れることで、既存の実装を利用しながら必要な部分だけを追加できます。
今回新たに必要だったのは、
キャッチ成功 → 取得数を1加算 → UIへ表示
という処理だけでした。
ScoreManagerを追加する
Unity AI Agentへ、既存のキャッチシステムを維持したまま取得数とUIだけを追加するよう指示しました。
その結果、新しく、
ScoreManager
が作成されました。
ScoreManagerは、現在のどんぐり取得数を保持・管理します。
取得数は、
CurrentScore
として外部から参照することができます。
また、
AddScore
によって取得数を加算し、
ResetScore
によって0へ戻すことができます。
さらに取得数が変化すると、
OnScoreChanged
というイベントを発生させる構造になりました。
この仕組みによって、今後、
一定数取得したらゲームクリア
といった処理からも、現在のどんぐり数を利用できるようになります。
どんぐり取得数をUIへ表示する
続いて、画面に取得数を表示するため、
ScoreCanvas
ScoreText
EventSystem
が追加されました。
ゲーム画面には、
どんぐり:0
と表示されます。
パンタがどんぐりをキャッチすると、
どんぐり:1
どんぐり:2
どんぐり:3
というように数字が増えていく予定です。
今回はUIデザインそのものを完成させることが目的ではありません。
そのため、どんぐりアイコンなどの装飾は追加せず、まず数字が正常に機能することを優先しました。
Unity AI Agentは「実装完了」と報告した
Unity AI Agentからは、
どんぐりキャッチ時の取得数カウントおよび画面UIへの表示実装が完了した
という報告がありました。
内部では、
BasketCatchArea
↓
ScoreManager
↓
OnScoreChanged
↓
ScoreUI
↓
ScoreText
という流れが構築されていました。
報告だけを見ると、問題なく完成したように見えます。
しかし、実際にゲームをPlayしてみると問題がありました。
どんぐりを取っても「0」のまま
パンタを操作し、落下してくるどんぐりをキャッチしました。
どんぐりは正常に消えています。
つまり、
当たり判定そのものは動いている
と考えられます。
ところが画面左上の表示は、
どんぐり:0
のままです。
何個キャッチしても数字が増えません。
Unity AI Agentは実装完了と報告していましたが、実際のゲームとしては正常に動作していませんでした。
すぐに修正させない
ここで今回は、
「直してください」
とは指示しませんでした。
まず、
プロジェクトを変更せず、原因だけを調査する
ようUnity AI Agentへ指示しました。
確認させたのは、
キャッチ時にCurrentScoreが増えているのか
OnScoreChangedが発火しているのか
ScoreUIがイベントを受信しているのか
ScoreTextへの参照は正常なのか
Consoleにエラーが発生していないのか
といった点です。
つまり、AIにいきなり修正を任せるのではなく、
まず何が正常で、どこから異常なのかを特定させる
ことにしました。
Unity AI Agentが原因を特定する
調査の結果、非常に明確なことが分かりました。
まず、
キャッチ時のCurrentScoreは正常に増加していました。
0から1、2、3と内部では正しく加算されています。
OnScoreChangedも正常に発火していました。
ScoreTextへの参照も正常でした。
Consoleにもエラーはありません。
問題があったのは、
ScoreUIがOnScoreChangedイベントを受信していない
ことでした。
原因は初期化順序だった
Unity AI Agentの調査によると、原因はUnityの初期化順序とイベント購読のタイミングにありました。
ScoreUIのOnEnableが実行された時点では、まだScoreManagerの初期化が完了していませんでした。
そのため、
ScoreManager.Instanceがnull
となり、ScoreUIによるイベント購読が行われませんでした。
その後ScoreManagerが正常に動き始めても、ScoreUIはイベントを購読していないため、取得数の変更通知を受け取ることができません。
結果として、
ゲーム内部では1、2、3……と増えている
にもかかわらず、
画面には「どんぐり:0」と表示され続ける
という状態になっていました。
エラーが出ない不具合
今回の問題でもう一つ興味深かったのは、
Consoleにエラーが出ていなかった
ことです。
プログラムそのものが停止しているわけではありません。
ScoreManagerは正常に動作しています。
イベントも正常に発火しています。
しかし、そのイベントを受け取る側が存在していませんでした。
そのためUnity上ではエラーとして検出されず、
ゲームを実際にPlayして画面を見なければ分からない不具合
になっていました。
原因を特定してから修正する
原因が特定されたところで、初めてUnity AI Agentへ修正を指示しました。
今回変更したのは、
ScoreUI.cs
だけです。
初期化順序に左右されないよう、ScoreManagerへのイベント購読処理を改善しました。
さらに、
isSubscribed
という購読状態を管理する仕組みを追加し、イベントが二重に登録されないようにしました。
購読解除についても処理されています。
つまり、
問題の原因を特定する
↓
原因となった部分だけを修正する
という方法を取りました。
10個連続でキャッチして確認する
修正後、再びゲームをPlayしました。
パンタを操作し、落下するどんぐりをキャッチします。
今度は、
どんぐり:0
から、
1、2、3……
と正常に数字が増えていきました。
今回は動いたところで確認を終了するのではなく、10個までどんぐりをキャッチして動作を確認しました。
結果、
10個まで正常にカウントされ、UIにも正しく表示されました。
これによって、
キャッチ判定
↓
どんぐり消去
↓
取得数加算
↓
UI更新
という一連の処理が正常に動作することを確認できました。
「実装完了」は「ゲーム完成」ではない
今回の実験は、AI Agentを利用したゲーム開発において重要なことを示しました。
Unity AI Agentは最初、
実装が完了した
と報告しました。
コード上でも、それぞれの処理は存在していました。
しかし実際にPlayすると、UIは更新されませんでした。
つまり、
AI Agentが実装を完了したことと、その機能がゲーム上で正しく動作することは同じではありません。
人間による実機確認が必要です。
AIにすぐ修正させないという方法
今回もう一つ見えてきたのは、不具合発生時のAI Agentへの指示方法です。
問題が発生したからといって、すぐ、
「直してください」
と指示する必要はありません。
今回は、
「まだ変更しないでください。原因だけを調査してください」
と指示しました。
その結果、Unity AI Agentは、
当たり判定は正常
ScoreManagerも正常
スコア加算も正常
イベント発火も正常
ScoreUIのイベント購読だけが異常
というところまで問題を切り分けました。
その後、原因となったScoreUIだけを修正しました。
この方法であれば、正常に動いている部分までAIが変更してしまう危険を減らすことができます。
AI Agentを使ったデバッグの流れ
今回の実験から、AI Agentを使ったゲーム実装とデバッグについて、一つの流れが見えてきました。
AI Agentが既存プロジェクトを調査する
↓
必要な部分だけを実装する
↓
AI Agentが実装完了を報告する
↓
人間が実際にPlayする
↓
人間が問題を発見する
↓
AI Agentへ「変更せず原因を調査する」よう指示する
↓
AI Agentが問題を切り分ける
↓
人間が調査結果を確認する
↓
AI Agentへ最小限の修正を指示する
↓
人間が再びPlayする
↓
正常動作を確認する
これは、AIにすべてを任せる開発方法ではありません。
同時に、人間がすべてのコードを書き、すべての原因を調査する従来の方法とも異なります。
人間とAI Agentが役割を分担しながらデバッグする方法
と言えるかもしれません。
Unity AIのクレジット消費を記録する
今回から、Unity AI Agentの実用性を検証するため、クレジット消費についても記録することにしました。
前回の作業終了時点では、
739 / 1,000クレジット
が残っていました。
今回、
既存プロジェクトの調査
ScoreManagerとUIの実装
UIが更新されない原因の調査
ScoreUIの修正
まで行った後、Unity Dashboardを確認しました。
残りは、
652 / 1,000クレジット
でした。
したがって今回の作業前後の差は、
87クレジット
です。
ただし、この87という数値を個々の処理へ単純に割り振ることはできません。
今回の一連の作業による実際の残量変化として記録しておきます。
AIにできるかだけではなく、AIに任せる価値があるか
クレジット消費を記録する理由は、単に使用量を節約するためだけではありません。
今後、コンタ、リン、ミミとキャラクターが増えていきます。
すでに完成している仕組みを、新しいキャラクターへ適用するたびにUnity AI Agentへすべて作業させる方がよいのか。
それとも、単純なCollider設定や既存設定の複製については人間が手動で行った方がよいのか。
これは実際の作業量とAIクレジット消費の両方を見ながら判断できます。
AI時代のゲーム開発では、
「AIにできるか」
だけではなく、
「その仕事をAIに任せることが合理的なのか」
という判断も必要になります。
今回の実験から
今回完成した機能だけを見れば、
どんぐりを取ると数字が1増える
という非常に小さなものです。
しかし、その実装過程から多くのことが分かりました。
既存プロジェクトをAI Agent自身に調査させる。
すでに正常な部分は作り直さない。
必要な機能だけを追加する。
AIの「実装完了」という報告をそのまま完成とは考えない。
人間が実際にゲームをPlayする。
不具合があれば、すぐ修正させるのではなく、まず原因だけをAIに調査させる。
原因が特定されたら、その部分だけを修正する。
そして再び人間がゲームをPlayして確認する。
今回も、
実装 → 検証 → 発見 → 調査 → 修正 → 再検証
という循環が発生しました。
そしてこの循環の中では、人間とAIのどちらか一方だけが開発を進めているわけではありません。
AI Agentがプロジェクトを調査し、コードを書き、原因を分析する。
人間がゲームを操作し、結果を見て、異常を発見し、AIへ次の指示を与える。
AIが実装し、人間が現実のゲームとして評価し、その結果を再びAIへ戻す。
この反復によって、ゲームは少しずつ完成へ近づいていきます。
次は、この取得数をゲームの進行条件として利用します。
一定数のどんぐりをキャッチしたらパンタのプレイを終了し、大喜びアクションへ移行する。
そしてパンタが退場し、次のキャラクターであるポンへ交代する。
今回作成した取得数管理システムが、次のゲーム進行システムへつながっていきます。
