UE5.5 GASP+Niagara FootStep VFX 水しぶき・泥はね・スパーク

※本サイトはアフィリエイト広告を利用しています。

本日のテーマはゲームアニメーションサンプルでVFX 水しぶきや土煙をだそう です
前回の足音の続きです

前提準備

フィジカルサーフェス・物理マテリアルを追加して音のパターンも増やしておきました
やり方は一緒なので前回の足音記事を先にご覧ください

本記事では、Niagara Footstep VFX | Fab というUE5の無料アセット(Fab Standard License)を利用します。土・砂・泥・草・水・氷・火花など15種類入りです。

足跡残すのもナイアガラでもできますが、今回のアセットにはありません
インタラクティブワールドの機能で後日紹介します

UE5.5で使う前準備

このアセットを使わないかたはチャプターを1つ飛ばして構いません
その場合はナイアガラシステムの準備はできているものとします

いつも通りプロジェクトに追加しましょう
UE5.5でプロジェクトを開くと、起動直後に下図の情報表示がでますが、
とりあえず「インポート」しなおすのが正解かなと思います

A_Surface_Footstep フォルダができているので、その中にあるデモマップを開いてみましょう
本来はこんなのができますよの展示ですが、なんにもでません

バージョン互換じゃない気もするのですが
2つ問題があるのでそれを見ていきましょう

デモが正常動作してない問題

まずは何にも出ない大問題のほうからみましょう
キャラクターの編集でナイアガラ変数を追跡しましょう

リファレンスを検索 では見つからないのでスコープのボタンで全体から探します

RecievedNotify というアニメーション通知が見つかりましたね

直後にSpawnSystem at Locationノード(ナイアガラをスポーンする処理)があるのでここが使用箇所であっていますね

ブレイクポイントを貼って実行してみましょう
スケールのピンに0 0 0が来ていますが、これは0では表示されません

原因はわかりました。修正しましょう。

ロケーションは元の位置に足しているので、オフセットらしい計算になっていますね

入力される値がどんな値かも確認しましょう。
この処理を呼び出しているアセットを探します。変数を検索しても見つからなかったので、参照ビューアで呼び出し関係をみます

走りと歩きのアニメーションから呼ばれていますね。走りのアニメーションを開いてみましょう

通知のところにありますね。それを選択して詳細欄をみると、スケールオフセットはここで0 0 0になっています

「オフセット」とは基準からのズレの表現なので、オフセットを1,1,1に変更するという変更案よりも、通知のBP側で受け取った値をLocationと同じくオフセットらしい計算にするほうが自然ですね

よっしー
よっしー

割愛しますがローテーションも同様です

これでデモが動きましたね

ナイアガラ警告問題

パーティクル自体の初期化処理が、UE5.3で?互換性なく交換されてしまったようなので、新しいものに置き換えが必要とのことです

んでその置き換え作業はシステムからはできず、子のエミッタ側でやる必要があるよと案内されています

量が多くて面倒ですが、難しくはないのでやってみましょう
このボタンからエミッタを開けます

これを選択して、詳細欄で3択で修正方法がありますが、一番簡単なのは上のやつです
※初期化処理は必須なので、削除はありえないので2択ですね

「推奨される代替案~」をやると自動で新しいのに変えつつ、もとのも残るので、設定見比べたりできます

そしてよく見るともっと細かい機能が廃止されているので、
自動修正だけではもとの機能を再現できていません

よっしー
よっしー

ここがYouTube動画冒頭で大きすぎるとか回転できてない問題の原因です

合わせこみやっていくのは大変なので今回はこのままでいきます
ひとつのシステムに3から5個くらいのエミッタがついていて、全部の初期化にこの作業が必要です

よっしー
よっしー

※警告扱いで一応そのままでも動いているので、そのままでもいいかもしれませんが、作者の設計意図通り動いてはいない状態かと思います。

エミッタの設定を全部更新すると、親のシステムの警告も消えていますね

ちなみにナイアガラシステムはデフォルトで変化があると自動でコンパイルしてくれます

よっしー
よっしー

条件をちょっと変えるたびにコンパイルボタン押すのは面倒ですから親切仕様ですね

とりあえず1つできましたが、この作業が15個分必要です

ウォーター2種類はエミッタが同じなのでパラメタ違いで片方だけ更新でOKでした。氷もおそらく2パターン同じだと思います。
やることは同じなのでほかは割愛します

GASPへの適用

