BehaviorTree でのMoveToタスクのカクつきを緩和してみる
お久しぶりです。ごりです。
1年ぶりの投稿です。
先日UE4勉強会in大阪(https://ue4study-osaka.connpass.com/event/93325/)にて
EQSについて講演してきました。
そのときに、BehaviorTreeのMoveToタスクについてのカクつきについて
質問があったので今回はそれについての記事にな
ります。
1年前の記事になりますが、このEQSを使って解説していきます。
準備としてBlackBoardKeyにVectorのDestination を追加しておいてください。
ここにEQSで計算した目標地点を格納します。
カクつくパターンのBehaviorTreeとして、以下のようにしました。
RunEQSQueryタスクにRandomWalk、BlackboardKeyにDestinationを設定します。
MoveToタスクの Blackboard keyにDestinationを設定します。
これで実行してみると...
カクついているのがわかると思います。
この対処法について、サービスで目標地点の近くにきたら目標地点を更新するという手法を提案しました。
そのサービスに中身について見ていきます。
BehaviorTreeの上部にある[新規サービス]からBTService_BlueprintBaseをクリック、新しくサービスを作成します。
作成したサービスの名前は UpdateDestinationとします。
サービスの更新間隔は以下のように設定してください。
新しく作成したサービスを開くと、イベントグラフには何もありません。
まずはカスタムイベントでEQSを実行するイベントを作成します。
RunEQSQueryノードでランダムウォークを設定し、
EQSの計算終了時に、目標地点をBlackBoardKeyに格納と目標地点までの距離を計算しています。
カスタムイベントを追加だけでは実行されません。
関数のオーバーライドから ReceiveSearchStartAI を選択します。
RecieveSearchStartAIではEQSの実行を行います。
今回の実装ではこのイベントは一回だけ呼ばれます。
次に関数のオーバーライドから RecieveTickAI を選択します。
RecieveTickAIでは残りの移動距離をチェックし一定の比率以下になったら目標地点を更新するようにしています。
これでサービスは完成です。
BehaviorTreeのRunEQSタスク削除し、以下のように設定しなおします。。
またMoveToの設定で BlackboardKey下の
Observed Blackboard Value Tleranceを有効にする必要があります。
これで実行すると...
カクつきが緩和されたと思います。
それとBehaviorTreeがすっきりしましたね。
この手法以外にもカクつきをなくす方法はあると思います。
みなさんもいろいろ試してみてください。
間違っている点などありましたら、ご指摘いただけるとありがたいです。
ではまた。
EQSでランダムウォーク
こんばんは、goolee(ごり)です。
今日はEQSを用いたランダムウォークについて。
ランダムには動いているので、良しとしました。
では「EQS_RandomWalk」の名前のEQSを作ります。
今回用いたGenerator は「Circle」Generator です。
変更する部分は円の半径、生成するアイテム間の距離、トレースモードの3つです。
今回は
円の半径を300 。
生成するアイテム間の距離を DataBinding の設定を 「Randomnumber」 で
最小値を「100」最大値を「400」。
TraceData のTraceMode を 「None」にしました。
アイテム間の距離をランダムにすることで、プレイヤーの正面にアイテムが生成されない場合を作り、これによって前に進み続けて行きどまりになったら方向転換という動きだけにならないようにしました。
TraceModeを「None」にした理由ですが、
TraceModeが「Navigation」のままだと目の前に壁があると、壁の手前にアイテムが生成されてしまい、トレースのテストに影響が出てしまうと考えました。
なので「None」にして目の前に壁があっても壁の奥にアイテムが生成されるようにしました。
次に今回行ったテストは
・現在向いている方向にある点かどうか
・視界にはいっているかどうか
・到達可能かどうか
の3つです。
まず 現在向いている方向にある点かどうか です。
これには 「Dot」テストを行います。
変更する部分はTestPurposeを「ScoreOnly」に変えるだけです。
これは数学の内積ですね。
プレイヤーが向いている方向ベクトル(赤色)と
プレイヤーからアイテムまでのベクトル(青色)で内積を行っています。
赤色と青色の矢印のなす角度Θが小さいほど内積の値は大きくなります。
つまり内積の値が大きくなるほど、向いている方向のアイテムになるということです。
では次に 視界にはいっているかどうか です。
これは前回書いた記事で行った 「Trace」テストを行います。
TestPurposeを「FilterOnly」にし Boolの一致のチェックをはずします。
最後に 到達可能かどうか です。
これには 「PathFinding 」のテストを行います。
これはアイテムまでの移動経路があるかどうかを判断してくれます。
変更する部分は TestPurposeを 「FilterOnly」に変えるだけです。
これでランダムウォークのEQSは完成です。
あとはこのようなビヘイビアツリーを作成すれば動きます。
移動のタスクは自作のものを使用していますが、「MoveTo」のタスクでも動くと思います。
実際に動かした動画がこちらになります。
なにかおかしな点ありましたらコメントお願いします。
ではまた。
EQSで簡単な敵の探索をしてみる
お久しぶりです。ごりです。
今日は簡単な敵探索をEQSを使って実装したいと思います。
まず「EQS_FindEnemy」の名前のEQSをつくります。
今回使うGeneratorは 「ActorOfClass」です。
半径はお好みで設定。今回僕は半径1000で行っています。
探索する相手クラスを「BP_Enemy」としています。
とりあえず現状でEQSを実行すると以下のようになります。
赤色を探索を行うキャラクター、青色を敵キャラクターとしています。
敵キャラの位置にアイテムが生成されていることがわかります。
このアイテムの中からテストを行って一つの敵キャラクターに絞っていきます。
今回僕が行ったテストは
・プレイヤーから一番離れている敵
・プレイヤーから見える敵
の2つです。
まずプレイヤーから一番離れている敵のテストを実装していきます。
テストの中から「Distance」を選択。
TestPurposeを「ScoreOnly」にするだけです。
今回は一番離れているてきなので。SocringEquationを「Linear」のままにしていますが、
一番近い敵を探索したい場合は「InverseLinear」を使うと良いです。
設定し終わるとこのようになります。
プレイヤーから離れるほど大きなスコアがついています。
では次にプレイヤーから見える敵のテストです。
これは「Trace」のテストを追加します。
TestPurposeを「FilterOnly」にし、
「Boolの一致」のチェックを外します。
これだと正しく計算されているかわからないので障害物をおいてみます。
プレイヤーから見えない敵キャラはスコア計算対象外となっていますね。
これで簡単な敵探索のEQS完成です。
このようなビヘイビアツリーを作成して動かすとこのように動きます。
ここ間違ってるなどありましたらコメントお願いします。
次回はランダムウォークでも作成したいと思います。
ではまた。
ウィジェットブループリント内でゲームパッドの入力をとれるようにした
どうも、ごりです。
今日はウィジェットブループリント内でのゲームパッドの入力の取り方を
僕なりにやってみました。
まずブループリントクラスを作成のところから、「ブループリントマクロライブラリ」を作成を選択して
親クラスは 「UserWidget」 で作成します。
名前は 「 GamePadInputMacroLibrary 」 とします。
今回はゲームパッドの左サムスティックで上下左右の入力とAボタンで決定するといった入力を取得したいと思います。
作成したマクロライブラリを開いて
まず右側の+マークをクリックして
「L_ThumStickY」「L_ThumStickX」「Button_A」と3つマクロを用意します。
「L_ThumStickY」で説明します。
インプットに実行ピンを追加し名前を「Execute」
アウトプットピンに実行ピンを3つ追加し、「Up」「Down」「Neutral」とします。
次から処理になります。
「GetPlayerController」ノードから「Get Inpur Analog Stick State」を取得します。
Witch Stick は 左スティックなので 「CAS Left Stick」のままでいいです。
僕はサムスティックをある程度傾けた時に入力判定を取りたいので
閾値の絶対値を 0.9にしています。
あとはStickYの値が閾値以上の場合は「Up」に
閾値以下の場合は「Down」に
それ以外は「Neutral」につなげばこれで完成です。
「L_ThumStickR」も同じように作ります。
次は「Button_A」についてです。
インプットには 実行ピンで「Execute」
アウトプットには 実行ピンで「Pressed」「NotPressed」
を追加します。
先ほどは「GetPlayerController」から「GetInputAnalogStickState」を取得していましたが、今度は「IsInputKeyDown」を取得します。
最後に ReturnValueが True なら Pressed
False なら Released につなげば 完成です。
あとは、入力を取得したいウィジェットブループリント内の
イベントティックに以下のようにつなげば入力を取得することができます。
これは毎フレーム判定しているので、InputAxis のような動作になります。
InputActionのようにしたい場合は、
このように DoOnce を使えば InputAction のようにすることもできます。
今回はマクロライブラリを使っての取得でしたが、
マクロライブラリを使わずにウィジェットブループリント内の仕組みで、取得する
方法があるみたいなので、いつかそれについてもやってみたいと思います。
これ間違っている、こうしたほうがもっと簡単などあれば
コメントお願いいたします。
キングダムハーツっぽいHPバー作ってみました。
お久しぶりです、ごりです。
今日は少し余裕があったので、マテリアルの勉強がてら
キングダムハーツのHPバーっぽいUIを作ってみました。
中身はまだ汚いので、きれいにしたら記事にするか、
プロジェクトごとあげるかします。
ではでは。(*- -)(*_ _)ペコリ
UE4でキングダムハーツのHPバー作ってみました。
— goolee (@goolee07) 2016年11月3日
マテリアル初いじりだったけど結構上手くいった! pic.twitter.com/jlzaw4me6G
UE4のVRテンプレートやってみました。
ごりです。
今更ですが、
UnrealEngine4のVer.4.13からVRテンプレートが追加されたので、
Viveでやってみました。
興味があった物を掴む処理の中身見ていきたいと思います。
まず入力のところから
プロジェクト設定-インプット を見ると、
トリガーを使うみたいです。
次にこの入力イベントを呼んでいる
コンテンツ-VirtualRealityBP-Blueprintsの中にある
「MotionControllerPawn」を見てみます。
アクションイベントを呼び出すと
コンテンツ-VirtualRealityBP-Blueprintsの中にある
「BP_MotionController」内の「GrabActor」「ReleaseActor」という関数を
呼び出しているみたいです。
この2つの関数が物を掴む、離す処理っぽいです。
まず「GrabActor」関数から
「WantstoGrip」という変数は手のアニメーションを握る状態か開く状態かを
使用する変数みたいで、
Trueの時に握って、Falseの時に離すようです。
次に「GetActorNearHand」関数は手に一番近いアクターを取得します。
しかしこの「GetActorNearHand」関数は
コンテンツ-VirtualRealityBP-Blueprints の中にある
「PickupActorInterface」というインターフェースを実装した
アクタークラスのみを取得するみたいです。
インターフェースについてはこちらの記事がすごくわかりやすいです。
アクターが取得出来たらリファレンスを保持して「PickUp」関数を呼び出ています。
この「Pickup」関数はアクター側の掴まれたときにどうするかの
処理になっていますね。
コンテンツ-VirtualRealityBP-Blueprints の中にある
「BP_PickupCube」がこのインターフェースを実装しているみたいなので
中身を見てみると、
アクターの物理シミュレーションを止めて、BP_MotionController に取り付けているようです。
「PickupActorInterface」を実装したアクターにこの処理をかけば、物が掴めるようになりそうですね。
次は「ReleaseActor」関数の中身です。
手の情報と掴んでいるものが取り付けられている親の情報が一致したときに
インターフェースの「Drop」関数を呼んでいるようです。
物理シミュレーションを再開し、親から外す処理のようですね。
以上がテンプレートの中の物を掴む処理となっています。
物を追加したいときは「BP_PickupCube」を複製してMeshを変えたら手っ取り早くすみます。
ただ「BP_PickupCube」は親クラスがStaticMeshActorになっているので
スケルタルメッシュを使いたい場合は親クラスがSkeltalMeshActorかアクター
にしてください。
試しに椅子を追加してみました。
UE4.13のVRテンプレートいじって椅子追加してみた pic.twitter.com/3adMwg9JO6
— goolee (@goolee07) 2016年10月29日
初投稿なのと、自分で考えてやっているのでおかしなとこあれば
コメントください。
次回はVR空間で弓矢を打てるようにしたいと思います。