VFX GraphにおけるVFX Property Binderの活用

この記事は[Unity Advent Calender 2019](https://qiita.com/advent-calendar/2019/unity) 18日目の記事です。

Unityの新しいエフェクト制作ツールであるVFX Graph、皆さんは活用されていますでしょうか？
本記事ではVFX Graphを使う上で知っておくと便利な機能、VFX Property Binderの紹介をします。
*Unityのバージョンについては2019.3.0b12を使用しています。バージョンによって単語や操作について相違点がある場合もあるのでご注意ください。

## VFX Graph

Unityの新しいエフェクトツールです。Compute ShaderによるGPUパーティクルとノードベースのエディターが特徴で、Package Managerから導入することができます。
映像作成やxRコンテンツなど、様々な用途にUnityが進化を遂げていく中で自分がかなり期待している機能の一つです。
機能自体の導入や基本操作に関しては省略しますので、そこから知っていきたい方は@tan-yさんの記事がかなり丁寧なので参考にしてみてください。

Visual Effect Graph 入門 @tan-y
https://qiita.com/tan-y/items/cd6fc58674d6f0c54d0b

## VFX Property Binder

VFX Property Binder(以下 : Property Binder)は、シーン内の情報をVFX Graphに伝達して演出のパラメータとして使うための機能です。
出た当初はParameter Binderという名前だった気がするのですが、いつの間にかProperty Binderという名前に変わっていました。
特定のオブジェクトのTransform、Colliderなど様々なパラメータに基づいた演出を可能にしてくれます。スクリプトもほぼ書かずに実現できるためかなりお手軽な機能です。
この機能を使うことで、オブジェクトの座標に従ってパーティクルを移動させたり、特定のオブジェクトとの衝突でパーティクルの挙動を変えたりと、演出にシーンに基づいた動的な変化を与えることが可能です。

<img width="362" alt="スクリーンショット 2019-12-14 17.06.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141004/cf19885f-a107-76b5-4d19-d4efa90140db.png">


Property Binderはコンポーネントとして提供されており、インスペクター上で様々な設定を行うことができます。
VFX Graphと連動させたい要素ごとに○○ Binderというコンポーネントが用意されており、上の画像のようにProperty Binderのコンポーネントの設定にセットしていくことになります。
Property Binderが親コンポーネントで、そこに子となる要素ごとのBinderのコンポーネントを設定していく感じです。

追加したコンポーネントは画像のようにインスペクターのメニューから設定可能で、メニューから用途に合わせて選択します。
色々な用途のその中のコンポーネントの中からいくつかの種類を紹介します。

## 使い方

まずは適当なオブジェクトにProperty Binderをアタッチします。
<img width="363" alt="スクリーンショット 2019-12-14 17.21.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141004/20a84799-ef5b-6287-b949-c7336b97b42b.png">
アタッチすると自動的にVisual Effectのコンポーネントもアタッチされます。
Visual EffectはVFX Graphのエフェクトをシーン内で使うためのコンポーネントで、Property Binderが作用させる対象になります。
Property Binderは内部でGetComponentしてVisual Effectを参照しているため、同じオブジェクトにアタッチすることが必要になります。

Property Bindingsのプラスボタンを押すと前述のパラメータごとのコンポーネントを設定することができます。
Position Binderを例として追加して説明していきます。

<img width="361" alt="スクリーンショット 2019-12-14 18.15.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141004/100ed64d-1805-b319-db1a-4fa52ec8a7cc.png">

追加すると、対応するコンポーネントのアタッチとプロパティ名の設定をする必要があります。
コンポーネントのアタッチについては任意のシーン内のコンポーネントを設定してください。Position BinderならVFX Graphに伝達させたいオブジェクトのTransformを設定することになります。
プロパティ名はVFX Graphに値を伝達するためのVFX Graph側のプロパティ名になります。


<img width="528" alt="スクリーンショット 2019-12-14 18.11.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141004/170be970-0ee0-9be1-525a-5b79a4d2fb24.png">

Positionというプロパティ名を指定する場合は上の画像のようにVFX Graph側でプロパティを作成する必要があります。
外部から伝達させるためにプロパティのExposedのオプションはオンにしないといけないので注意しましょう。

<img width="360" alt="スクリーンショット 2019-12-14 18.20.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141004/4939db37-4c9b-e332-8ba7-ccd94ae05611.png">

設定が完了すると、緑のマークになります。ここが緑にならない場合、設定に問題がある場合があるので見直してみてください。（大抵はVFX Graph側の設定です。）

<img width="671" alt="スクリーンショット 2019-12-14 18.21.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141004/b6b4bb36-9caa-91d0-151c-49e9fe5c60cf.png">

あとはVFX Graph側でノードに繋げれば、シーン内のパラメータを使うことができます。

## Property Binderの種類

どういったパラメータを伝達させることができるのか、いくつかProperty Binderの種類について説明します。

### Position Binder
オブジェクトのPositionの情報をVFX Graphに伝達するためのコンポーネントです。
キャラクターの位置で演出を変えたり、演出の注視点を変えたり、位置に関する動的な変更を加えるのに便利です。

### Rigid Body Collision Event Binder
Collisionにおける衝突イベントをVFX Graphに伝達するためのコンポーネントです。
VFX GraphはSpawnノードをうまく活用することで、一つのGraph内で複数のエフェクトを定義し、それらの生成タイミングを切り替えることが可能です。
その際に、生成タイミングの切り替えでこのコンポーネントを使うことで、衝突したら爆発のエフェクトに切り替えたい！といったゲームの演出でありがちな要件をスクリプトを書かずに実現することができます。

### Light Binder
Lightの色や輝度をVFX Graphに伝達するためのコンポーネントです。
シーン内のLightに合わせた演出をしたい！という場合にいい感じにこなしてくれるのがこのコンポーネントです。
対象のLightを設定するだけで色、輝度、効果範囲のパラメータをエフェクトと連動させることができます。

### Mouse Event Binder
マウスのイベントをVFX Graphに伝達するためのコンポーネントです。
これまで紹介したコンポーネントはシーンに合わせて動的に演出を変更するためのものでしたが、Mouese Event Binderはユーザー入力によってエフェクトを制御するために使用します。

### UI Dropdown Binder
uGUIのDropdownで選択した情報をVFX Graphに伝達するためのコンポーネントです。
uGUIでエフェクトのプレビュー画面が作りたい、といった時にちょっとしたスクリプトを書いて作ることはあると思うのですが、それをコンポーネントで完結させることが可能な機能です。

ここで紹介したものだけでも、様々な用途に合わせてコンポーネントが用意されているのが分かるかと思います。
個人的にはPosition Binderだけでもかなり演出の手助けになってます。

## 使ってみる
試しに簡単な例でPosition Binderを使ってみます。
まずは適当なVFX Graphのエフェクトを作成し、次のようなGraphの設定だけ追加します。

<img width="730" alt="スクリーンショット 2019-12-17 20.55.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141004/a8428493-90dc-d68c-9cbd-5aec7a1f8531.png">

ざっくり説明すると、これは特定の座標に向かって適当に加速をするような設定になっています。
まず、
パラメータとして追加したPositionノードとパーティクルの現在位置であるTransform (Position) ノードと共に差分を算出するSubstractノードに繋ぎ、現在位置からPositionまでの距離を出力します。
この値に適当な係数をMultiplyで掛けて、パーティクルの更新を行うUpdateで速度を加算するAdd Velocityブロックに繋いで完成です。

そしてエフェクトをシーン上に配置します。
エフェクト自体はこんな感じでデフォルトのテクスチャがわき出る感じになってるかと思います。

<img width="228" alt="スクリーンショット 2019-12-17 21.02.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141004/151ab76c-6201-bc7d-0939-ce4af1203af0.png">

エフェクトを配置したらPosition Binderの設定をします。
今回はわかりやすいようにSphereを生成して、その座標をPosition Binderで伝搬させてみます。

<img width="878" alt="スクリーンショット 2019-12-17 21.05.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141004/cf2acfe2-9f25-50f1-329a-5c04d6ef32de.png">

ヒエラルキーからSphereを生成して、エフェクトのオブジェクトにProperty Binderのアタッチ、及び上の画像のような設定をしたPosition Binderを設定すれば完了です。
これで先程VFX Graphで追加したPositionにSphereの座標が伝搬されます。
後はシーン上でSphereを動かしてみると...

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141004/9c441e88-fe9f-238b-1263-b45b2f4ab8f4.gif)


Sphereに沿ってエフェクトの動く方向が変わりました！
このようにランタイムだけでなく、シーン上でも確認できるので、気軽に試すことができます。

もっと応用的な例がみたい！という方は公式のリファレンスもそうなのですが、下記のブログを参考にしてみてください。

Unityで主人公が通った場所の草をなぎ倒す
https://gametukurikata.com/effect/bendgrass

上記のブログでは実際に有用な草のフィールド演出を元にしているため、応用して演出に活かすことがやりやすい内容になっています。
VFX Graphのノードの使い方についても参考になるものがあるので、興味がある方は一度読んでみて欲しいです。

### まとめ
Parameter Binderを使うことで、VFX Graphの演出の幅をかなり広げることができます。
静的な演出だったものが動的な演出になることで、コンテンツとして伝えられる表現の幅も広くすることができます。
VFX Graph、楽しいので皆さんも触ってみましょう！