【UE4】アニメーションに合わせてパーティクルを生成してみる

#はじめに
https://www.youtube.com/watch?v=JCfbBA42_xE
こちらのムービーのように斬撃に合わせてエフェクトを生成する方法を紹介します。

#必要なアセットはこちらから
https://1drv.ms/u/s!Au-8FqgREBKZhSIIMiZKkgsK2YXv
One Driveに今回作成するプロジェクトに必要なアセット（キャラクターメッシュとアニメーション）をアップロードしました。
もちろん、どのようなアニメーションでも今回紹介する手順に則って設定していけば同じようにカッチョイイエフェクトを出せるのでカッチョイイモーションをお持ちであればそちらで試していただいても構いません。

#プロジェクトの作成
新しくプロジェクトを作成していきます。
使用しているエンジンバージョンはUE4.17.1です。

・使用テンプレート：空のプロジェクト
・プロジェクト名：SwordAttackEffect（お好きな名前で構いません）
・スターターコンテンツ：有り

#キャラクタメッシュとアニメーションのインポート
OneDriveからアセットをダウンロードされた方は作成したプロジェクトにインポートしてください。

BoxMan.fbxをインポートする際にはインポートオプションの**Use T0As Ref Pose**に**チェックを入れ**、全てインポートでOKです。
![1.png](https://qiita-image-store.s3.amazonaws.com/0/104467/878777bb-ca8a-de0e-c549-881edcaa78c1.png)

Sword_Attack_01.fbxは**Import Mesh**の**チェックを外し**、全てインポートしてください
![2.png](https://qiita-image-store.s3.amazonaws.com/0/104467/14380e9c-b995-f81b-61ed-3e40152b4a8c.png)
インポートが終わると２種類のアニメーションが表示されますが１フレームのみのTポーズアニメーションは一切使用しないので削除してください。（赤枠の方）
![3.png](https://qiita-image-store.s3.amazonaws.com/0/104467/3fce4aef-b09c-e72e-2783-742dafa02876.png)
斬撃攻撃のアニメーションは名前が長いので**A_Sword_Attack_01**にリネームします。

Sword.fbxはBoxMan.fbxをインポートした時の設定がそのまま残ってしまっているので、**Skeletonをなし**にして、全てインポートします。
![4.png](https://qiita-image-store.s3.amazonaws.com/0/104467/2f21b3be-439a-7587-2048-c6c622b893f0.png)

これで必要なアセットのインポート作業は終了です。
必要な方は適宜アセットをリネームしてください。自分は以下のようにリネームしました。
![6.png](https://qiita-image-store.s3.amazonaws.com/0/104467/7c964a9f-68e2-a402-e1ee-af78211a2459.png)


#いよいよ本番！
##ステップ１：アニメーションブループリントの作成
アニメーションブループリントを作成します。（名前は**ABP_BoxMan**としました）
作成する際にスケルトンを指定しますが**BoxManの方**を選択してください。（間違えてSwordを選ばないように）
![5.png](https://qiita-image-store.s3.amazonaws.com/0/104467/d48502c9-43f0-ffcb-5bba-2e11b0ceacaa.png)

AnimGraphは以下のようになります。
![7.png](https://qiita-image-store.s3.amazonaws.com/0/104467/ef846c4e-9779-4460-4e80-2f46892bf913.png)

とりあえずアニメーションブループリントはこれで一旦終わります。

##ステップ２：トレイルエフェクトの作成
最初にトレイルエフェクト用のマテリアルを作成します。名前は**M_Trail**としました。
内容は以下のとおりです。
詳細パネル内の設定も忘れずに行ってください。
![8.png](https://qiita-image-store.s3.amazonaws.com/0/104467/ae4d275a-1e74-3932-6562-9e2a3de88144.png)

続いてエフェクトを作成します。名前は**P_SwordTrail**としました。
P_SwordTrailを開き**タイプデータ**を**AnimTrail Data**に変更します。
![9.png](https://qiita-image-store.s3.amazonaws.com/0/104467/f86fcda6-c38c-5ec0-0b53-6438747c4005.png)

**Initial Velocity**は不要なので削除します。

**Color Over Life**を選択し詳細パネルを以下のように設定します。
![10.png](https://qiita-image-store.s3.amazonaws.com/0/104467/9ec3bb81-5a33-b0c4-df2f-516d32b852c5.png)

以上でトレイルエフェクトの作成は終了です。

##ステップ３：トレイルエフェクトをアニメーションにくっつける
作成したトレイルエフェクトをアニメーションにくっつけていきます。
最初にキャラクタのスケルトンを開きプレビューメッシュとプレビューメッシュをアタッチする用のソケットを追加します。これはトレイルエフェクトの始点と終点を設定しやすいようにするためです。
スケルトンツリー内の**hand_r**を右クリックし**ソケットを追加**を選択します。ソケットの名前は**Sword**とします。
![11.png](https://qiita-image-store.s3.amazonaws.com/0/104467/3b0a0398-44db-846d-a1b1-438af97cdb72.png)
Swordソケットをいい感じの位置に調整します。
自分はRelative Locationを以下のように設定しました。
(X=-0.000003,Y=-12.753735,Z=-20.000002)
Location以外は特に弄る必要はありません。
Swordソケットを右クリックし**プレビューアセットの追加**でSwordスケルタルメッシュを選択します。
![14.png](https://qiita-image-store.s3.amazonaws.com/0/104467/78013425-39ae-9b06-4f86-fbe0b79c7b56.png)


もう一度**hand_r**を右クリックし**ソケットを追加**を選択します。
名前を**SwordTrail_Start**とします。
このソケットはトレイルエフェクトの始点となる場所を表します。
Relative Locationを**(X=-0.000009,Y=-15.000002,Z=19.999998)**このようにします。
この位置は丁度剣の鍔のあたりになります。
![12.png](https://qiita-image-store.s3.amazonaws.com/0/104467/530ad592-a82b-e035-1a29-47c38ddc0591.png)

続いて同様の操作でソケットを追加します。名前を**SwordTrail_End**とします。
位置を**(X=-0.000053,Y=-15.000031,Z=175.000000)**にします。
この位置は剣の先端になります。
![13.png](https://qiita-image-store.s3.amazonaws.com/0/104467/fad79400-15c1-de9c-5205-e55a10971968.png)
これでトレイルエフェクトの始点と終点を設定出来ました。

次に**A_Sword_Attack_01**（斬撃アニメーション）を開きます。
画面の一番下にあるタイムラインの赤棒を**攻撃が始まる瞬間のフレーム**まで移動します。
![15.png](https://qiita-image-store.s3.amazonaws.com/0/104467/676bc7a2-7950-7695-977f-062e965d55b5.png)
移動できたら通知と書かれている白枠の赤い線を右クリックし**通知ステートを追加**で**Trail**を選択します。
![16.png](https://qiita-image-store.s3.amazonaws.com/0/104467/2a5cd51e-175b-8763-6f1c-7da6bdb5fe2c.png)
追加されたTrail通知ステートの右にある赤い砂時計のようなマークを**攻撃が終わる瞬間のフレーム**まで移動します。
![17.png](https://qiita-image-store.s3.amazonaws.com/0/104467/067a7b87-e971-5b8c-6e94-8af5e11c6b51.png)

無事移動出来たらTrail通知ステートをクリックし詳細パネルで各種設定をしていきます。
**PSTemplate**にステップ２で作成した**P_SwordTrail**を割り当てます。
**First Socket Name**には先程作成した始点のソケットである**SwordTrail_Start**を設定。
**Second Socket Name**には**SwordTrail_End**を設定します。
![18.png](https://qiita-image-store.s3.amazonaws.com/0/104467/90a64a75-509c-bba2-4bf2-c3fee3f4914a.png)

これで再生してしばらく経つとトレイルが表示されます。
![19.png](https://qiita-image-store.s3.amazonaws.com/0/104467/d1bf6754-f0a2-59af-cbd1-535da890ac9e.png)

以上でトレイルエフェクトをアニメーションにくっつける事が出来ました。

##ステップ４：炎パーティクル
炎パーティクルはプロジェクト作成時に含めたスターターコンテンツの**P_Fire**を基に作成します。P_Fireをコピーするか直接弄るかはお好みです。

デフォルトのP_Fireはループするタイプですので一度スポーンさせてしまうとDestroyしない限りはその場に残り続けてしまいます。ですので、このP_Fireをバースト（１ループのみ）するように各エミッタとモジュールを変更していきます。

全エミッタのRequiredにある**Emitter Duration**を**0.0**に変更します。
![20.png](https://qiita-image-store.s3.amazonaws.com/0/104467/2fae96c3-9e92-f79b-a889-11db842deeca.png)

全エミッタのSpawnにある**Rate**と**Rate Scale**のConstantを**0.0**に変更します。
![21.png](https://qiita-image-store.s3.amazonaws.com/0/104467/eb4be12b-a2e6-5947-3ad6-cdb0a53abef1.png)

続いて**Burst List**のプラスボタンをクリックしCountを**5**にします。
![22.png](https://qiita-image-store.s3.amazonaws.com/0/104467/917e7f26-6577-41f0-63c2-744bfff755f8.png)

次に全エミッタのLifetimeのDistributionを**Float Constant**に変更しConstantを**0.5**にします。
![23.png](https://qiita-image-store.s3.amazonaws.com/0/104467/c467b341-42ef-f487-7c24-c84e0f57b849.png)

無事に設定できたらビューポートの方にパーティクルの再生が終了すると**完了**という文字が出るはずです。この文字が出ない方はどこかしら設定し忘れていると思います。
![24.png](https://qiita-image-store.s3.amazonaws.com/0/104467/fc27dad8-b7f6-d9f4-6f04-c7e7d22fb043.png)

以上で炎パーティクルをバーストさせることが出来ました。

##ステップ５：アニメーションに合わせて炎パーティクルを生成する
いよいよアニメーションに合わせてパーティクルを生成するようにしていきます。

パーティクル生成を通知するためにアニメーションにカスタム通知を追加していきます。
斬撃アニメーションを開きTrail通知ステートを設定した白枠の右端にある**プラスボタン**をクリックし白枠を１つ増やします。
![25.png](https://qiita-image-store.s3.amazonaws.com/0/104467/8e3e3d6a-ffdb-738e-6c56-8c5320593681.png)

新しく追加した白枠を右クリックし**通知を追加**、**新規通知**を選択し名前を**Fire_Begin**とします。同様の手順で**Fire_End**を追加します。
![26.png](https://qiita-image-store.s3.amazonaws.com/0/104467/c1e8cae0-d7fd-c74e-77ae-493b582559ac.png)

各カスタム通知の位置はTrail通知ステートの左端と右端に合わせます。
![27.png](https://qiita-image-store.s3.amazonaws.com/0/104467/00512a2b-4d4f-ae69-73c1-eef8eb4c96dc.png)

追加した２つの通知に合わせて処理を実行するようにします。**ABP_BoxMan**を開き、イベントグラフに以下のように処理を組みます。
![28.png](https://qiita-image-store.s3.amazonaws.com/0/104467/203d2770-26b7-0494-0923-1ada04b7fb3f.png)

Spawn Emitter at Locationの**Emitter Template**には先程作成した**P_Fire**を設定します。
プレビュー画面を見てみると斬撃アニメーションに合わせてトレイルと炎パーティクルが出現するようになるはずです。

レベル上で確認する場合は**ABP_BoxMan**をそのままレベルにドラッグアンドドロップしてください。プレイを押すと同様の結果が見れるはずです。
![29.png](https://qiita-image-store.s3.amazonaws.com/0/104467/92d46af2-93cb-cbbe-0066-ced3801e8f69.png)

いい感じですね！かなりカッチョ良くなったと思います！

#完成したプロジェクトはこちら
おまけ（ブラッシュアップ編）で解説する予定の箇所も含まれた完成版をOneDriveにアップロードしました。
https://1drv.ms/u/s!Au-8FqgREBKZhSPpWkFrZRIFT2X4

#おまけ（ブラッシュアップ編）
炎パーティクルを生成出来たことでかなりカッチョ良くなりましたが、もう少し手を加えて、よりカッチョ良くしてみようと思います。

##炎を外側に飛ばす
現状の炎パーティクルは生成された位置に点として残るような感じになっています。
![30.png](https://qiita-image-store.s3.amazonaws.com/0/104467/ce2cabca-22c7-2c59-533b-85d745b5f315.png)
これだけでも十分かっこよくなっていますが、このパーティクルを剣の軌道から外側に飛ぶようにすると攻撃のスピード感や派手さが増し、より目を引く効果を生み出します。
![31.png](https://qiita-image-store.s3.amazonaws.com/0/104467/1cd25d48-40d8-ab36-1dbf-34a090dc95d5.png)

![32.png](https://qiita-image-store.s3.amazonaws.com/0/104467/a094181a-7e15-c9aa-7a9e-141fec48e6c3.png)

炎パーティクルを外側に出すには[Particle Instance Parameter](http://qiita.com/Dv7Pavilion/items/0d867d260a5b92ea3f5a)を使います。

**P_Fire**を開き一番左側のエミッタ（**Flames**）に**Accelerationモジュール**を追加します。
AccelerationモジュールのDistributionを**Vector Particle Parameter**に変更し、Parameter Nameに**Velocity**を入力します。続いてParam Modesを展開し３つ全てを**DPM Direct**に変更します。
![33.png](https://qiita-image-store.s3.amazonaws.com/0/104467/ad5ae47d-7ed8-080c-0ba7-f8cc7e99ebd9.png)

Accelerationモジュールを設定出来たらエミッタパネルでAccelerationモジュールを**Shift + 左クリックしてドラッグ**し他のエミッタへと移動します。これで**モジュールインスタンスが**作成されます。モジュールインスタンスは項目名の**右側に＋マーク**が付きます。
![34.png](https://qiita-image-store.s3.amazonaws.com/0/104467/f0f9582e-07ba-49cb-d2ef-881cc1febc18.png)

以上で炎パーティクルの設定は終了です。

続いてABP_BoxManを開きSpawnEmitter at LocationのReturn Valueから**Set Vector Parameter**を引っ張り出し、以下のように組みます。
![35.png](https://qiita-image-store.s3.amazonaws.com/0/104467/633fcfc5-5dfc-3fec-3f45-8223b42533fa.png)

Set Vector Parameterの**Parameter Name**には**Velocity**を入力します。このVelocityは炎パーティクルの**Accelerationモジュールで設定したParameter Nameと同じ**です。

これで実行すると炎が軌道の外側に飛ぶような感じになります。


Sel Vector ParameterのParamを渡す際に**Get Right Vector**に**-1000**を掛けました。
このようにした理由はアニメーション中の**SwordTrail_Endソケット**のローカルでの向きに由来しています。
![36.png](https://qiita-image-store.s3.amazonaws.com/0/104467/bf0e7021-5b43-80a3-f498-464e32a21ade.png)
上の画像では緑軸（右を表す）が剣が進む方向とは反対に向いてしまっています。このままでは軌道とは反対の向きに炎が飛びますので、結構な違和感を生み出してしまいます。
今回の場合、炎は軌道に沿いつつ外側に出したかったのでRight Vectorに-1000を掛けました。

この画像を見ると青軸（上を表す）もいい感じの方向を向いていますので**Get Up Vector**に**1000**を掛けてもいい感じになります。

#おまけ（LOD）
>ここで紹介する問題はOneDriveにアップロードしていた完成版のプロジェクトでは解決されていません。（全然完成版じゃなかったですね！すいません！）

この記事を書いている時に気が付きましたがカメラとの距離が離れるとパーティクルがその場に残り続けてしまっていました。（バースト設定になっていない）
原因は**パーティクルのLOD**でした。
P_FireにはLODが設定されており、今までのP_Fireに対する変更はLOD0（最もきれいに見える）にのみ適用されていました。LOD1は何も変更が適用されていなかったためのバグ（？）でした。

この問題の解決方法は簡単でLODを再生成するだけです。
パーティクル編集画面のツールバーにある**LODを再生成**をクリックすればOKです。
![37.png](https://qiita-image-store.s3.amazonaws.com/0/104467/c48d765e-dcd1-488b-1da4-af739c8b6760.png)

これでLOD1をプレビューした時に再生が終わると**完了**という文字が出るようになります。
同時にカメラが離れた時にパーティクルが残ってしまう問題も解決します。

#まとめ
かなり長めの記事になってしまいましたが重要なところをまとめてみます。

**1.パーティクルをバースト（一度だけ生成）にする**
**2.カスタム通知で生成開始と終了の間だけパーティクルをソケットの位置に出す**

これだけです。

結構お手軽に出来るので是非何かしらで活用していただければ幸いです。
お疲れ様でした。