3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[VFX Graph]音楽ライブにいる「サイリウム振ってる集団」をつくる

Last updated at Posted at 2021-01-16

#目次
1.はじめに
2.つくるもの
3.VFXGraphとは
4.つくりかた
5.完成品
6.参考

#1. はじめに
それはとある休日のこと。
わたしは「Unityでなんか作ってみるネタないかな」と思いながら、
ユニティちゃん Candy Rock Star ライブステージ!を眺めておりました。

そのときふいに思ったのです。
image.png

「ライブっぽいモーションなのに、観客いなくてかわいそう…」
と。
というわけで、VFX Graphを利用して
ユニティちゃんを囲む オタク サイリウム集団をつくってみます。

#2. つくるもの

先に作るもののイメージを見てもらいましょう。こんなのをつくります。

ezgif-6-84f5e5c772cd.gif

ユニティちゃんの周りを取り囲む、サイリウム集団のエフェクトです。
UNITE IN THE SKYにあわせて棒を振ってます。たのしそう

ezgif-6-0bda0b1acf9b.gif

アピったりもします。「ユニティちゃんこっちみて~」みたいな。
この2種類の動きを外部から切り替えられるようなサイリウム集団のエフェクトをこれからつくっていきます。

※ エフェクト以外のステージ、モデル、モーションは
こちらの「ユニティちゃんライブステージ! -Candy Rock Star-」を利用しています。

#3. VFXGraphとは
Visual Effect Graph
Unityの比較的新しめな機能の1つです。
「ノードベースのプログラミング環境を備えた高性能な GPU パーティクルエフェクトシステム」だそう。
ノードベースなのでわりと簡単にいろんなエフェクトが作れます。
基本的な使い方についてはUnite Tokyo 2019 の公演が超わかりやすいです。
こいつを使ってエフェクトをつくっていきます。

#4. つくりかた

VFX Graphの初期状態はこちら
gif_animation_011.gif

初期グラフはこちら
image.png

ここから以下の流れでエフェクトをつくります。

  • サイリウム単体のパーティクルをつくる
  • モーションを付ける
  • サイリウム集団をステージ状に配置して色を付ける
  • モーションを増やす

※ わりと細かく解説していくので、「細かいことは見ればわかる」「動くものが欲しい」という方は
5.完成品」までスキップしてください。

では、順にやっていきます。

環境

  • Unity 2019.4.16f1
  • Visual Effect Graph 7.3.1

サイリウム単体のパーティクルをつくる

テクスチャを貼り付けてみる

まずはサイリウムを用意しましょう。
Psyllium_white_half.png
このpngを Output Particle QuadMainTexTure に設定します。
下半分が空白になっているのは、後で行う回転処理を簡単にするためです。(後でもう一度解説します)
gif_animation_012.gif

飛んで消えてくサイリウムができました

位置を固定する

つくりたいのは飛んで消えてくサイリウムではなく「その場で動き続けるサイリウム」です。
移動と消滅を防ぐために、Output Particle Quad の内部ブロックを全部消した上で
SpawnInitialize Particleを変更します。
ついでに動きをわかりやすくするため、いったん1本だけのサイリウムにしてしまいましょう。
ブロックはこんな感じ
image.png
ポイントは Single Burst ブロック。
こいつを使うことで、パーティクルの生成を1回だけにできます。
また、Initialize ParticleCapacity が「一度に存在する最大パーティクル数」なので、こいつを1にしてしまえばサイリウムは1本しか現れなくなります。

gif_animation_014.gif
さみしいけど、まずはここから

モーションを付ける

Update Particle にブロックを追加し、フレームごとに角度情報を更新して「棒を振る動き」を表現します。
image.png
(角度ではなく角速度を与えたほうが自然な動きになりそうですが、調整が大変だったので今回は位置を直接与えます)
Periodic Total Timeで棒を振る速度を、Sample Curveで動きの挙動を表現し、Multiplyで棒を振る最大角度を設定します。
今回は「棒を振って戻す」動作を2拍で行うこととして、UNITE IN THE SKY(BPM140)およそ2拍分の時間である0.857(s)を設定しました。
ここの調整は基本的にアナログ作業です。いい感じのSample Curveを作りましょう。
また、ここで設定する回転角度は「パーティクルの中心が回転軸」となっています。
「下半分が空白となっているサイリウム画像」をパーティクルのテクスチャとして設定したのは、
この設定で回転軸がサイリウムの根本となるよう調整した結果なのでした。
gif_animation_016.gif
真正面から見るとぺこぺこしてるように見えますね。軸を固定しているので仕方ないです。
(今回は簡略化のため、回転軸の移動は行いませんでした。)

ここまでで基本となるサイリウムパーティクルの完成です。

サイリウム集団をステージ状に配置して色を付ける

作ったサイリウムを増やして観客っぽいエフェクトをつくり、ユニティちゃんのステージを囲いましょう。

サイリウムを増やす

まずは作ったサイリウムを増殖させましょう。
SpawnInitialize Particleブロックを再び変更します。
image.png

