AIゲーム開発研究室
AIに「どんぐり工場」を作らせる
AIゲーム開発研究室
ゲーム開発ドキュメント
Unity AI Agentによるゲームシステム実装
AIに「どんぐり工場」を作らせる
前回の実験では、Unity AI Agentによってパンタのアニメーションとプレイヤー操作を実装した。
パンタは待機時には正面を向いて小さく動き、右へ移動すると右向きのアクションへ切り替わる。
左へ移動するときには右向きアニメーションを反転して使用し、キーを離すと再び正面の待機状態へ戻る。
さらに、
左右矢印キー
A・Dキー
の両方で操作でき、画面外へ出ないようにする制御も実装された。
これによって、パンタはゲーム画面に置かれた一枚の画像から、
プレイヤーが操作できるゲームキャラクター
になった。
次はいよいよ、ゲームそのものを動かしてみる。
「森のどんぐり大作戦」は、空から落ちてくるどんぐりを、キャラクターが籠で受け止めるゲームである。
まず必要なのは、
どんぐりを空から落とすこと
である。
最初のどんぐりを落とす
いきなり大量のどんぐりを出現させるのではなく、最初は1個だけ落としてみることにした。
使用するのは、すでに制作してUnityへ読み込んである、
Acorn_01.png
である。
Unity AI Agentへ、
画面上部にどんぐりを1個出現させ、2D物理を使用して自然に落下させる
よう指示した。
さらに、
落下しながら回転すること
画面下へ完全に出たら削除すること
も要求した。
ただし、この段階では、
キャッチ判定も、
得点も、
連続出現も、
まだ実装しない。
まず、
「どんぐりが1個落ちる」
という最小単位だけを作る。
どんぐりが落ちた
Unity AI Agentによる実装が完了した。
Playする。
画面上部から、
どんぐりが1個落ちてきた。
しかも、回転しながら落下している。
そして画面下へ出ると、自動的に削除された。
ここまで正常に動作した。
さらに、どんぐりの表示サイズについても、こちらから具体的な数値は指定していなかった。
指示したのは、
パンタとゲーム画面に対して適切な大きさにすること
だけである。
実際に表示されたどんぐりを見ると、特に修正する必要のない大きさになっていた。
人間が動きを判断する
一方、実際に落下するどんぐりを見ると、少し気になるところがあった。
ゲーム画面は上下に前景の枝葉と草が配置されているため、実際にどんぐりを追いかけられる空間はそれほど広くない。
そのため、最初の落下速度では少し速く感じられた。
また、どんぐりの回転については、もう少しはっきり回転してもよいように感じた。
そこでUnity AI Agentへ、
どんぐりの大きさは変更しない
落下速度だけ少し遅くする
回転は少し強くする
よう指示した。
ここでも具体的な数値は指定していない。
AIが数値を変更し、人間が実際の画面を見て判断する。
再びPlayする。
今度は、落下速度も回転も自然に感じられた。
この状態を採用することにした。
「どんぐり工場」を作る
1個のどんぐりが正常に落下することが確認できた。
次は、これを連続して出現させる。
ただし、同じ場所から落ち続けるのではゲームにならない。
そこでUnity AI Agentへ、
画面上部のランダムなX位置から、一定間隔でどんぐりを1個ずつ生成し続ける
よう指示した。
すでに完成している、
どんぐりの大きさ
落下速度
回転
画面外での削除
については変更しないようにした。
AIは、どんぐりを生成するための仕組みを構築した。
Playする。
今度は、
次々とどんぐりが降ってきた。
しかも毎回同じ位置ではなく、画面上部の異なる位置から出現する。
ここで、どんぐりを継続的にゲーム画面へ供給する基本システムが完成した。
制作中、これを私たちは、
「どんぐり工場」
と呼ぶことにした。
実際にパンタを動かしてみる
まだキャッチ判定は実装していない。
そのため、パンタをどんぐりの下へ移動させても、どんぐりはそのまま通過して画面下へ落ちていく。
それでも、パンタを左右へ操作しながら、ランダムに落ちてくるどんぐりを追いかけてみた。
すると、一つの問題が見えてきた。
思ったより難しい。
画面の上下には枝葉と下草があり、実際にプレイヤーが認識して移動できる空間は広くない。
そこで、
パンタをもう少し小さくするか。
どんぐりの落下速度をさらに遅くするか。
ゲーム画面そのものを考え直すか。
いくつかの可能性を検討した。
しかし、ここで別の考え方が出てきた。
そもそも全部取る必要があるのか
「森のどんぐり大作戦」は、
落ちてくるすべてのどんぐりを取らなければならないゲームではない。
取れないどんぐりがあってもよい。
プレイヤーは、
これは取れる。
あれは間に合わない。
次のどんぐりを狙おう。
と判断しながらキャラクターを動かす。
そう考えると、すべてのどんぐりを簡単に取れるようにする必要はない。
むしろ、全部取れてしまう方がゲームとして単調になる可能性がある。
キャラクターによってゲームが変わる
さらに、これから実装する5人のキャラクターには、それぞれ違った特徴を持たせる予定である。
移動速度についても、
高速
標準
低速
の3段階を基本とすることにしている。
現時点では、
リン=高速
パンタ=標準
ポン=低速
を想定している。
すると、同じ速度で落ちてくる同じどんぐりでも、キャラクターによって遊び方が変わる可能性がある。
リンなら、素早く走って画面の端に落ちてくるどんぐりまで追いかけられるかもしれない。
パンタなら、取れるどんぐりを判断しながら普通に追いかける。
ポンは移動が遅いため、どんぐりを追いかけるより、
「ここへ落ちてくるだろう」
と予測して待ち伏せする遊び方になるかもしれない。
そしてコンタには、移動すると少し滑るという特徴を持たせる予定である。
どんぐりを見つけて走り出したものの、
止まりたい場所で止まれない。
結果、
全然取れない。
ということも起こるかもしれない。
しかし、それも失敗ではなく、
コンタというキャラクターで遊ぶ面白さ
になる可能性がある。
難易度を今は決めない
そこで今回は、現時点で難易度調整を行わないことにした。
どんぐりの落下速度も、
パンタの大きさも、
出現間隔も、
ゲーム画面の構成も、
ひとまず現在の状態を維持する。
5人のキャラクターが実装された段階で、実際にそれぞれを操作してからゲーム全体のバランスを判断する。
これは、単純にゲームを「簡単にする」「難しくする」という調整ではない。
キャラクターの個性によって、同じゲームの遊び方そのものが変わる。
その可能性を残しておくためである。
AIがゲームシステムを作り始めた
今回、人間はどんぐりの落下スクリプトを書いていない。
2D物理コンポーネントも設定していない。
画面外へ出たどんぐりを削除する処理も書いていない。
ランダムな位置から継続的にどんぐりを生成するシステムも、人間が実装したものではない。
人間が行ったのは、
どんぐりを落としたい。
もう少しゆっくり落としたい。
もう少し回転させたい。
今度はランダムな場所から連続して落としたい。
という目的と判断を伝えることだった。
Unity AI Agentは、それをUnity上の具体的なシステムへ変換した。
前回までAIが作っていたのは、主としてキャラクターの動きだった。
今回は、
ゲーム世界そのものを動かすシステム
をAIが作り始めたことになる。
人間は、ますます観客になっていく
パンタが動き、
どんぐりが降ってくる。
画面を見ながらパンタを左右へ動かしていると、ゲームの形が急速に見え始めた。
そして今回も、人間がUnity上で直接行う作業は非常に少なかった。
AIへ指示を渡す。
必要に応じて操作を許可する。
Playする。
見る。
遊ぶ。
そして、
「これはいい」
「これは少し速い」
「このままで行ってみよう」
と判断する。
実装の主体がAIへ移るほど、人間はますます、
ゲームを作っている人というより、ゲームが作られていくところを見ている観客
のようになっていく。
もちろん、その観客は作品の方向を決める。
しかし、目の前でAIが次々とUnityを実装していく様子を見ると、
「人間はもう観客なのではないか」
と思えてくる。
そして、それが意外なほど楽しい。
今回の到達点
今回の実験によって、
どんぐり1個の生成
2D物理による落下
落下中の回転
画面外へ出たどんぐりの自動削除
落下速度と回転の調整
ランダムなX位置からの出現
一定間隔での連続生成
まで実装された。
パンタはすでにプレイヤーの操作によって左右へ動く。
その頭上から、今度はどんぐりが次々と降ってくる。
まだ、どんぐりを取ることはできない。
パンタの前を通過して、そのまま地面の下へ消えていく。
しかし、
キャラクターが動き、ゲーム世界からオブジェクトが生成される。
ここまで来たことで、「森のどんぐり大作戦」は静的なゲーム画面から、明確にゲームシステムを持つ世界へ変わり始めた。
次はいよいよ、
パンタの籠で、どんぐりを受け止める。
どんぐりが籠に入った瞬間に消える。
その瞬間、
落ちてくる
↓
追いかける
↓
キャッチする
という「森のどんぐり大作戦」の最初のゲームループが完成する。
どんぐり工場は、無事に稼働を開始した。 🌰
AIはゲームキャラクターを動かし、自ら問題を診断できるのか
AIゲーム開発研究室
ゲーム開発ドキュメント
Unity AI Agentによるキャラクター実装
AIはゲームキャラクターを動かし、自ら問題を診断できるのか
前回の実験では、Unity AI Agentを使用して、「森のどんぐり大作戦」の背景、上部前景、下部前景、そしてパンタをUnity上へ配置した。
それまで別々の画像素材として制作してきたものが、初めて一つのゲーム画面として組み合わされた。
しかし、まだパンタは動かない。
今回は、いよいよパンタをゲームキャラクターとして動かしてみる。
ここでも基本方針は変わらない。
人間がUnityのInspectorを操作し、スクリプトを書き、Animatorを設定するのではなく、
人間と対話AIが実装内容を検討し、その指示をUnity AI Agentへ渡す。
Unity AI Agentは、その指示をもとに実際のUnityプロジェクトを構築する。
まず、パンタのアニメーションを作る
パンタの待機時のアクションには、すでに制作済みの3枚の画像素材がある。
Panta_Catch_Up_01.png
Panta_Catch_Up_02.png
Panta_Catch_Up_03.png
この3枚を、
01 → 02 → 03
の順番で切り替えることによって、パンタがその場で小さく動くアクションになる。
Unity AI Agentへ、この3枚からSprite Animationを作成するよう指示した。
AIはAnimation ClipとAnimator Controllerを作成し、既存のPanta GameObjectへ設定した。
Playしてみる。
パンタが動いた。
画像は、
01 → 02 → 03
の順番で正常に切り替わっている。
ところが、一つ問題があった。
素材にあるはずの上下動が消えた
3枚の画像素材には、パンタの上下位置そのものに差をつけてある。
つまり、Unity側でPanta GameObjectを上下させなくても、画像を順番に切り替えるだけでパンタが小さく上下して見えるように制作している。
しかし、Unity上では画像は切り替わっているものの、その上下動がほとんど見えない。
なぜなのか。
ここで人間がSprite Editorを開き、原因を調べることもできる。
しかし今回は、それをしなかった。
Unity AI Agentへ、
「アニメーションは正常に動いているが、元画像に含まれている上下動が見えない。原因を調査してほしい。ただし、まだ修正はしないこと」
と指示した。
Unity AI Agentが原因を調査する
Unity AI Agentは、元となった3枚のPNG画像とUnity側のSprite設定を調査した。
その結果、原因が判明した。
3枚の画像は、すべて同じ
200 × 349 pixel
のキャンバスで制作されていた。
そして元画像を調べると、パンタが描画されている位置には実際に差があった。
2枚目では1枚目より約36pixel上へ移動し、3枚目では約13pixel上へ移動している。
つまり、
元画像には確かに上下動が存在していた。
問題はUnity側にあった。
UnityへSpriteとして取り込む際、透明部分を含む共通キャンバス全体ではなく、実際にキャラクターが描画されている領域を基準として扱い、それぞれのSpriteが再び中央へ揃えられていた。
その結果、
画像素材の中に存在していた位置の差が相殺されていた。
Unity AI Agentは、ここまで自ら調査して原因を報告した。
AIに自分の実装を修正させる
原因が分かった。
そこで今度はUnity AI Agentへ修正を指示した。
ただし、
「2枚目を36pixel上げる」
「3枚目を13pixel上げる」
とは指示していない。
人間側から数値を与えるのではなく、
元の200×349pixelの共通キャンバスに含まれている位置情報を維持すること
を要求した。
Unity AI AgentはSpriteの設定を修正した。
再びPlayする。
今度は、
パンタが小さく上下した。
元画像に仕込まれていた動きが、Unity上でも正しく再現された。
さらに驚いたことに、アニメーション速度についても特に調整する必要がなかった。
そのままで自然な動きになっていた。
足元の見え方を調整する
アニメーション自体は完成した。
しかし実際に動いているパンタを見ると、足の動きの一部が下部前景の草に隠れすぎているように感じられた。
そこでUnity AI Agentへ、
着地時には足の一部が草に隠れる。しかし上へ動いたときには足の動きが見える位置
になるよう、パンタ全体のY位置を少しだけ上へ調整するよう指示した。
ここでも具体的なY座標は指定しない。
Unity AI Agentが位置を調整し、人間が実際の画面を見て判断する。
その結果、パンタが森の地面に立っている感じを残しながら、動きもよく見える位置になった。
プレイヤーがパンタを動かす
次に、パンタをプレイヤーが操作できるようにする。
Unity AI Agentへ、
左右矢印キー、またはA・Dキーでパンタを左右へ移動させる
よう指示した。
AIは必要なスクリプトを作成し、Panta GameObjectへ設定した。
Playする。
右へ動く。
左へ動く。
矢印キーでも、A・Dキーでも正常に操作できた。
さらに、パンタが画面外へ出ないようにする制御も実装されていた。
これによって、パンタは単なるアニメーション画像ではなく、
プレイヤーが操作するゲームキャラクター
になった。
キャラクターの速度を考える
パンタ単体で操作すると、最初に設定された移動速度でも問題はなかった。
しかし「森のどんぐり大作戦」では、最終的に5人のキャラクターが登場する。
そこで移動速度について、
高速
標準
低速
の3段階を基本とすることにした。
現時点では、
リン=高速
パンタ=標準
ポン=低速
を予定している。
そのため、パンタの移動速度を最初の状態より少し遅くし、
ゲーム全体の標準速度
として使える操作感へ調整した。
コンタとミミについては、速度だけではなく、それぞれ別の動作特性も含めて今後検討する。
右を向いて動く
ここまでのパンタは、左右へ移動することはできるものの、待機用の正面アニメーションのまま横へ移動していた。
そこで次に、右移動用として制作していた、
Panta_Catch_Right_01.png
Panta_Catch_Right_02.png
Panta_Catch_Right_03.png
を使用する。
待機アニメーションで発生した問題を踏まえ、今回は最初から、
元画像の共通キャンバスに含まれる位置情報を維持すること
をUnity AI Agentへ指示した。
さらに、
停止中 → Panta_Catch_Up
右移動中 → Panta_Catch_Right
となるようAnimatorと移動制御を連携させる。
実装後にPlayすると、
右キーを押した瞬間にパンタが右向きのアクションへ切り替わり、そのまま右へ移動した。
キーを離すと停止し、正面向きの待機アクションへ戻る。
成功である。
左移動に新しい画像は作らない
左移動については、新しい画像素材を用意しなかった。
完成した右移動用アニメーション、
Panta_Catch_Right
をそのまま使用し、左へ移動するときだけSpriteを左右反転させる。
Unity AI Agentへその処理を指示した。
結果、
停止中 → 正面
右入力 → 右を向いて移動
左入力 → 左を向いて移動
キーを離す → 正面へ戻って待機
という一連の動作が完成した。
AIは実装するだけではなかった
今回、最も興味深かったのは、パンタが動いたことだけではない。
途中で、
「元画像に存在する上下動がUnity上では消えてしまう」
という、事前には想定していなかった問題が発生した。
そこで人間がUnityの設定を調べて修正したのではない。
Unity AI Agentへ問題を伝えた。
AIは、
元画像を調査し、
Unity側の設定を調査し、
両者を比較し、
原因を特定し、
その結果を人間へ報告した。
そして修正を指示すると、その問題も解決した。
つまり今回確認されたのは、
AIによる実装
だけではない。
AIによる実装結果の診断と修正
まで含まれている。
人間は何をしていたのか
今回、人間はC#スクリプトを書いていない。
Animator Controllerも作っていない。
SpriteのPivotも修正していない。
Transformへ移動速度の数値を入力したわけでもない。
人間が行ったのは、
動きを見る。
違和感を見つける。
どのような動きにしたいかを判断する。
AIから求められた操作許可を確認する。
完成した結果を採用するか判断する。
ということである。
実装作業のかなりの部分をAIが担当するようになると、人間の役割は、
「作る人」から「見て、判断する人」へ
少しずつ移動していく。
実際、今回の制作中、
「もう人間は観客ではないか」
と思うほど、Unity AI Agentが次々と実装を進めていった。
しかし、その「観客」は何もしない観客ではない。
どの動きがかわいいのか。
どの速度がキャラクターに合っているのか。
足がどの程度草に隠れるべきなのか。
ゲーム全体としてキャラクター間の速度差をどう設計するのか。
そうした判断は、依然として人間が行っている。
今回の到達点
今回の実験によって、パンタには、
待機アニメーション
左右移動
右向き移動アニメーション
左向き移動アニメーション
停止時の待機状態への復帰
矢印キー/A・Dキーによる操作
画面外への移動制限
標準キャラクターとしての移動速度
が実装された。
前回、森の中に立ったパンタが、
今回は自分で動き始めた。
そしてUnity AI Agentは、単に指示された実装を行うだけではなく、途中で発生した問題について、自らプロジェクト内部を調査し、原因を特定するところまで行った。
ここまで来ると、
「AIはUnityを操作できるのか」
という最初の問いから、研究は明らかに次の段階へ進んでいる。
次に試すのは、
ゲームシステムそのものをAIに作らせること
である。
パンタは動けるようになった。
次は――
空から、どんぐりが落ちてくる。
「森のどんぐり大作戦」が、いよいよゲームとして動き始める。
AIはゲーム画面を組み立て、見た目を判断できるのか
AIゲーム開発研究室
ゲーム開発ドキュメント
Unity AI Agentによる実制作開始
AIはゲーム画面を組み立て、見た目を判断できるのか
前回の実験では、Unity AI Agentに自然言語で指示を与えることによって、GameObjectの作成、コンポーネントの追加、C#スクリプトの作成とアタッチ、さらにオブジェクトの移動まで実行できることを確認した。
これによって、
自然言語による指示だけで、AIはUnityを実装できるのか。
という最初の問いに対して、一つの大きな成果を得ることができた。
しかし、実際のゲーム開発はここからである。
今回は実験用のGameObjectではなく、これまで制作してきた実際のゲーム素材をUnityへ読み込み、
Unity AI Agentにゲーム画面そのものを組み立ててもらう。
いよいよ「森のどんぐり大作戦」の実制作へ入ることにした。
ゲーム素材をUnityへ読み込む
まず、これまで制作してきた素材ファイルを整理した。
素材のファイル名をUnityで扱いやすい英数字表記へ変更し、用途ごとにフォルダを分けた。
背景素材は、
Assets/Art/Backgrounds
キャラクター素材は、
Assets/Art/Characters/Panta
アイテム素材は、
Assets/Art/Items
へ配置した。
これによって、背景、キャラクター、どんぐりなど、ゲーム制作に必要な素材をUnity上で整理して管理できる状態になった。
今回は、この素材を人間が一つずつシーンへ配置するのではない。
ここからUnity AI Agentへ指示を与える。
AIに背景を配置させる
最初に、ゲームの基本背景を配置するようUnity AI Agentへ指示した。
使用する素材は、
Forest_Background.png
である。
Unity AI Agentは素材を認識し、SpriteRendererを持つGameObjectを作成してシーンへ配置した。
背景そのものの配置には成功した。
しかし、最初の状態ではゲーム画面全体を完全には覆っていなかった。
そこで、
Main Cameraの表示領域全体を背景で覆い、画像の縦横比は維持する
ように指示した。
Unity AI AgentはMain Cameraと背景画像の大きさを調べ、背景のScaleを計算して変更した。
その結果、1920×1080のゲーム画面全体を背景画像で覆うことができた。
ここで重要なのは、人間がScaleの数値を計算して入力したのではないことである。
人間が伝えたのは、
「ゲーム画面全体を背景で覆う」
という目的だけだった。
その目的を実現するために必要なUnity上の処理を、AIが判断して実行した。
上部前景を配置する
続いて、画面上部の枝葉素材、
Forest_Foreground_Top.png
を配置した。
これは背景画像の上へ重ねる前景素材である。
Unity AI Agentへ、画面上部へ配置し、背景より手前に表示するよう指示した。
AIはGameObjectを作成し、位置とScaleを調整し、SpriteRendererの描画順も設定した。
ゲーム画面を確認すると、背景の森の手前に枝葉が重なり、画面上部に自然な奥行きが生まれた。
下部前景を配置する
次に、
Forest_Foreground_Bottom.png
を使用して、ゲーム画面下部の草地を配置した。
こちらもUnity AI AgentがGameObjectを作成し、位置、大きさ、描画順を設定した。
これによって、
背景の森
上部の枝葉
下部の草地
という三つのレイヤーがUnity上で組み合わされた。
素材制作段階では別々の画像だったものが、初めてゲーム画面として一つになった。
ここまでの画面構成は、すべてUnity AI Agentへの自然言語による指示を中心として行っている。
そして、パンタ登場
背景と前景が完成したところで、いよいよパンタを登場させることにした。
使用したのは正面向きの、
Panta_Front.png
である。
Unity AI Agentへ、パンタをゲーム画面中央付近へ配置するよう指示した。
AIはパンタのGameObjectを作成し、SpriteRendererへ画像を設定してシーンへ配置した。
森の中に、初めてパンタが立った。
これまで別々に制作してきた背景、前景、キャラクターがUnity上で一つのゲーム画面として組み合わされた瞬間である。
AIに「自然な位置」を判断させる
ここで新しい問題が生まれた。
パンタを単純に画面下部へ置いただけでは、背景画像の上にキャラクター画像を貼り付けたように見える。
パンタは森の中に立っている。
したがって、着地しているときには、
足の一部が手前の草に隠れている方が自然である。
そこで今回は、具体的なY座標を指定しなかった。
Unity AI Agentには、
パンタを少し下へ移動し、足の一部だけが前景の草に自然に隠れる位置へ調整する
よう指示した。
すると、これまでとは少し違う動きが始まった。
AIが画面を見始めた
Unity AI AgentはパンタのY座標を変更した。
そして、
Capture 2D Scene
を実行しようとした。
画面キャプチャの許可を与えると、AIはシーンを確認した。
さらにパンタのY座標を変更した。
そして再び画面キャプチャを要求した。
つまり、
位置を変更する
↓
画面を確認する
↓
さらに位置を変更する
↓
もう一度画面を確認する
という処理を始めたのである。
最終的にパンタは、
Y = -2.85
付近へ配置された。
重要なのは、この数値を人間が指定したのではないということである。
人間が伝えたのは、
「足が下草に少し隠れる自然な位置」
という視覚的な目的だった。
AIはその目的を実現するため、自ら位置を変更し、画面を確認しながら調整した。
「数値を指定する」から「目的を伝える」へ
今回の実験で見えてきたものは、単なるUnity操作の自動化だけではない。
従来のUnity制作であれば、人間が画面を見ながら、
TransformのY座標を変更する。
画面を見る。
もう少し下げる。
再び画面を見る。
という調整を行う。
今回、この試行錯誤の一部をUnity AI Agentが行った。
人間は具体的な数値ではなく、
「どう見えてほしいのか」
を伝えた。
AIは、その目的をUnity上の具体的な操作へ変換した。
これは、前回確認した
自然言語 → Unity操作
から、さらに一歩進んだ結果である。
今回確認できたのは、
自然言語による目的の提示
↓
Unity上での操作
↓
結果の視覚的確認
↓
再調整
という流れである。
人間の役割はなくならない
ただし、AIが最終的な美的判断まで完全に行えることが確認されたわけではない。
今回のパンタの位置についても、人間から見ると少し低く感じる可能性がある。
一方で、使用している正面向きパンタはもともと足が短く、実際のゲームではジャンプアクションも使用する。
さらに、着地時には足が前景の草に少し隠れる必要がある。
そのため今回は、この位置を現時点での着地基準位置として採用することにした。
ここには、
AIが候補を作る。
人間がゲーム全体の目的から採否を判断する。
という役割分担が現れている。
AIが人間に代わってすべてを決定するのではない。
しかし、人間がUnityのすべての数値を直接操作する必要もない。
両者の間に、新しいゲーム制作の形が見え始めている。
今回の到達点
今回、Unity AI Agentによって、
実際のゲーム素材を読み込み、背景を配置し、前景を重ね、キャラクターを配置するところまで進んだ。
さらに最後には、
画面を確認しながらキャラクターの位置を調整する
という処理まで確認することができた。
前回は、
AIはUnityを操作できるのか。
という実験だった。
今回はそこから一歩進み、
AIは実際のゲーム画面を組み立てられるのか。
そして、
AIは結果を見ながら調整できるのか。
という実験になった。
少なくとも今回の範囲では、その両方について具体的な成果を得ることができた。
そして画面には今、
森があり、
草木があり、
その中にパンタが立っている。
まだゲームとしては動いていない。
しかしこれはもう、単なるUnity AI Agentの動作実験ではない。
「森のどんぐり大作戦」の実制作が始まったのである。
自然言語による指示だけで、AIはUnityを実装できるのか
ゲーム開発ドキュメント
Unity AI Agentによるゲーム実装実験
自然言語による指示だけで、AIはUnityを実装できるのか
これまで「森のどんぐり大作戦」では、キャラクター、背景、前景、どんぐりなど、ゲームに必要となる素材の制作を進めてきた。
そして今回、いよいよUnityによるゲーム実装へ入る。
ただし、本研究では、人間がUnityを操作し、AIにはC#スクリプトだけを書いてもらう、という方法を目指しているわけではない。
AIにスクリプトを書いてもらい、
人間がGameObjectを作り、
人間がスクリプトをアタッチし、
人間がComponentを追加し、
人間がInspectorを設定する。
それでは、ゲーム実装の主体は依然として人間である。
そこで今回は、さらに一歩踏み込むことにした。
自然言語による指示だけで、AIがUnity Editor内部の実装作業そのものをどこまで行えるのか。
Unity AI Agentを使用して、実際に検証する。
Unity AIを前提としたプロジェクトの作成
今回の実装環境には、
Unity 6.5(6000.5.8f1)
を使用した。
テンプレートには、
Universal 2D
を選択。
プロジェクト名は、
Omusubiyama
とした。
そして今回、特に重要なのが、
「AI Assistantを使用」
をONにした状態でプロジェクトを作成したことである。
今回Unityを使用する目的は、単にゲームを実装することではない。
AIがUnity内部のゲーム構築に、どこまで直接参加できるのか。
それ自体を検証する。
Unity AI Agentの導入
Unity Editorを起動し、
Window → AI → Assistant
からUnity AI Assistantを開いた。
Unity AIを使用するため、今回は14日間の無料トライアルを開始した。
しかし、これですぐ実験開始とはならなかった。
Assistantには、
Checkpoints setup failed
という警告が表示された。
AIにUnityを任せるための「戻り」
Checkpointは、AIがUnityプロジェクトへ変更を加える際、その変更前の状態を保存しておくための仕組みである。
AIによる実装では、
AIに変更させる
だけでは不十分である。
問題が発生した場合、
変更前へ戻れる
ことも重要になる。
画像生成AIによる素材制作でも、生成結果を比較し、必要なら前の状態へ戻ることは重要だった。
Unity実装では、それ以上に「戻り」が重要になる。
そこでCheckpointを使用できる状態にしてから実験を開始することにした。
エラーを確認したところ、Gitが見つからないことが原因だった。
そこでGit for Windowsを導入した。
導入直後にはUnity側で認識されなかったが、PCを再起動したところ、
System(git 2.55.0)
として正常に認識され、
Checkpoints setup successful
となった。
これで、AIにUnityを変更させるための実験環境が整った。
実験1 AIにGameObjectを作らせる
最初からゲーム本体を実装させることはしない。
まず確認したいことは、非常に単純である。
自然言語による指示だけで、AIはUnity Editorを実際に操作できるのか。
Unity AI Agentへ、次のプロンプトを入力した。
使用プロンプト
Create one empty GameObject in the current scene and name it AI_Test_Object.
Do not make any other changes.
指示したのは、
現在のSceneに空のGameObjectを一つ作成し、AI_Test_Objectという名前を付ける。
ただそれだけである。
Agentは処理に必要なコードを生成した。
内容を確認すると、
AI_Test_Object
というGameObjectを作成する処理が記述されていた。
実行を許可すると――
Hierarchyに、
AI_Test_Object
が出現した。
人間はUnityのメニューからGameObjectを作成していない。
自然言語でAIへ指示しただけである。
Unity AI AgentがUnity Editorを実際に変更できることが確認された。
実験2 Componentを追加し、Inspectorを設定する
GameObjectを作れることは確認できた。
しかし、それだけではゲーム実装とは言えない。
次に確認したのは、
既存のGameObjectをAIが認識し、Componentを追加し、そのパラメータまで設定できるのか。
ということである。
使用プロンプト
Add a Rigidbody2D component to AI_Test_Object.
Set its Gravity Scale to 0.
Do not make any other changes.
Agentは既存の AI_Test_Object を検索し、Rigidbody2Dがすでに存在するか確認したうえで、存在しない場合には追加する処理を生成した。
さらに、
Gravity Scale = 0
を設定する処理も生成した。
実行すると、
AI_Test_Object
のInspectorに、
Rigidbody 2D
が追加され、
Gravity Scale = 0
に設定された。
これによって、
GameObjectの生成だけでなく、Componentの追加とInspector相当のパラメータ設定までAIが実行できる
ことが確認された。
AIが止まった?
ところが、この実験中に一つ問題が発生した。
Agentへ指示を出しても、いつまでたっても処理が終わらない。
画面では処理中のように表示されている。
最初は、
PCの性能が足りないのではないか。
とも考えた。
しかし、よく画面を見ると、
Awaiting input...
と表示されていた。
さらに、
Assistant wants to Execute code
と表示され、
人間に、
Deny / View / Allow
の選択を求めていた。
つまり――
AIは止まっていたのではなかった。
人間からの許可を待っていたのである。
しかも、人間がそれに気づかなかったため、AIは長時間、何もせず待ち続けていた。
ここで今回の実験による副次的な発見があった。
AIは非常に辛抱強い。
AIへ与える権限を変更する
Unity AI Assistantの設定を確認すると、
Execute Generated C# Code
が、
Ask Permission
になっていた。
つまり、AIが生成したC#コードを実行するたびに、人間の許可を必要とする設定である。
そこで、
Ask Permission → Allow
へ変更した。
すべての権限を無条件にAIへ渡したわけではない。
今回必要となる、
生成したC#コードを実行する権限
だけを変更した。
そして再び実験を行った。
実験3 Colliderを追加し、数値を設定する
次に、既存の AI_Test_Object へBoxCollider2Dを追加させる。
使用プロンプト
Add a BoxCollider2D component to AI_Test_Object.
Set the BoxCollider2D Size to X = 2 and Y = 3.
Do not make any other changes.
すると――
驚くほど速く処理が完了した。
AI_Test_Object のInspectorには、
Box Collider 2D
が追加され、
Size X = 2
Size Y = 3
に設定された。
人間はComponentを追加していない。
Inspectorの数値も入力していない。
自然言語による指示だけで、
対象GameObjectの認識
→ Componentの追加
→ パラメータ設定
→ Unityへの反映
までが実行された。
同時に今回の実験では、もう一つ重要なことが分かった。
AI Agentの能力だけではなく、人間がAIへどのような権限を与えるかによって、開発フローそのものが大きく変化する。
これは今後、AIによるゲーム実装を考えるうえで重要な検討事項になる。
実験4 C#スクリプトを作り、GameObjectへアタッチする
最後に、さらに一段階進める。
今度は単なるComponent設定ではない。
AI自身にC#スクリプトを新規作成させ、それをGameObjectへアタッチさせる。
そして実際に動作させる。
Unity AI Agentへ、次の指示を行った。
使用プロンプト
Create a new C# script named AI_Test_Movement.
The script should make AI_Test_Object move slowly left and right automatically while the game is running.
Attach the AI_Test_Movement script to AI_Test_Object.
Do not modify or remove the existing Rigidbody2D or BoxCollider2D.
Do not make any other changes.
今回は、新しいファイルを作成するため、
Create file
の許可を求められた。
これはC#コードの実行とは別の権限である。
ファイル作成を許可すると、Agentは、
AI_Test_Movement.cs
を新規作成した。
さらに、
AI_Test_Objectへ自動的にアタッチ
した。
既存の、
Rigidbody2D
BoxCollider2D
も維持されている。
Inspectorにはスクリプトの公開パラメータも表示された。
ここまで、人間はC#コードを書いていない。
スクリプトファイルも作っていない。
GameObjectへのアタッチもしていない。
すべてAIが行った。
AIが作ったゲーム処理を実行する
最後にUnityのPlayボタンを押した。
すると、
AI_Test_ObjectのTransformのX座標が左右へ往復し始めた。
AIが作成したC#スクリプトが、Unity上で実際に動作したのである。
今回作ったもの自体は、左右へ動くだけの単純なGameObjectである。
しかし、この実験の目的はゲームを完成させることではない。
確認したかったのは、
AIがUnityの実装作業そのものを担当できるのか
ということである。
その問いに対して、今回の基礎実験では明確な結果が得られた。
今回の実験で確認できたこと
今回、人間は、
C#を書いていない。
Rigidbody2Dを手動で追加していない。
BoxCollider2Dを手動で追加していない。
Inspectorのパラメータを手動で設定していない。
生成されたスクリプトをGameObjectへ手動でアタッチしていない。
人間が行ったのは、
何を実装するのかを決めること。
AIへ自然言語で指示すること。
必要な権限を判断して与えること。
AIが行った結果を確認すること。
次に何を行うのかを判断すること。
である。
一方、AIは、
GameObjectの生成
既存GameObjectの認識
Componentの追加
パラメータの設定
C#スクリプトの生成
GameObjectへのアタッチ
実行可能な状態の構築
を担当した。
人間 → AI → Unity
これまでゲーム実装では、
人間 → Unity
という関係が基本だった。
人間がUnityを操作し、GameObjectを作り、Componentを追加し、Inspectorを設定し、スクリプトをアタッチする。
しかし今回の実験では、その間にAIが入った。
人間
↓
自然言語による実装指示
↓
AI Agent
↓
Unity
という新しい実装経路が、実際に成立した。
これは単に、
「AIにC#を書いてもらう」
ということではない。
人間が実装方針を決め、
AIへ指示し、
AIがUnity内部で実装し、
人間がその結果を確認して次の判断をする。
ゲーム実装における人間とAIの役割そのものが変化する可能性がある。
今回の実験は、まだ非常に小さな基礎実験にすぎない。
複数のGameObject。
ゲーム素材。
Prefab。
Collider同士の関係。
ゲーム進行。
キャラクター制御。
シーン管理。
エラーの発見と修正。
実際のゲーム制作では、これから検証しなければならないことが数多く残されている。
しかし少なくとも今回、
自然言語による指示から、AIによるUnity実装、そして実際の動作までを一本につなぐことができた。
ゲーム素材の制作を終え、
いよいよ「森のどんぐり大作戦」のUnity実装へ入ろうとしていたその入口で、
想定していた以上に大きな扉が開いた。
AIはゲーム開発を支援するだけなのか。
それとも、
人間と役割を分担し、ゲームそのものを実装する存在になり得るのか。
ここから、その答えを実際のゲーム制作によって確かめていく。
実装前に不足したキャラクター素材を追加制作する
AIゲーム開発ドキュメント
第28回 実装前に不足したキャラクター素材を追加制作する
ゲームの実装設計を進めたことで、パンタに新たなキャラクター素材が必要であることが分かった。
必要になったのは、ゲーム中のキャラクター交代時や終了時などに使用する「大喜び」のアクションである。
当初の素材設計では想定していなかったが、実際のゲームの動きを具体的に考えていく中で必要性が明らかになった。
そこで、実装へ進む前にいったん素材制作へ戻り、パンタの追加画像を制作することにした。
連続アニメーションを作らせない
これまでの実験では、生成AIに歩行などの連続した動作を一度に制作させた場合、足の運びやポーズの連続性を正確に制御することが難しかった。
そこで今回は、完成したアニメーションそのものを生成AIに作らせる方法を採用しなかった。
生成AIには、
「大喜びしているパンタの異なるポーズを複数制作する」
ことを求めた。
実際のジャンプや上下移動などは、画像として描かせるのではなく、Unity側で制御する。
つまり、
画像生成AIには「ポーズ」を作らせ、ゲーム上の「動き」はUnityで作る。
という役割分担である。
「違うポーズ」を言葉で定義する
しかし、単に、
「違う喜びのポーズを複数作ってください」
と指示しただけでは、腕の位置だけが少し違う、ほとんど同じ画像が生成される可能性がある。
そこで今回のプロンプトでは、ポーズの違いを具体的に言語化した。
- 腕の位置を変える
- 脚の位置を変える
- 身体の傾きを変える
- 左右への重心移動を変える
- 表情を変える
重要なのは、
「差分を作るために、身体のどこを変化させるのか」まで言語化したこと
である。
その結果、顔の向きも含め、身体全体の動きが異なる7種類の大喜びポーズが生成された。
単なる腕の差分ではなく、身体全体の重心やシルエットが異なる素材を得ることができた。
生成された画像の中から必要なポーズを選択し、Unity側の動きと組み合わせてゲーム内のアクションとして使用する。
「イラスト」から「ゲーム素材」へ変換する制作工程
今回も、人間による加工を経て、大喜びしているパンタの素材を完成させた。
実装設計から素材制作へ戻る
今回、もう一つ重要だったのは、ゲーム開発の工程が一方向には進まなかったことである。
素材制作が終わったから実装する。
それだけではなかった。
実装方法を具体的に考えたことで不足している素材が判明し、再び素材制作へ戻った。
設計
→ 素材制作
→ 実装設計
→ 不足素材の発見
→ 素材制作へ戻る
→ 実装
という流れが実際に発生したのである。
これは失敗による後戻りではない。
実装を具体化したからこそ発見できた、新たな制作条件である。
AIを利用したゲーム開発においても、最初にすべてを決めて一本道を進むのではなく、制作と実装を往復しながら必要なものを発見していく。
今回のパンタの追加素材制作は、その「戻り」が実際の制作工程の一部であることを示す実例となった。
今回使用したプロンプト
以下が、今回パンタの「大喜び」素材を制作するために画像生成AIへ入力したプロンプトである。
森のどんぐり大作戦
パンタ 大喜びアクション素材 制作プロンプト Ver.1.1
制作目的
2Dゲーム「森のどんぐり大作戦」に使用する、
パンタの「大喜び」アクション素材
を制作してください。
ゲームクリア時、キャラクター交代時、登場シーンなどで使用できる、パンタらしい元気でかわいい喜びのポーズを複数制作します。
生成されたポーズの中から、最終的に3カット程度を選び、ゲーム内の喜びアクションとして使用します。
使用する基準画像
添付する
「パンタ キャラクターマスター(公式基準画像)」
を必ず基準画像として使用してください。
以下のデザインを忠実に維持してください。
- 顔
- 耳
- 目の周囲の黒い模様
- 丸く大きな体形
- 白黒の毛並み
- 手足の太さ
- キャラクター全体の柔らかな水彩表現
- 青いリュック
特に、
青いリュックは必ず背負わせてください。
喜びのポーズによってリュックが消えたり、別の形になったりしないようにしてください。
アクション
パンタが、
「やったー!」と大喜びしている瞬間
を表現してください。
ただし、今回はジャンプアニメーションそのものを制作するのではありません。
パンタの足は地面についている状態にしてください。
ジャンプや上下移動はゲーム実装時にUnity側で行います。
そのため、画像内ではパンタ自身を空中に浮かせないでください。
喜びポーズのバリエーション
同じポーズを繰り返すのではなく、
身体の動きがはっきり異なる複数の喜びポーズ
を制作してください。
例えば、
- 両手を高く上げて大喜びする
- 両手を左右に大きく広げる
- 片手を高く上げ、もう片方の手を横に広げる
- 両手を胸の近くまで引き寄せ、うれしそうに力を込める
- 身体を少し左右どちらかへ傾けながら喜ぶ
- 胸を張って誇らしそうに喜ぶ
など、
シルエットを見ただけでも違いが分かるポーズ
にしてください。
重心の変化
単純に腕の形だけを変えないでください。
各ポーズで、
パンタの身体全体の重心を変化させてください。
例えば、
- 重心が中央
- 少し左脚側へ重心を移す
- 少し右脚側へ重心を移す
- 身体を少し左へ傾ける
- 身体を少し右へ傾ける
- 胸を張って上半身を少し伸ばす
など、
身体全体を使って喜びを表現してください。
ただし、
転びそうな極端な傾きにはしないでください。
ゲームキャラクターとして自然に成立する範囲にしてください。
足のポーズ
足の形もすべて同じにしないでください。
- 両足を自然に開く
- 片足を少し前へ出す
- 片足を少し横へ出す
- 膝を少し曲げる
- 左右どちらかの脚に重心を乗せる
など、上半身の動きに合わせて自然に変化させてください。
ただし、
両足の少なくとも一部は地面に接している状態
にしてください。
ジャンプしているポーズにはしないでください。
表情
パンタらしい、
非常にうれしそうな表情
にしてください。
表情にも少し変化をつけてください。
- 大きな笑顔
- 口を開けた満面の笑顔
- 口を閉じたうれしそうな笑顔
- 目を少し細めた笑顔
などを混ぜてください。
すべて同じ顔にしないでください。
ただし、パンタの顔そのもののデザインは変更しないでください。
籠について
籠は持たせないでください。
今回は喜びアクション専用素材です。
リュックについて
青いリュックは必須です。
パンタが腕を上げたり身体を傾けたりしても、リュックは背中に自然に装着された状態を維持してください。
背景
背景は完全な透明にしてください。
白背景、単色背景、森、地面、影、装飾などは描かないでください。
パンタだけの独立したゲーム素材にしてください。
重要事項
今回の目的は、
完成した連続アニメーションを一度に作ることではありません。
まず、
パンタの喜びを表現する、異なる複数のポーズ候補を制作すること
が目的です。
生成された候補を人間が確認し、その中からゲームアクションとして自然につながる3カット程度を選択します。
したがって、
無理に連続動作として整合させるより、それぞれのポーズの違いと表情の豊かさを優先してください。
禁止事項
- パンタのキャラクターデザインを変更しない
- 青いリュックを消さない
- 籠を持たせない
- どんぐりを持たせない
- 空中に浮かせない
- ジャンプさせない
- 全カットを同じポーズにしない
- 腕だけを変えて身体を同じ姿勢にしない
- 全カットを同じ表情にしない
- 背景を描かない
- 地面や影を描かない
- 文字を入れない
パンタらしい、見ているだけで「やったー!」という声が聞こえてきそうな、元気でかわいい大喜びのポーズを複数制作してください。
こうして、実装に必要なパンタの追加素材が揃った。
そして今回の制作によって、
「異なるポーズを作れ」と指示するだけではなく、何を変化させれば異なるポーズになるのかを言語化する。
という、画像生成AIによるゲーム素材制作の新たな方法も確認することができた。
次はいよいよ、これまで制作してきた素材をUnityへ持ち込み、実際のゲームとして動かしていく。
















