UE4でのAIを設計するために必要なこと
UE4でAIを作るとき何をすべきか?
どうやればAIを作れるのかを解説したいと思います。
1,4コマまんがを描く
2,AIの構成要素
3、体の実装
4、センサー実装(視覚)
5,センサー実装(聴覚)
6,思考(ビヘイビアツリー)
4コマまんが風に描く
作りたいキャラがどんな動きをするのか、
絵にしてみましょう。
今回は3パターンに分けて描いてみました。
1,敵正面からプレイヤーが来る
2,敵背面からプレイヤーが攻撃
3,敵背面から来たプレイヤーが音を出す。
になります。
パターン1、正面から視野へ入る場合
パターン2、裏から回り込む場合
敵の裏側に自分(プレイヤー)が回りこみました。
この場合は視野に入らずに裏から攻撃できます。
パターン3、音を出してしまった場合
※実際には紙とペンだけで十分です。
実際に描く場合は紙とペンで十分です。
UE4を開く前にどのような動きにしたいのか絵を描きましょう。
AIの構成要素
下記のように分けます。
AIの置かれた環境
1. 体(敵)
2. センサー(目、耳、を持ちます)
3. 行動(攻撃、振り向き、追跡、帰還、)
AIの考えている事
1. 思考(ビヘイビアツリー)
2. 記憶(BlackBoard)
各項目を1つずつ実装する必要があります。
次章以降で「4コマまんが風に描く」で描いた絵を元に、
AIの置かれた環境、AIの考えていることを実装していきます。
体の実装
Mixamoのパッケージを使用しました。
https://www.unrealengine.com/marketplace/mixamo-animation-pack
Mixamoのアニメーションパックを開くと
全キャラクターのベースになっているActorに”MixamoCharacter_Master”が入っています。
コレをコピー&ペーストし、MixamoCharacter_Master_Enemyを作成します。
次にMixamoCharacter_Master_Enemyの下記BPを全て削除します。
これ等は全て人がキャラを操作するための物なので、AIには不要なものになります。
コレ全部削除
派生されたCharacterである「Mixamo_Jill」たんのParent class に先ほど作成した
"MixamoCharacter_Master_Enemy"に設定します。
このゾンビたん(Mixamo_Jill)を使用しました。
ゾンビたん(Mixamo_Jill)のParent class に設定します。
センサーの実装(視覚)
センサーは下記のようにサービス内での実装になります。
「BTPlayerFinder」というサービスが「視覚」を実装しているサービスになります。
処理完了後は”全体の流れ”の図の通りBlackBoardへ書き込みます。
基本的には公式チュートリアルのこれ
https://docs.unrealengine.com/latest/JPN/Engine/AI/BehaviorTrees/QuickStart/11/index.html
を参考に作成しました。
この処理だけだとキャラの周囲全て見てしまうので
http://www.sousakuba.com/Programming/gs_two_vector_angle.html
ここのページを参考に下記の処理を作成しました。
この関数は引数で
自キャラの座標
敵キャラの座標
自キャラの正面を示す単位ベクトル
を入力すると、自キャラの正面に対する敵キャラ位置の角度を計算してくれます。
センサーの結果はブラックボードへ書き込みます。
Targetが見つけたターゲット
TargetFindedが、ターゲットを見つけた状態の場合はTrueにします。
センサー実装(聴覚)
聴覚は通常のBPで実装します。
キャラの周りに聴覚エリア用のコリジョンを用意し、
コレにSoundObjectがOverLapした場合にBlackBoardへ書き込みます。
今回はプレイヤーがボタンを押すとSoundObjectをバラ撒くように設定しました。
結果はBlackBoardのSounded、SoundedPosへ書き込みます。
聴覚用コリジョンエリア
SoundObject
聴覚用コリジョンエリアにSoundObjectが接触した時にBlackBoardのSounded、SoundedPosへ書き込むよう設定します。
行動の実装について
今回は下記の行動を実装しました。
・追跡(UE4に標準で入ってる)
・振り向き
・帰還(UE4に標準で入ってる)
思考(ビヘイビアツリー)
ビヘイビアツリーは階層化されたステートチャートと認識して下さい。
ノードの一つ一つは全て何らかのステートであり、名前を付けられるように設計して下さい。
下の図はUMLで言う所のステートチャートの区切りを赤枠で囲った図です。
ビヘイビアツリーは階層型ステートチャートなので下図のような形で、ステートの中にステートチャートが入っている構造になります。
ビヘイビアツリーのステートチャートは下記の「IsNumEqual」デコレータで作成します。
「ブラックボードの数字」と「設定した数字」が同じ時、trueを返します。
非常に簡単なデコレータですが、最重要デコレータになります。
ブラックボード内の「stMain」が「メインのステート遷移」のステート番号を管理しています。
例えば「待機中=0」「探索中=1」「特攻中=2」と言った形で番号を振り、
デコレータの「IsNumEqual」でステート遷移を作ります。
stMainがメインのステート遷移を維持しています。
尚、stCautionは作る予定で間に合わなかった残骸です。
※なお、このやり方は我流です。
どっかのお手本とか参考にしてないのでセオリーではない可能性が高いです。