戦闘ロボットシミュレータ

概要

1. シミュレータ環境構成

1.1. シミュレータ本体

シミュレータ本体はUnity を使って開発しています。 現時点ではWindows 版のバイナリのみ配布しています。  このシミュレータ環境の所定の場所にプラグインのDLLを配置すると、プラグインで記述されたプログラムに基づいて各ユニットが行動します。 賢いプログラムを記述し、敵ユニット郡を上手に殲滅させて下さい。

1.2. AIプラグイン

2種類のインターフェースを実装したクラスを作成して下さい。

1.3. AIInterface

まず、ユニットが生成された直後にSetup メソッドがシミュレータから呼び出されますので、ここで初期化処理を実施して下さい。初期化処理が終わったら、どの種類のユニットを生成したのか、ユニット種別をUnitType 値として戻り値にして下さい。

続いて、定期的な更新処理としてUpdate メソッドがシミュレータから呼び出されます。呼び出される時間間隔は不定ですので、UnityEngine のTime.deltaTime を参照して、前呼び出しからの経過時間を取得し、適切な制御を実施して下さい。自機の情報としてSelfInfo のインスタンスを、検出できた他のユニットの情報をOtherInfo インスタンスのリストとして引数で受け取ります。他のユニットを検出できる範囲はユニット種別によって異なります。制御を終えたら、進行スピードや向き、攻撃の状態などを設定したNextTask のインスタンスを生成し、このインスタンスを戻り値として返して下さい。NextTask インスタンスに基づいて、シミュレータがユニットの状態を更新します。

ユニットが消滅する直前にはTerm メソッドが呼び出されますので、例えばログファイルのクローズ処理といった終了処理を記述して下さい。


public interface AIInterface{

    /// @brief 初期化する。どのタイプのユニットであるかを戻り値として返す。
    /// @return ユニットの種別
    UnitType Setup();

    /// @brief ターン毎の状態更新を行う。
    /// @param me 自身の情報
    /// @param other 自機以外の情報。検出されたものだけがリストの要素として渡される。
    /// @return 自機の更新情報
    NextTask Update(SelfInfo me, List other);

    /// @brief 終了時の処理を行う。
    void Term(); 
}

1.3.1. UnitType

ユニットの種別を示します。 Setup メソッドによりユニットを生成するときにはUnknown は使わないで下さい。 (使うと、今の仕様では強制的に偵察兵扱いになります)。 Setup メソッドで返したユニット種別にあわせて、シミュレータはユニットの外観を決定し、戦闘時における移動や攻撃の特性を反映させます。


public enum UnitType
{
    Unknown, /// 不明
    Scouter, /// 偵察兵
    Fighter, /// 突撃兵
    Sniper, /// 狙撃兵
}

1.3.2. SelfInfo

Update メソッドで制御を実施する時に参照する自ユニットの情報です。 2017年1月時点ではhead_forward は使わないで下さい。攻撃方向=進行方向なので、forward を参照して下さい。


public struct SelfInfo
{
    public bool active; // true の場合、稼働中であることを示す
    public int life; /// 残りライフ
    public Vector3 position; /// 現在位置(絶対座標。単位はメートル)
    public Vector3 forward; /// ボディの正面方向のベクトル。移動に影響する。
    public Vector3 head_forward;    /// 頭部の正面方向のベクトル。攻撃に影響する。
    public Vector3 up; /// ボディの上方方向のベクトル。

    public float front_distance;    /// 正面方向の障害物までの距離。負の値の場合は障害物を検知できず。
    public float right30_distance;    /// 右斜め前30度方向の障害物までの距離。負の値の場合は障害物を検知できず。
    public float left30_distance;    /// 左斜め前30度方向の障害物までの距離。負の値の場合は障害物を検知できず。
    public float under30_distance;    /// 正面斜め下30度方向の障害物までの距離。負の値の場合は障害物を検知できず。
    public int invisible;   /// 攻撃を受付けない状態の時はtrue である
}

1.3.3. OtherInfo

検出できた周囲の敵・味方・中立ユニットの情報です。Update メソッドにはこのインスタンスのリストが渡されます(検出できなければリストの要素数は0)。

is_enemy は特に注意して下さい。味方を検出していた場合、攻撃すると同士討ちに なります。

また、unit_type と、自分・相手の位置・向き関係とを確認することで、敵から検知されているかどうかを判断する目安となり、適切な戦術立案に役立てることが出来ます。


public struct OtherInfo{
    public float distance;  /// 相手ユニットまでの距離(単位はメートル)
    public float vertical_direction;    /// 自分から相手への垂直方向の向き. 単位はラジアン。右向きが正
    public float horizontal_direction;    /// 自分から相手への水平方向の向き. 単位はラジアン

    public Vector3 forward;	/// 頭部の正面方向のベクトル
    public Vector3 up; 	/// 頭部の上方方向のベクトル

    public CovorInfo cover; /// 相手までの間に障害物があるかどうか
    public UnitType unit_type; /// 相手ユニットの種類
    public EnemyFriendInfo is_enemy; /// 敵・味方を区別するためのタグ   
}

1.3.4. NextTask

Update メソッドの戻り値の型です。 このインスタンスのメンバをそれぞれ設定することでのみ、ユニットの制御が可能です。

roller_mode がfalse の場合、4足歩行モードになります。angular_accel を0.8 以上にすると右に横移動、-0.8 以下だと左方向に横移動します。それ以外の場合は旋回します。

roller_mode がtrue の場合、車輪走行モードになります。横移動はできなくなりますが、走行スピードが通常の倍になります。


public struct NextTask
{
    public bool active; /// true の場合、稼働中である。false にして非稼働にすると、攻撃は受けるが、敵から感知されなくなる。
    public bool roller_mode; /// true の場合、ローラーモードに変形。移動速度は倍になるが、真横への移動ができなくなる。
    public float accel; /// アクセルの強さ。0.0f ~ 1.0f で指定。
    public float angular_accel; /// 旋回の強さ。0.0f ~ 1.0f で指定。
    public bool shot; /// 攻撃中の場合はshot をtrue にする。但し、装填中などで発射できるとは限らない。
}

1.3.5. CovorInfo

OtherInfo に含まれるメンバ変数の型の一つです。 検出した相手との間に障害物があるかどうかを示します。


public enum CovorInfo
{
    Unknown,    /// 不明
    Covor, /// 障害物有り
    NoCovor, /// 障害物無し
}

1.3.6. EnemyFriendInfo

OtherInfo に含まれるメンバ変数の型の一つです。 敵・味方を区別します。



public enum EnemyFriendInfo
{
    Unknown, /// 不明
    Friend, /// 味方
    Enemy, /// 敵
    Newtral, /// 中立
}

2. シミュレータ本体

プラグインの開発環境はこれから追加していきます。。。
ダウンロード概要

シミュレータの初期試作版です。とりあえず動くかどうかを確認するレベルのもの。

3. 紹介動画