Unity VFXGraphを1ヶ月で完全に理解した話

本日から2022年最後の月が始まりますね！そしてアドベントカレンダーも始まりますね！そしてそして本日は私の誕生日ですやったね！！
ということで、この記事は[N/S高等学校 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/n-s-highschool)、1日目の記事です。


筆者はS高等学校とN Code Labo（以下Nラボ）所属の人です。
今日はNラボでやったことについてのお話。

# 前置き
私はここ一年程、Nラボにて`1ヶ月間で1本お題に沿ったゲームを作る`、1ヶ月制作という企画をやっています。
今回は直近の1ヶ月制作企画、11月の1ヶ月間で行ったことのまとめとして、最後に書き出すための記事です。

10月、次の1ヶ月何をやるか決めかねていた際、興味はあったけどがっつり触れていなかったVFXGraphの話を講師とした結果、11月の企画は1ヶ月でVFXGraphを習得（）するというお題になってしまいました。

ちなみに今回はほぼ作っていないので1ヶ月"制作"というよりお勉強。まあたまにはこういう月があってもいいよね。

環境は以下
* Unity 2021.3.8f1
* HDRP 12.1.6
* VFXGraph 12.1.6

# VFXGraphとは
>Visual Effect Graphは、Unity プロジェクトの大規模な視覚効果を作成するためのパッケージです。Visual Effect Graphは GPU のパーティクルの動作をシミュレートします。これにより、ビルトインのパーティクルシステムよりもはるかに多くのパーティクルをシミュレートできます。多数のパーティクルを含み、高度にカスタマイズ可能動作が必要な視覚効果を作成したい場合は、ビルトインパーティクルシステムの代わりに Visual Effect Graph を使用します。