前回改造したオーディオバンクのところですが、さらに改造して音を返す部分だけを残しています
SurfaceTypeを変数に昇格させて、そこにあらかじめ地面の種類を保存されている前提とし、ここではその値を参照して出力するだけにしました

そしてライントレースはどこにいったかですが、イベントグラフのBeginPlayからシーケンスで処理を追加して、

ここでタイマーで動かすループ処理の中に移動しました
ティックでもよいと思います

よっしー
よっしー

タイマーではなく、アニメーション通知などから必要な時に実行するようにしてもよいと思います(YouTube動画「おまけ」で精度アップするときにそうしています。追加で記事にもするかも)

メッシュのルートのちょっと上から下までライントレースするのは元のままです

動画では変数に書き込んでデバッグ表示するようにしています

これでサーフェスタイプをいつでもモニタできるようになったので、
VFXに関しても、音と同じようにパーティクルを切り替えてスポーンさせるだけです

同じロジックで出力タイプだけナイアガラシステムに変える作戦でOKです。
が、せっかくなので今回はチューザーテーブルを使ってみました

よっしー
よっしー

UE5.5でチューザーテーブルは正式版になりました

キャラクタの状態をインプットとして受け取り、それに応じて、どのパーティクルを出すかを選ぶテーブルとしています

一応ここに直接実装したいかたは、こんな感じでスイッチで切り替えるか、
もしくはセレクタでもできるかと思います

ただし、このように直書きだと、ゲームのボリュームが増えるにつれて、どこにその処理があるのかわからなくなるので、できればスッキリさせておきたいですね

チューザーテーブルはキャラクタの外で変更ができるので、分担だったり管理がしやすい利点があります

よっしー
よっしー

前回やったオーディオバンクもチューザーテーブルに置き換えるのもよいかと

チューザーテーブルとは

まずご存じない方向けにざっくり

一番左が出力で、ここではナイアガラシステムが設定されています
それ以外が選択条件の列で、CBPサンドボックスキャラクターの情報を入力で受け取っています。

行の1番上から右の条件列をすべて満たしているか判定し、成立していたら左の条件が選択されて処理終了します。
一つでも条件が不成立であれば、次の行の評価に進みます。いわゆる状態遷移表ですね。

チューザーテーブルをつくろう

ではチューザーテーブルを作りましょう。「チューザー」で検索するとその他のところにいるほうのやつです(日本語だと「Choo」などではヒットしません(;^ω^))

よっしー
よっしー

※ GASPではオンになっていますが、それ以外のプロジェクトだとプラグインで有効化しないとでてこないかもしれません

テーブルの出力は何か、がテーブルとして一番重要ですね
ナイアガラ関連はたくさんありますが「NiagaraSystem」を選びましょう


入力(テーブルの外から与える情報)として、サンドボックスキャラクターの情報が見たいので、Parametersに Class Parameter で CBP_SandboxCharacter を選びます。
これで、このクラスがもつ変数などの情報を選択条件に使用できるようになります。

作成 で枠ができました

よっしー
よっしー

Chooser Tableなのでアセット名は CT_** でいいかなと。

行からでも列からでも作れます。

行にはアセットでNiagaraSystemを登録していきます
条件成立するかは上から評価されていくので大事なものから並べます

列は、サンドボックスキャラクターの情報の何を使って分岐させたいかです
たとえばブールだとフラグで、FloatやIntなどの数値型は範囲を設定する感じです

「任意」だと、この条件は気にしないってことになります

どれも返さないっていう選択はよくなさそうなので
最後の候補は必ず選択されるように設計するのが大事かと思います

よっしー
よっしー

なので一番下にはほぼ「任意」か「全体含む範囲」が並ぶイメージですね

GASPのアニメーションのテーブルでは
 Dense密 > Sparse疎 > その他は Dense
というふうに、高精度側を優先させつつ、どちらでもない条件だったらDense側を再度採用するという安全設計っぽいつくりになっていました

もし特定の条件ではVFXを出したくない(つまり、このテーブルからなにも返したくない)という場合は、空っぽにはできるかなと思います。なので必ず通る範囲にしておいて

さらに使う側で空っぽだとエラーになりそうなので、ヌルポ対策をしておくとよいかと思います

地面の種類とキャラの速度でVFXを選ぶテーブル

できたテーブルを見ましょう

前の手順で一定周期で更新されているSurfaceTypeが主な条件です
下2列に関してはそこが任意となっているため、SurfaceTypeが関係ないですが、スパーク出すか通常かの出力を切り替える条件は、
前方への速度が600超えたらスパークで、それ以外の場合はジェネラルにしてあります

