GameplayEffect - その1 GameplayEffect と Application 編
こんにちは、ごりです。
今日はGameplayEffectに関しての説明です。
Effectと聞くと火を出したりといった見た目の影響を想像する人が多いですが、
今回は内部のパラメータに影響を与えるといった意味で用いられる機能です。
カテゴリだけで9個あります。
設定項目が多いので複数回に分けて書いていきたいと思います。
その中から、今回はGameplayEffect,Application について
説明していきたいと思います。
まず、GameplayEffectについて
- DurationPolicy
パラメータに影響を与える時間を設定できます。
Instant : Effectが適用された瞬間に一度だけパラメータに影響を与えます。
Infinite : Effectが適用されてから取り消されるまでの間、
永続的に影響を当てます。
HasDuraion : Effectが適用されてから一定時間パラメータに影響を与えます。
Infinite,HasDuration にすると Period というカテゴリが追加されます。
Period : ここで指定した数値秒ごとに、パラメータの値が変更されます。
Execute Periodic Effect on Application : ここの値がfalseだと値が変更されるのは
指定秒経ってからになります。true の場合は 適用されてすぐに値が変更され、
指定秒経ったらまた値の変更がされるようになります。
デフォルトでは true になっています。
- Modifiers
Modifiersはパラメータに与える数値の変化量を設定できます。
Attribute : 影響を与えるパラメータです。
AttributeSet(そのうち記事にします) にある値を指定できます。
ModifierOp : 影響を与える際の値の計算方法です。
Modifier Magnitude : パラメータの変化量
SourceTags : パラメータに影響を与える発生源となったもののタグ
Required Tags : ここで指定されたタグが全てあれば、対象に影響を与える。
Ignore Tags : ここで指定されたタグが全てあれば、対象に影響を与えない。
TargetTags : パラメータに影響を与える対象となったもののタグ
Required Tags : ここで指定されたタグが全てあれば、対象に影響を与える。
Ignore Tags : ここで指定されたタグが全てあれば、対象に影響を与えない。
- Executions
Executionsは独自の計算方法を設定できます。
Calculation Class :
GameplayEffectExecutionCalculation クラスを継承した、独自の計算クラスです。
Conditional GameplayEffects :
Effect Class : ここで指定した計算式でパラメータへの影響に成功した際に
対象に適用するGameplayEffect
Required Source Tags : 発生源にここに指定されたタグがあれば対象に適用する
- ConditionalGameplayEffects
Effect Class : このGameplayEffectが適用された際に
対象に適用する別のGameplayEffect
Required Source Tags : 発生源にここに指定されたタグがあれば対象に適用する
続いて、Apllication についてです。
- Chance to Apply to Target
このGameplayEffectを適用させる確率、1の場合は必ず適用
- Execute Periodic Effect on Application
GameplayEffectCustomApplicationRequirement クラスを継承して、
適用可能かどうかの判定方法を設定できます。
以上が、設定項目 GameplayEffect、Applicationの説明になります。
また、間違っている点ありましたら、ご連絡いただけると幸いです。
ではでは。
GameplayAbility - タグ編
お久しぶりです、ごりです。
3連休ですが家に引き込まって記事書き続けます。
今日は GameplayAbility についてです。
こちらは4.20から追加されたUE4のSampleプロジェクトのActionRPGで
使用されている機能ですね。
今日は使い方というよりも、設定項目の説明になります。
使い方を知りたい方は
おかわりはくまいさんがすごくわかりやすく解説していますので、
以下の記事を参考にしてください。
okawari-hakumai.hatenablog.com
アビリティを作成した際の、Default設定のこちらのTagsの項目についての説明です。
- Ability Tags
こちらのノードで、アビリティを実行するためのタグになります。
- Cancel Ability with Tag
ここに設定されているタグと一致していて、実行中のアビリティはすべて、
中断されます。
- Block Abilities with Tag
ここに設定されたタグと一致しているアビリティは、このアビリティを実行中には、
実行されません。
- Activation Owned Tags
このアビリティが実行されると、ここに設定されたタグを持ちます。
- Activation Required Tags
このアビリティを実行するためには、ここで設定されたタグを持っている
必要があります。
- Activation Blocked Tags
ここで、設定されたタグを持っていると、このアビリティは実行されない。
ここから下の設定項目は [ TryActivateAbilityWithTag ]ではなく、
別の呼び出し方法にかかわってきます。
こちらのノードを使う際 Payload というピンがあります。
こちらはGameplayEventDataという構造体になっています。
この構造体を作成する中に、
Instigator Tags, Target Tags がありますので、ここに設定したタグが
かかわってきます。
- Source Required Tags
Instigator Tags に設定されたタグが、ここに設定したタグに含まれていたら、
このアビリティが実行されます。
- Source Blocked Tags
Instigator Tags に設定されたタグが、ここに設定したタグに含まれていたら、
このアビリティが実行されません。
- Target Required Tags
Target Tags に設定されたタグが、ここに設定したタグに含まれていたら、
このアビリティが実行されます。
- Target Block Tags
Target Tags に設定されたタグが、ここに設定したタグに含まれていたら、
このアビリティが実行されません。
以上が、GameplayAbility のTagsの説明になります。
まだDefaultの設定の中には、別の設定項目もあるのですが、
GameplayEffect というのが関わってきますので、今日はここまでにします。
GameplayEffectについては明日書かせていただきます。
一通りの説明が終わったら、GameplayAbilityを使って作った簡単な機能の
プロジェクトを公開したいですね。
また、今回の説明で間違っている点などありましたら、連絡していただけると
ありがたいです。 ではでは。
空中を歩くAIをつくってみる
こんばんは、ごりです。
2か月ぶりの更新です。
今回は飛行AIを作ってみたいと思います。
ナビメッシュだと地上のAIには使えるのに空中にいるAIには使えないんですよね...
上記のようなプラグインも出ているみたいですが、
今回はこのプラグインを使わずに作っていきたいと思います。
そしてナビメッシュも使いません。
UE4をやっている人なら一度は見たことのあるこのノードを使います。
これをつかってビヘイビアツリーのMoveToタスクを作ると、空中のキャラクターも動いてくれるようになります。
作り方は、まずビヘイビアツリーの
[新規タスク]のBTTask_BlueprintBase をクリックして、新しくブループリントクラスを作ります。
クリックするとビヘイビアツリーと同じフォルダに
こいつが作られるので、名前を BTTask_CustomMoveTo
に変更しておきましょう。
変更したらダブルクリックして開きます。
次に関数のオーバライド一覧から
RecieveExecuteAIをクリックします。
タスク開始時の処理を作っていきます。
ブラックボードに移動先の座標が書かれているとして、
[BlackBoard Key Selector]型の変数を追加します。
名前は NextLocation とします。
また移動先までの距離(Length)の変数も追加しておきます。
変数を追加したら下記の画像の通りに、ノードをつないでいきます。
開始時の処理はこれで完了です。
続いて移動処理を書いていきます。
関数のオーバーライド一覧から[Recieve Tick AIをクリックします。
ここで作る処理は、移動後の移動先までの残り距離の割合を計算し、閾値以下ならこのタスクは成功として返す処理となっています。
はい、これで自作のMoveToタスクが出来上がりました。
過去記事のEQSを使って動かしてみました
この時のAIのCharacter Movement はFlyingの状態にしてください。
ちゃんと空中を歩いていますね。
アニメーションを飛行アニメーションに変えたらそれっぽくなるかもしれないですね。
ちなみにこのカスタムMoveToはパス検索などしていないので、現状障害物をよけて進んだりはできません。
障害物をよける処理については、また後日に書きたいと思います。
ではまた。
CEDEC2018で空中のパス探索についての講演がありましたね。
それについても、そのうち実装出来たらと思います。
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 のようにすることもできます。
今回はマクロライブラリを使っての取得でしたが、
マクロライブラリを使わずにウィジェットブループリント内の仕組みで、取得する
方法があるみたいなので、いつかそれについてもやってみたいと思います。
これ間違っている、こうしたほうがもっと簡単などあれば
コメントお願いいたします。