Initialize Particleは、「Positionの範囲(Killの範囲は除く)に、Capatiy個のパーティクルを生成する」という構造。
ユニティちゃんのステージを置く部分にサイリウムを生成したくなかったので、中心部分は球状にkillしています。
また、SpawnPeriodic Burstは、Count個のパーティクルを一瞬で生成してくれます。
gif_animation_017.gif

生成したパーティクルの注視点を一か所にあつめるため、OutputLookAtPositionを追加します。
image.png
これで0,0,0にユニティちゃんがいれば、サイリウム集団は全員ユニティちゃんのほうを見て棒を振るという寸法です。
image.png

角度を合わせてユニティちゃんを召喚してみると、だんだんそれっぽくなってきました。

色を付ける

サイリウムに色を付けます。Update ParticleSet Colorブロックを追加しましょう。
image.png
パーティクル単位でランダムなHSVを生成し、RGBに変換してSet Colorにつなぎます。
MaxMinでHの範囲を指定できます(今回は完全にランダム)。
image.png
カラフルですね。
また、Random Number を削除すれば、単色のサイリウムになります。
image.png
UOっぽいものとかできます。

生成位置を調整する

ここまででエフェクトはほぼ完成したのですが、生成したパーティクルは平面上に配置されているので
あまり「たくさんいる」感じがしませんね。数のわりに見栄えがちょっとさみしいです。
それに奥のひとはユニティちゃんが見にくそうで、なんだかかわいそうな気がしてきました。
ということで、武道館のように「中心から離れたサイリウムほど高い位置にいる」ように生成位置を調整しましょう。
Initialize ParticleAdd Positionブロックを追加します。
image.png
沢山ブロックをつなげていますが、やっていることはシンプルで

z = \sqrt{x^2 + y^2}

となるz座標の計算です。これでゆるやかな曲線を表現します。
各パーティクルの位置をGet Attributeで取得し、z座標を計算して格納することで
おおよそお椀型にサイリウムを生成できます。
Negateブロックでお椀の向きを反転させ、最後のMultiplyAddで倍率を調整しています。
image.png

ちょっと見栄えが良くなっていませんか?

gif_animation_021.gif
引きで見るとこんなかんじ。
これにユニティちゃんモデルとステージギミックを追加すれば、観客付きライブステージの完成です!

モーションを増やす

最後にモーションを増やして、外部から切り替えられるようにしてみます。

アピールモーションをつくる

サイリウム集団がユニティちゃんにアピールするモーションを作ってみます。
曲の最後なんかに「わーっ!」って騒いでるイメージのやつです。
エフェクトとノードをまとめて貼り付けてしまいます。
gif_animation_022.gif
image.png
回転軸がz軸であること以外は先に作った縦振りのモーションと基本的に同じですが、
Periodic Total Timeをランダム化しているのがポイントです。
実際のライブなんかでも、アピールしているときの棒振り速度は人によって違いますよね?
これが全員同じ速度だと、なんだか気持ち悪い動きになってしまいます。
gif_animation_023.gif
なんか変ですね…良い感じに速度がばらけるようランダム化しましょう。

モーションを切り替える

作ったモーションは外部から切り替えられるようにしておくと、スクリプトやTimelineで変化させることができて便利です。
外部から切り替えられるように、SwitchブロックとBlackbordを利用した上で
2種類のモーションを同時にSet Angleへつないでおきます。
image.png
SwitchブロックはTest Valueの値を確認し、0が入っていればValue0、1が入っていればValue1…といった具合に
出力を切り替えることが出来ます。
また、左の変数リストみたいなやつがBlackbordです。
ここには任意の値を格納したブロックを作成しておくことができ、そのまま変数ブロックとして利用できます。
加えてExposedオプションを有効にしておけば、コンポーネントのPropertiesから値を取得したり変更したりすることが出来るようになります。
image.png

今回は変数PsyliumMotionSwitchを作成し、その値が

  • 0なら縦振り
  • 1なら横振り(アピール)

のモーションとなるよう切り替えを行っています。
gif_animation_031.gif
Timelineで値を切り替えてみた例(今回はTimelineの解説はしません)

#5. 完成品

これにてエフェクト完成です!お疲れ様でした!
最後に完成したノードグラフを見ておきましょう。
image.png
モーションだけでなく、サイリウムの色も切り替えられるようにしてみました。(切り替えの仕組みは同じです)
また、私の手元で作成したエフェクトをpackage化してgithubに置いておいたので
手っ取り早く使いたい方は試してみてください。
(動作保証はできませんのであしからず)

#6. 参考

Visual Effect Graph(公式マニュアル)
パーティクルエフェクトが超進化する! Visual Effect Graph の基礎と応用 - Unite Tokyo 2019
UnityのVisual Effect Graphの設定と使い方

(シェーダが書ける方はこちらを参考にした方がいいかも↓)
Unity でシェーダを使って 20,000 人が音楽に合わせてサイリウム振ってる様子を作ってみた

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?