ゲームAI・人工生命

(MindRender, Unity)

課題内容

以下の課題から,1つを選択します.


車の自動運転AIを作成し,最終日にトーナメント形式で対戦を行い順位を付けます.

参考:教科書(3.8節)「自動運転学習で競争しよう」

最終日のコース・ルールなど


教科書の演習問題の中から,★★,もしくは★★★のものを1つ以上選んで解きます.


Unityを使って,ゲームAI・人工生命の面白い応用を創ります.


制限

本演習の目的は,AI・人工生命を自分で創って理解することであるため,ML-Agentsの使用は原則禁止です.ただし,ML-Agentsの低レベルAPIを使用して,アルゴリズムを自分で実装する場合は,この限りではありません.使用を検討している人はTAに事前に必ず相談してください.

環境セットアップ

教科書やセットアップ時のトラブル例を参照してください.

サンプルプログラムのダウンロード

自動運転の対戦には,本演習用に整備したプログラムを使用するため,こちらからダウンロードしてください.

自動運転・対戦プログラム 


教科書に載っているサンプルプログラムは,

教科書の書籍サポートのページ:http://www.iba.t.u-tokyo.ac.jp/software/AIAL/index.html

からダウンロードできます.プログラムの詳細は教科書を参照してください.


その他,教科書に載っているもの以外にも提供可能なサンプルプログラムがいくつかあります.

その他提供可能なプログラムのリスト

Unityスクリプトについて(初心者向け)

UnityのスクリプトはC#で書きます.Unity上でスクリプトを実行するには,まず,MonoBehaviourというクラスを継承したクラスを作成することになります.


MonoBehaviour

UnityエディタのProjectタブで右クリック→Create→C# ScriptとするとMonoBehaviourを継承した空のクラスを作成できます.

作成したクラスにはStartとUpdateの関数(空)が定義されていると思います.これらは特別な関数(イベント関数)で,Unityシーンの実行時に特定のタイミングに呼び出されます.


Start

MonoBehaviourのStart関数は,シーン実行の最初のフレームの前に呼び出されます.初期化処理などはここに書きます.

同様なイベント関数にAwakeというものがあります.AwakeはシーンがロードされたときにStartよりも先に呼び出さます.他のオブジェクトのStartよりも前に実行したい初期化処理はAwakeに書きます.

下のように書くとシーンの開始時にUnityエディタのConsoleタブに"Start!"と出力されます.

void Start() {

    Debug.Log("Start!");

}


UpdateとFixedUpdate

MonoBehaviourのUpdate関数は,毎フレーム1回呼び出されます.フレームレートによって,呼び出される間隔は変動します.

対して,FixedUpdate関数は,シーン内時間で一定の間隔で呼び出されます.すべてのオブジェクトのFixedUpdateの実行後にUnityの物理演算が走ります.

車の制御など物理演算が絡む処理はFixedUpdateに書きます.


参考:その他のイベント関数

上で紹介した以外にも,OnCollisionEnter(物体との衝突時に呼び出し)など,様々なイベント関数があります.

他のイベント関数のリストやその実行順序については以下を参照してください.

MonoBehaviourスクリプトリファレンス:https://docs.unity3d.com/ja/2021.3/ScriptReference/MonoBehaviour.html

公式マニュアル・イベント関数の実行順序:https://docs.unity3d.com/ja/2021.3/Manual/ExecutionOrder.html


スクリプトをオブジェクトにアタッチ

MonoBehaviourを継承したスクリプトを作成しただけでは,実行されません.シーン上のオブジェクトにアタッチする必要があります.

シーン上のオブジェクトを選択してから,Inspectorタブの一番下のAdd Component→Scriptsから作成したスクリプトを選択するとアタッチできます.

(Projectタブから作成したスクリプトをドラッグ&ドロップでも可能です.)


Inspectorタブからフィールドの値を変更する

[SerializeField]を付けたフィールドやpublicなフィールドはUnityエディタのInspectorタブで値を変更することができます.

注意:Inspectorタブで値を変更すると,コード上の初期値とシーン実行時の初期値が異なってきます.

例えば,

[SerializeField] private int number = 0;

とコード上で定義されているとき,コードを眺めただけだとnumberの初期値は0ですが,このスクリプトをアタッチしたオブジェクトのInspectorタブで違う値に設定した場合,例えば5に設定したとすると,numberは5として実行されます.

また,numberをInspectorタブで5に設定した後,コードの方で

[SerializeField] private int number = 123;

と初期値を変更したとしても,シーン上のオブジェクトには反映されません(5のまま).numberの値は常にInspectorタブで見えているものが使われるので,コードを読む際には注意してください.


参考:詳しい説明

スクリプトについてのもう少し詳しい説明は公式マニュアルを参照してください.

Unityユーザーマニュアル/スクリプト:https://docs.unity3d.com/ja/2021.3/Manual/ScriptingSection.html

スクリプトリファレンスも参考になります.

Unityスクリプトリファレンス:https://docs.unity3d.com/ja/2021.3/ScriptReference/index.html