オブジェクトの範囲内に入ると既定のアクション(椅子に座る、ベッドに寝るなど)を行うキャラクターAIを作成します。
指定されたターゲットポイントを巡回するAIはすでにできているので、それに追加する形で作成します。
###【今から作るもの】
・キャラクター。何かがオーバーラップしたらタグが付いているか検知する関数を持つ。
・椅子。再生するアニメーションやアニメーションの再生時間、キャラクターの位置を合わせるための座標などを保持。
・AI。キャラクター付近に椅子があるかをチェックする。椅子を発見したら椅子に記録されたアニメーションを再生し、終わったらパトロールを再開する。
###【キャラクター】
まずはキャラクターを作成します。
メッシュにはあらかじめ歩行などをおこなうアニメーションBPをつけておきます。
ほかの動作をアニメーションモンタージュで再生した場合は一時的にその動作に上書きされますが、アニメーションモンタージュが再生停止されると再びにアニメーションBPが再生されます。
こちらはキャラクターに持たせたCheckOverlap関数です。
オーバーラップしたアクタがタグを持っているか調べています。
複数のアクタが同時にオーバーラップした時のために配列とForEachLoopを使用していますが、返される値は常に一つです。
(そのため椅子二つと同時に接触すると常に片方の椅子に座ります)
後ほど説明するAIのタスク内で呼び出して使用します。
###【椅子】
椅子です。
椅子には三つの変数を持たせてあります。
1.近づいたときに再生するアニメーションモンタージュ
2.再生する秒数
3.再生中と再生が終わった後にキャラクターのカプセルコンポーネント(コリジョン)をどこに置いておくか
3についてはアニメーション再生中にコリジョンがそのままだとカプセルが大きく弾き出されてしまうので、椅子の前にコリジョンだけ置いてあります。
###【AI】
まずこちらがビヘイビアツリーの全体になります。
右半分がアクタを検知しつつパトロールする部分です。
左半分は椅子などのアクタを検知した際にアクションを再生し、再生時間が過ぎれば停止させる部分です。
細かく見ていきます。
まずは右半分。
下の4つのタスクはパトロールポイントを巡回するものです。
重要なのは中央の部分。
Sequenceエリアに追加されているサービス(緑色)が定期的に呼び出されています。
中身はこちら。
キャラクターにキャストして関数を呼び出し、椅子などのアクタが返ってくればブラックボードキーにそのアクタがセットされます。
キーに何らかの値が入ると、ビヘイビアツリーの左側に実行が流れます。
Sequenceノードの上に追加されれているデコレーター(BlackboardBasedCondition)が定めた条件を満たしたため、左側のタスクが順番に実行されます。
今回は椅子に座るアクションのため、キャラクターを椅子の位置に動かして実行するため、まず左端の「MovingAction」が実行されます。
中身はこちらです。
長いですが、やっていることは
1.キャラクターにアニメーションモンタージュを再生させる
2.キャラクターのカプセル位置を椅子の前に移動させる
3.キャラクターのメッシュが椅子の中心に来るようにカプセルからずらす
くらいです。
アニメーションが終わった後で元の位置に戻すときのために座標などをブラックボードに保管したりもしています。
MovingActionタスクが成功したことでImmediateActionはスキップされ、WaitBlackboardTimeが実行されます。
こちらは椅子の持っている変数の秒数だけ待つタスクです。
これが終わればQuitActionです。
先ほど再生していたアニメーションモンタージュを停止し、キャラクターをカプセルの位置へ戻します。
実行するとこのような挙動になりました。
###【注意点】
カプセルの位置を変更できるように作成したActionLocation変数ですが、Z座標を変更するとカプセルが重力に従い落ちてきて床にめり込みます。
Zは0にしておくのが無難です...