スプリント中じゃないとこの速度にはならないので
WantsToSprintフラグはこの場合は見ても見なくてもOKです

ここで条件に使っているVelocity Fwという変数は、Tickイベントで更新する処理を追加しています。

ムーブメントコンポーネントからVelocity (速度ベクトル)を取り出して、キャラが向いている方向とVelocityの内積で前方の長さ(ワールド座標のXYZ空間からキャラクターのローカル空間上のX成分を取り出したもの)が計算できます
前向きに結構加速できているとき「だけ」スパークさせたいという意図です

よっしー
よっしー

ここはちょっとムズイかもですが、何言っているかわからんという方は、素直にベクトルの長さだけ見てもいいと思います
「Vector Length XY」ノードで、高さ方向は無視したXY平面上のベクトルの長さ(真上から見たときの矢印の長さ)が得られます

この場合は横向きや後ろに走っている場合でも閾値次第でスパークできます(GASPの初期設定だとそこそこ前向きじゃないと600はでません)


ではもとのテーブルに戻って、スパークさせる条件と同様に、
水しぶきの強さを2種類変化させてみましょう
行を追加し、アセットでWaterHeavyを設定後、一番左のここをつまむと順番を変えられるので上から2番目に持ってきましょう


SurfaceTypeがウォーターでスプリントはTrueでもよいですが
今回は任意のまま速度だけ変更してみます
これで300以上のときヘビーがでる設定ですが、上から順番に評価されるので、先に条件成立しているとそっちが選ばれちゃうのでこれではWaterLightがでます。

先にこの条件に当てはまるか判定してもらうならトップに順番を入れ替えましょう
すると、先に判定される300を超えているときはヘビーになって、300未満のときはライトなしぶきになります

もしくは条件を互いに被らない範囲にすることもできます
最大値の検証をしていませんが、おそらく300ちょうどまでWaterLightがでてそれいこうはHeavyがでると思います

(ドキュメントに説明がみあたりませんが、)ここのNo Max が上限を範囲に含める含めないのフラグかなと思います

歩いているときは弱めで、走っているときは強めになりましたね
300だとすぐ達成されちゃうので、スパークと同じ600に変更しておきました。

この辺の調整は速度をデバッグプリントしてやるとよいでしょう

また、スプリントじゃないと達成されない速度なのでWants to Sprint列は消しました。どちらでも構いません。

よっしー
よっしー

※ただし車乗ったりするようなゲームの場合は、乗ってる乗ってないみたいなフラグ等が必要な場合もあるでしょう


さて、本当はカスタムイベントを作っただけでは動きませんね
音と同じくアニメーション通知をきっかけに実行すればよいかなと思います

BP_Anim_Notify_Foley_Event > Recieved_Notify

前回もみた音を出す処理(PlaySound at Location)の後ろに、足跡代わりのスフィアを描くデバッグ機能があり、そこで、左右の足の位置とメッシュのルートの位置をみています
ようするにここですね

メッシュの原点である中心か左右の足です
その中でどの位置を使うかは Side 変数で指定されています
この変数は通知に公開されていて、

この右足が着地しようというタイミングでサイドが右になっていますね

ほぼ両足着地のこのアニメーションではSideはNoneになっています
割愛しますが、着地後の足踏みではそれぞれ設定されています

よっしー
よっしー

※弓矢を持っているのはプレビューメッシュで別件ですm(_ _)m

そしてこのどっちの足かできまる位置情報をもとに、メッシュのOwner(所有者つまり親であるキャラクター)をCBP_SandBoxCharacterにキャストして、作ったナイアガラをスポーンさせる処理を実行すれば完成です

キャスト使いたくないって場合は、音と同じようにインターフェース化するなど、
真似ればよいと思います

あと、音の時は共通処理部分だったので気にする必要がありませんでしたが、
前回記事でもふれたように、ジャンプ時と着地のタイミングでは、モーションマッチングの都合で音ズレが起きないように、アニメーション通知からではなく、ここ(OnLanded Event)から音を鳴らす処理があります

通知からだけだと、この場合にパーティクルがでないので、ここにもスポーンパーティクルイベントを呼びましょう

ジャンプはOnJumped Eventで同様に音を鳴らす処理がありますが、私はこのタイミングはパーティクルでなくてもいいかなと省略しています

よっしー
よっしー

入れたい方はOnLandedとまったく同じでいいと思います

できましたね

コメント

タイトルとURLをコピーしました