[Unityマニュアル](https://docs.unity3d.com/ja/2021.3/Manual/VFXGraph.html)より

要するに、ノードをポチポチするだけでパーティクルが作れるめっちゃ強いやつです。
おまけにCompute ShaderベースのおかげでCPUに負荷をかけず大量のパーティクルが出せる。強い。

# やったこと
今回、VFXGraphを完全に理解するべく
[Unity公式のVFXGraphのサンプル](https://github.com/Unity-Technologies/VisualEffectGraph-Samples)
[Unityステーションの寿司VFX](https://github.com/keijiro/SushiVfx)
この二つのサンプルプロジェクトを使用しました。
面白い表現が盛り沢山な最高のサンプルプロジェクトなので、VFXGraph初学者の方はぜひ覗いてみてください。

今回は基本的に、この二つの中身を分解しつつ色々と試しながら理解を深めていった形です。

一応、VFXGraph自体1ヶ月制作以前にも若干触ってはいたんですが、実質0からやったようなものなので当然つまずきまくりです。
今回はつまずいた（学びがあった）部分を中心に書いていきます。

#

#### なんか存在しないノードあるんだけど？？？
![qiita_vfx1_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681511/86e39dab-bf02-e7ea-2e98-0fcee8562320.png)
はい。Subgraphでした。~~ずっとノード名で調べても出てこず困惑してた。お恥ずかしい~~
Subgraphは、グラフの一部分をノードにまとめることができる便利機能です。

自作した複雑な処理を普通のノードと同じように扱えるので、
Subgraphを使用することにより、**グラフがコンパクトになり見やすくなる、よく使う処理を簡単に使い回すことができる**、といった利点があります。めっちゃ便利。

Subgraph化したい部分のノードの塊を範囲選択して右クリック→`Convert to Subgraph Operator`でSubgraphを作成できます。
![qiita_vfx2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681511/22fe2d73-cee7-cfda-af93-3fcd3edee45b.png)

ちなみに最初の画像みたく、すでにノードとして置いてあるSubgraphは右クリック→`Enter Subgraph`で中身を表示することができます。
![qiita_vfx3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681511/fad8f2df-3363-7bb6-4370-d51e71044d3d.png)

初見の機能に少し戸惑いつつ、無事解決。
ちなみに、同じくノードベースのShaderGraphにも同じ機能があるようで、ShaderGraphに強い講師の方は初見ですんなり理解していました。悔しい。

# 

#### Mesh Samplingが上手くできない！！
答えはシンプルだったんですが、解決するまでとにかく悩みました。めっちゃ悩みました。なんならNラボの担当講師も悩ませました。

![qiita_vfx6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681511/ed43e8eb-16bb-785c-4c21-084657f809ce.png)
Mesh Samplingは、3Dモデルのメッシュから頂点データを取得しグラフで使用できる機能です。

ちなみに↑のノードは`Operator`→`Sampling`から出せます。

寿司VFXの挙動を確認しようとした際、これを使用しているサンプルだけ何故かおかしな点があり、
状態としては以下
* ちゃんと3Dモデルが入っているのに形/色がエフェクトに反映されていない
* エフェクト自体は動く
* 特にエラーなし

調べても同じような症状が見つからず、Unityのバージョンを変えてみたり、とにかく色々試してみたものの解決せず、、
改めてマニュアルを確認してみることに。

そこで[Unityマニュアル](https://docs.unity3d.com/Packages/com.unity.visualeffectgraph@14.0/manual/Operator-SampleMesh.html)をよ〜く読んだところ、最後の方に恐ろしい文章を見つけてしまいました。
>If a Mesh is not readable, the Position (Mesh) Block and Sample Mesh Operator return zero values when they attempt to sample from it. For information on how to make a Mesh readable, see Model import settings.

「メッシュが"読み込み可能"になってないと動かないよ！」

はい。3Dモデルの方の設定の問題でした。~~私の悩んだ時間返して~~

メッシュをグラフに入れたとして、3Dモデルが読み取り可能に設定されていない場合は動作してくれません（しかもエラーが出てくれない悲しみ）

これはインスペクタの`Model`から、`Read/Write`にチェックをつけることで設定することができます。

![qiita_vfx5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681511/8f3c6b8d-f9cd-49b0-a457-d6d20ca901d5.png)

こちらの設定、メッシュデータをGPU＋CPUが処理するメモリに上げることで、ランタイムにUnityがメッシュデータにアクセスできるようになるようです。

今回ずっとグラフの方が問題だと思い込んでいて、3Dモデルの方を気にしていなかったのがよくないのですが、設定がやらかしてる系のミスには気をつけていきたいですね。

# 
#### なんかノード存在しないんだけど？？？
一番最初と似てますが違う問題発生です。

腕試しとして、別のプロジェクトに寿司VFXを再構築しようとした際、↑で紹介したMesh Samplingのノードが何故か出せませんでした。

```ちなみに↑のノードはOperator→Samplingから出せます。```
出し方は前にも書いてありますが、
調べた限り確かにこれであっているはず。

しかし出そうとすると、↓のようにノードが存在していません。
![qiita_vfx7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681511/cb8e9665-d917-4b46-5768-fec6858a8c38.gif)

検索しても見つからず行方不明。
![qiita_vfx8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681511/af461f8a-dbba-aa56-e672-eb97555fab57.png)

ただ、最初と違いこれは確かに存在するノードです。
実際、寿司VFXの方では↑の手順で出すことができます（検索でもちゃんと見つかる）

私はえらいので、ちゃんと前回の失敗で学んだマニュアルを読む大切さを活かします。

結果、再び恐ろしいことが書いてありました。なんなら[前回と同じマニュアル](https://docs.unity3d.com/Packages/com.unity.visualeffectgraph@14.0/manual/Operator-SampleMesh.html)の先頭に。
> Experimental: This Feature is currently experimental and is subject to change in later major versions.

「この機能は実験的だから今後のバージョンで変わるかもよ！」

はい。(´･ω･`)

調べたところ、実験的（Experimental）な機能として存在しているノードは、設定しないと表示されないようです。

`Editor`→`Preference`を選択し、`Visual Effects`内の`Experimental Operators/Blocks`にチェックをつけることで設定することができます。
![qiita_vfx9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681511/39599632-620d-fa01-138c-e0899fade780.png)

設定することで、無事ノードが表示。
![qiita_vfx10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681511/c203e746-561a-bbb9-13ae-376275b2f1b8.gif)

前回学んだことを全く活かさず、2回目の設定系ミスでした悲しい。。

# 最後に

だいぶ初歩的な部分でのミスが多く、かなりの精神的ダメージを負いましたが私は元気です。
様々なつまずきがあった1ヶ月でしたが、結果的には全て無事解決し、つまずきを学びに昇華することができました。

今回は私がつまずいたところを備忘録もかねて書いた形です。
その他細かいノードの説明などなど、VFXGraphの仕様の解説はすでに他の方々が大量の優良記事を書かれているので、そちらをご覧ください。
（ただし、今回二つ目の問題に関しては公式マニュアルの最後にちょこっと書いてある以外の記載を私が見つけられなかったので、もし奇跡的に同じ悩みを持った方の助けとなっていたら嬉しいです（~~マニュアルを読めばわかるから誰もそれの記事書いてないのでは？とかは悲しくなるので言わないように~~））


個人的には（今回記事に書いていない部分でやったことも含めて）この1ヶ月で実際、VFXGraphの理解はかなり深めることができたのかなと思っています。

以上。最後までお読みいただきありがとうございました！
良いUnityライフを！！

p.s. 今回得た教訓：*__ドキュメントは必ずちゃんと読もう。。__*