【Unity】出現させたパーティクルをいい感じに消していくVFXの作り方

# 事の発端
無から自由自在にエフェクトを出現させられるVFXですが、元あるパーティクルから逆に消していくVFXの方法はあまり見ないと思ったので記事にさせていただきました。

↓こんな感じのものが作れます
![S_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/54f9af6f-c167-756d-dd07-993a205d9319.gif)


既に似たようなものがあったら申し訳ない。

### Unity バージョン
Unity 6000.0.10f1
URP使用

# 作り方
### 1.Visual Effect GraphをPackageManagerからインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/460f687b-f714-ed28-af23-a4fb30abc84c.png)
#### 注意
VisualEffectGraphをインストールしたら、
PreferencesのVisualEffectsの項目を確認してください。

Experimental Operators/Brlocksにチェックが入っていたらOkです。
※GPU Eventが使えるようになります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/21bdf4b5-801f-3dbb-f14b-f85069774811.png)


### 2.VFXを作成する
ProjectウィンドウでVisualEffectGraphを作成（作れるならScene上でもOK）

### 3.Graphを作る
Graphを作ります。一旦全体を映してから細かく説明させていただきます。
#### 全体図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/c7e50a29-45ed-548e-20f7-74c4ed80d7ca.png)

### 床パーティクル部分
まず時間経過では消えないパーティクルを生成します。何もしなければ何の反応もしません。
#### **Spawn**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/05974315-415c-3482-f33a-8b5e0fd29e33.png)

**SingleBurst**にして、床パーティクルを一回だけ出現させるよう設定します。
Countの項目には一回で出すパーティクルの量を入れてください。
（とりあえず1000にしてます）



   　
#### **Initialize Particle**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/f0840907-55ff-56b8-c4e0-259e8fa8befe.png)
ここで何を出現させるか設定します。（Scriptのprivate void Start()みたいな感じ）

・**Set Size Random Uniform**
　出現させた時、パーティクル一個に対するサイズをA~Bの範囲でランダムに決めます。
 
・**Set Position Random Per Component**
　A~Bの範囲までランダムにパーティクルを出現させます。
 上記の画像の場合だと
 x：Aの範囲(5) + Bの範囲(-5 大きさは 5)
 y：0
 z：Aの範囲(5) + Bの範囲(-5 大きさは 5)
 なので図解するとここの範囲から形成されることになります。
 ![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/44224055-824f-e348-2b12-f820e27d6e48.png)

・**Set Tex Index Random Uniform**
　もし表示させたいTextureが複数あり、ランダムで切り替えたい場合はこちらのBlockを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/d55e7535-2945-8bd4-4a6c-dfaa191a143c.png)

内容としては記入したFlipBookの縦横比から全体の数を求めてるだけです。

一枚の画像を複数枚の画像として扱うので
複数の画像が分かれてるのであれば、サイズを合わせて一枚に結合させてください。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/19ad02b7-f80a-1c80-a7ab-2849b7746219.png)

  　
#### **Update Particle**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/a5d0802c-d90d-f903-0aad-79d00ac967c4.png)

ここでは常に動作する処理を追加していきます。

:::note warn
一度Update ParticleをInspectorで表示させて**Age Particles**のチェックを外しておいてください。このチェックが入っていると、LifeTimeを設定していなくてもパーティクルが消えてしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/5af877e2-8331-5941-0396-60f7d7230693.png)
:::

・**Kill Shape Sphere**
　パーティクルを消すための当たり判定を追加します。出現させた床パーティクルを消す為には一番重要なBlockになります。

 ・**Trigger Event On Die**
 　パーティクルを消した瞬間に判定が返ってくるBlockです。evtからGPU Eventに繋げば、消した後に新しく好きなパーティクルを出現させることができます。なくても大丈夫ですが、見栄え的には消した反応はあった方がリッチに見えます。
  ※GPU Eventは後程　

:::note info
**※TargetTransformについて**
Kill Shapeの位置をGameObjectのPositionに同期させることでGame中自在に床パーティクルを消すことができます。

同期させるには、VisualEffectの入っているGameObjectのInspectorに**VFX Property Binder**を追加し、PropertyにVFXで対応させたいTransform型Property、Targetに同期させたい別のGameObjectをアタッチさせてください。

より詳しく知りたい方はVFX Property Binderと検索してみてください（投げやり）

公式リファレンス↓
https://docs.unity3d.com/ja/Packages/com.unity.visualeffectgraph@10.7/manual/PropertyBinders.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/5df571ec-d733-a6a5-120b-3990e16439b4.png)
:::
  
#### **Output Particle Unlit**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/361bc1cb-9375-dd9e-0892-db819002f395.png)

結果何を表示させるかの処理をここで設定します。

※ここのFlipBookは複数画像を用意する必要がある場合に設定した、**Set Tex Index Random Uniform**に入れたFlip Bookと同じ数値を入れてください。

・**Orient : Face Camera Plane**
　パーティクルをカメラ目線にするか決めるBlockです。

### 消した後のパーティクル部分
ただ単に消すだけのパーティクルだとつまらないので、消した後にパーティクルをアニメーションさせます。

今回のVFXでは、消す用の当たり判定が接触したら、だんだん小さくなって消えてなくなっていくパーティクルを作ります。

#### **Initialize Particle**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/ed6fbbff-e33e-b6f7-b8a6-cf3a8ed1f1ca.png)
GPU Eventから繋げます。

Kill Shapeでパーティクルを消した場合、どうあがいてもアニメーションをさせる前に消滅してしまいます。なので、「**消した瞬間に新しく同じ場所、サイズのパーティクルを出現させる**」といった方法を取ってアニメーションさせています。

・**Set Position From Source** & **Set Size From Source** & **Set Tex Index**
　読んで字のごとし、床パーティクルでセットしたPositionとSizeの値を設定してくれます。

 ※**Set Tex Index**は複数画像がある場合に必要
 **Set Tex Index**にくっついている**Get Tex Index**の値は、現在の画像番号を返してくれます。
 LocationをSourceにすることで今どのTextureが床パーティクルの位置に表示されているかを知れます。

・**Set Lifetime Random Uniform**
　A~Bの範囲でランダムに消す秒数を指定してくれます。

#### **Update Particle**
こちらには何もBlockはありませんが、必ず入れておいて下さい。アニメーションしなくなります。

#### **Output Particle Unlit**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/d2642827-a751-47e1-74b6-5fc652f5d262.png)

Flip BookとTextureは床パーティクルと同じものを設定してください。

・**Multiply Size Over Life** & **Set Alpha Over Life**
　どのようにアニメーションしていくかを設定できます。お好みでAnimationCurveを変更してください。

# 実践
一番最初に見せたGIFのようになれば完成です。

割とVFX初心者が躓きそう（実際かなり考え込んだ）な部分をまとめた記事にはなったかなと思います。これで何かしらの手助けになれば幸いです。

![S_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3723719/99e72c5a-8594-3338-aace-c039d6500003.gif)