ゲーム内情報の取得 #2
#1 では Map Scanner を動かすのに必要な最低限の対応を行いました。 ここではさらに以下のようなゲーム内情報を取得する処理を実装します。
- プレイヤーキャラクターを実装されたアクションを駆使して上手に操作するための情報
 - 周囲の敵キャラクター、アイテムの位置など、動的に配置/移動するアクターの情報
 - その他デバック機能など、通しプレイでゲームを攻略していくのに必要となる情報
 
ゲーム固有のプレイヤー情報
プラグインで提供しているサブレベルでは、以下のような様々なゲームで共通して使えるであろう情報のみを収集、外部に送信しています。
- プレイヤーの位置 (x, y, z)
 - プレイヤーの向き (roll, pitch, yaw)
 
{
    "Player":
    {
        "Location": {"X": 00.00, "Y": 00.00, "Z": 00.00},
        "Rotation": {"Roll": 00.00, "Pitch": 00.00, "Yaw": 00.00}
    }
}
「プレイヤーを目標の座標に直線移動させる」というような単純な制御をするだけであればこれだけで十分かもしれませんが、多くの場合はより複雑な操作を行う必要があります。
例えば、障害物を飛び越えるためのジャンプ、レベル上に配置されたギミックを動作させるための特殊なアクションが必要になることが考えられます。
そこで、各ゲームごとに追加でゲーム固有のプレイヤー情報の収集を実装する必要があります。
プレイヤーキャラクターの情報全てが必要になることは稀です。 自動プレイ (特に Playthrough Tester) の実行に必要となる情報に限定して取得を行うとよいでしょう。
敵に関する情報
通しプレイなどで周囲にいる敵を倒すためには、どこに敵がいるのかを知る必要があります。
存在する全ての敵キャラクターの情報を収集するのは通信するデータ量が多くなり、好ましくありません。 プレイヤーを中心に一定距離以内の敵キャラクターの情報だけを収集するとよいでしょう。
アイテムに関する情報
Playthrough Tester などで敵が落とすドロップアイテムなど動的に生成されるアイテムを入手するには、どこにアイテムがあるのかを知る必要があります。
敵に関する情報と同様に、プレイヤーを中心に一定距離以内のアイテムの情報だけを収集するとよいでしょう。
デバッグ機能に関する情報
デバッグ機能関連で、自動テストプログラム側が状態を把握したい場合があります。 デバッグ機能は各ゲームで個別に実装している場合が多いため、ゲームごとの対応が必要になります。
デバッグ機能は大抵デバッグメニューに列挙されているか、別途コンソールコマンドのリストが管理されているでしょう。 そのため、デバッグメニューの実装から辿ったり、コンソールコマンドの実装から必要な情報を読み取る方法を特定するとよいと思います。
サンプルゲームでの実装例
ゲーム固有のプレイヤー情報
サンプルゲームでは追加で以下の情報を収集しています。
- 現在落下中 (接地していない) か? … bool
 - ジャンプ可能か? … bool
 - 無敵状態か? … bool
 
{
  "Alfort": {
    "Player": {
      "IsFalling": false,
      "CanJump": false,
      "Invincible": false
    }
  }
}

Unreal Engine の場合、PlayerCharactor は GetPlayerPawn の返り値をキャストすることで参照可能になります。
これを利用して取得したプレイヤーアクターをキャストしてから取得したいパラメーターを探して取得しています。
なお、プレイヤーの状態はアニメーションステートで管理している場合があるので、場合によってはそちらを参照する必要が生じるかもしれません。
敵に関する情報
サンプルゲームでは、プレイヤーの周囲 1500(15m) 以内の敵の以下の情報を収集しています。
- キャラクターの位置 (x, y, z)
 - ヒットポイント … int
 - キャラクター名 … 文字列
 
キャラクター名は一意ではありませんが、個体識別に利用しています。
{
    "Alfort":
    {
        "Enemies":
        [
            {
                "Location": {"X": 00.00, "Y": 00.00, "Z": 00.00},
                "HP": 200,
                "Name": "Hoge1"
            },
            {
                "Location": {"X": 00.00, "Y": 00.00, "Z": 00.00},
                "HP": 200,
                "Name": "Fuga2"
            }
        ]
    }
}

敵キャラクターは一般的にレベルに静的に配置されず、ゲームプレイ中に動的に生成され、倒せば破棄されるような仕様になっています。
そのため、以下のような処理を逐次実行することで現在レベル上に配置されている敵キャラクターを列挙するようにしています。
- 敵キャラクターの基底クラスを指定した 
Get All Actors of Classノードで全ての敵を列挙Get All Actors of Classはコストの高い処理なので、別の方法で敵の情報を取得できるのであればそちらを使用
 - 列挙した全ての敵キャラクターの内、プレイヤーとの距離が一定未満のものだけをピックアップ
 - 敵キャラクターの情報を収集
 
アイテムに関する情報
サンプルゲームではアイテムオブジェクトは静的に配置された宝箱のみなので、動的に情報を収集する必要はありません。 しかし敵がドロップアイテムを落とす場合を追加実装する場合も考慮し、敵と同じように周囲のアイテムの情報も収集するようにしています。
サンプルゲームでは、敵に関する情報と同様にプレイヤーの周囲 1500(15m) 以内のアイテムの以下の情報を収集しています。
- アイテムの位置 (x, y, z)
 - 回収済みか? …bool
 
{
    "Alfort":
    {
        "Treasures":
        [
            {
                "Location": {"X": 00.00, "Y": 00.00, "Z": 00.00},
                "Activate": false
            },
            {
                "Location": {"X": 00.00, "Y": 00.00, "Z": 00.00},
                "Activate": true
            }
        ]
    }
}

デバッグ機能に関する情報
サンプルゲームでは、マップを切り替えた際にデバッグメニューで ON/OFF 可能な項目がリセットされる(自動テストプログラム以外が設定を変える)仕様です。 適切に設定が行えるよう以下の情報を収集しています。
EnemyAI停止の ON/OFF … bool
{
  "Alfort": {
    "EnableEnemyAI": false
  }
}
