ゲームエフェクトデザイナーのブログ (新)

レポート記事とかUE4のマテリアルとか。C#とかも触ったり。

Flipbookマテリアルについて

※2018.6/9追記
 UE4標準のマテリアル関数「Flipbook」の中身の方がシンプルで不具合もありません
 この記事の組み方は良くないです‥
 また時間のある際にそちらを解説します

 

UE4でエフェクト向けにマテリアルを組む際に、Particle System側ではなくマテリアル内でSubUVアニメーション(Flipbook / パラパラアニメ)させたいことがあります。

今回はその方法についてメモしておきたいと思います。

UE4標準のFlipbookマテリアル関数を使用する


UE4.19時点で、Flipbookのためのマテリアル関数が2つ見当たります。
1つはGPUパーティクル用みたいですね。

f:id:moko_03_25:20180322002616j:plain

こちらを使用しても良いのですが、中身が少々分かり辛いのと不要な機能が入っていたりもするので、シンプルな構成のものを自作していきます。

基本的なマテリアル構成


テスト用にテクスチャを用意します。
縦と横のパターン数が違う方がデバッグしやすいと思います。

f:id:moko_03_25:20180322014431j:plain

まずベースとなる基本構成はこちら。1パターン分の絵が表示されるようにしています。
横・縦ともに1パターン分のサイズを出してUV座標に掛けています。
この時点では機能していないAddの部分にUVの移動を与えていきます。

f:id:moko_03_25:20180322002610j:plain

次に、1秒ごとにU方向へパターンが切り替わるようにします。
Timeの値をFloorで切り捨てると1秒ごとに1ずつ増える値を取得できるので、それをU座標に足すだけで1パターン分移動するようになります。
このようにTexcoordに対しては、パターン切り替えを先にAddで行って、後からMultiplyで1パターン分の大きさにUVをスケールする方が数値の流れを理解しやすいと思います。

f:id:moko_03_25:20180322002608j:plain

今度は、U方向のパターンが最後まで表示されたら次はV方向に1パターン分移動するように構成します。
つまりU方向に5パターンの絵が敷き詰められているなら、Timeで1カウントするのに5秒かかるようにします。そのためにはTimeを5で割れば良いのですが、これまでの手順で5で割っている部分があるので再利用しています。

f:id:moko_03_25:20180322002605j:plain

全体図を見てみます。これで1秒ごとにパターンが切り替わるようになりました。

f:id:moko_03_25:20180322002654j:plain

 

パーティクルごとにランダムなパターンから再生を開始させる


開始パターンをランダムにしたい場合、Timeノードから得られる値に全パターン分の範囲内でランダムな値を足すようにしてあげればOKです。

Dynamic Parameterノード(cascadeでDynamicモジュールを追加して0~1の乱数を設定する必要があります)やParticle Random Valueノード(こちらはGPUパーティクル限定 / 詳しくはこちらの記事をどうぞ)を使って得られる「0~1」のランダムな値に対して全パターン分の値を掛けて、Timeに足せばOKです。

f:id:moko_03_25:20180322002652j:plain

 

パターン切り替わり時に次のパターンをブレンドさせる


Timeから得られる値に1を足してあげるだけで次のパターンになります。
構成は一気に増えますがやっていることとしてはとてもシンプルです。

今の絵柄と次の絵柄をLerpノードでブレンドさせますが、遷移させるためにTimeの値をFracで小数点以下だけ取り出して、LerpのAlphaポートに繋いでいます。

f:id:moko_03_25:20180322002649j:plain

 

パターンが切り替わる速度を変える


説明が後回しになりましたが、1秒に1パターンの切り替え速度では遅いですよね。
図のようにTimeに30を掛けると1秒間に30回、パターンが切り替わります。

f:id:moko_03_25:20180322002646j:plain

ただし、Timeの値はもんしょさんの記事で解説されているようにパーシスタントレベル開始時からカウントされるため、時間経過とともに値がどんどん大きくなっていきますが、30のように大きな値を掛けるとさらに巨大な値になります。そして値が大きくなるにつれfloatの精度が悪くなるためか、このように絵が崩れていきます。

f:id:moko_03_25:20180322002643j:plain

そこでTimeノードのプロパティ「Period」で、ある程度のカウントで0にリセットされるようにしておきます。リセットされる瞬間は切り替わりがおかしい絵が一瞬出てしまいますが、これは仕方ないかと思います。。

f:id:moko_03_25:20180322013527j:plain

 

パーティクルの寿命に応じて一通り再生させる


パーティクルが生まれてから死ぬまでを0から1に遷移する値で取得できるParticle Relative Timeノードを使って、最初のパターンから最後のパターンまで再生させる構成は図のような感じになります。

f:id:moko_03_25:20180322013524j:plain

開始パターンをランダムにする必要が無いので構成も楽ですね。

以上になります!参考になれば幸いです。