ぷるぷるの雑記

低レイヤーがんばるぞいなブログ. 記事のご利用は自己責任で.

Unity Particle Packのエフェクトを理解する ~Dust Explosion 編 ~

UnityのParticle Systemでゲームエフェクト自作するのって大変ですよね?本を買おうにも値段が高いし、なかなか体系的にParticle Systemの効果的な使い方を学べるコンテンツは少ないと思います。しかし、アセットストアで手に入るUnity Particle Packの中には様々なプレハブが入っており、とても勉強になります。今回はその中でもDust Explosionというプレハブを見ていきたいと思います。

Unity Particle Pack とは

Unity Particle PackとはUnity Technologiesによる無料のアセットです。Standard AssetsのParticle System版みたいな立ち位置でしょうか。VRChat World を作りたい身からしたら嬉しいことが一つあります。ご存じの通りVRChat World上のゲームオブジェクトに付与するスクリプトはUdonSharp Scriptである必要があります。つまり、アセットストアからDLしたアセットがそのまま使えるとは限りません。しかし、Unity Particle Pack内のゲームオブジェクト自体にはC#スクリプトが使用されていないので、そのままVRChat World上で使用することが出来ます(.unitypackage自体にC#スクリプトが含まれていますが、Particle System自体に使用されてるわけではないので問題ないっぽい?)。実際、.unitypackageをインポートする際、C#スクリプトごとインポートしてもなんも問題ありません。ちなみに、Readmeファイルには次のように書いてあります。

f:id:prupru_prune:20220227131106p:plain
Unity Particle PackのReadme
UnityのShuriken Particle Systemを学ぶためにどうぞ見てください(超意訳)と書いてありますね。

Dust Explosionのインスタンス

それではさっそくParticle Systemのうちの一つであるDust Explosionを詳しく見ていきましょう。Unity Package PackをプロジェクトにインポートするとプロジェクトウィンドウにEffectExamplesというフォルダが出来ているので、Assets/EffectExamples/Fire & Explosion Effects/Prefabs/DustExplosion.prefabをヒエラルキーウインドウにドラッグ&ドロップすればインスタンス化の完了です。

f:id:prupru_prune:20220227133742p:plain
DustExplosion.prefabをインスタンス

ヒエラルキーを見る

DustExplosionのヒエラルキーは次のようになっています。

f:id:prupru_prune:20220227140913p:plain
DustExplosionのヒエラルキー
DustExplosionという名前の親オブジェクトに、4つの子オブジェクトが含まれていますね。計5つのゲームオブジェクトのすべてに個別のParticle Systemが付与されています。初めて知ったのですが、この5つのゲームオブジェクトのどのParticle SystemをGUIから再生させても、全てのParticle Systemが再生されるんですね。親要素を再生して子要素も再生されるならわかるんですが、どうなってるんでしょうね。まあこういう時はUnityのスクリプトリファレンスを読んでみましょう。ParticleSystem.Play()の説明を見ると、引数にbool型を与えることができるようです。trueを渡してPlay()を実行すると子要素のParticle Systemも同時に再生するようなので、おそらくGUI上のPlayボタンは、選択中のParticleSystemのルートのParticleSystem.Play(true)を実行しているのではないでしょうか。逆に個別に再生したい場合は、ゲームオブジェクトの横の目印にあるマークを無効にすればよいです。
f:id:prupru_prune:20220227143513p:plain
全ての要素が再生されてしまうので、目玉で調整
オブジェクトの表示/非表示の設定も分かったことなので、ここからはParticleSystemを一つずつ見てみましょう。

DustExplosion

まずはルートのゲームオブジェクトを見てみましょう。有効になっているのは次のモジュールです。

  • Main
  • Emission
  • Shape
  • Color over Lifetime
  • Size over Lifetime
  • Texture Sheet Animation
  • Renderer

全てのプロパティを見ていてはきりがないので、この中でも特徴的な部分を見ていきます。

Mainモジュール

Start Lifetime、Start Speed、Start Size、Start Rotation、Gravity ModifierがRandom Between two Constantsになっていてパーティクルが単調にならないようになっています。Start Colorが不透明無色なので、色は他のモジュールで設定しているようですね。

f:id:prupru_prune:20220227222716p:plain
DustExplosionのMainの設定

Emissionモジュール

Rate over Time、Rate over Distanceはともに0になっています。その代わりBurstsが設定されており、再生直後にパーティクルが生成される設定になっています。爆発というエフェクトの性質上、Burstsが適切ということでしょうか。

f:id:prupru_prune:20220227222935p:plain
DustExplosionのEmissionの設定

Shapeモジュール

ShapeがConeになってます。てっきりHemisphereかと思ってました。

Color over Lifetimeモジュール

最初は茶色(土埃の色)で、時間がたつと透明になるようになっています。徐々に土が拡散していく様を表現しているようです。

f:id:prupru_prune:20220227145817p:plain
DustExplosionのColor over Lifetimeの設定

Size over Lifetimeモジュール

下図がSize over Lifeftimeのカーブになります。徐々に小さくするのかと思ってましたが、そんなことはなかったです。Color over Lifetimeの方で自然にフェードアウトする設定は足りているようです。

f:id:prupru_prune:20220227150142p:plain
DustExplosionのSize over Lifetimeの設定

Texture Sheet Animationモジュール

特にないです。Start Frame=0、Cycles=1で普通にスプライトを再生します。

f:id:prupru_prune:20220227150728p:plain
Texture Sheet Animationの設定

Rendererモジュール

設定が多くてよくわからないですね。

f:id:prupru_prune:20220227151015p:plain
Rendererの設定
Render Mode=Billboard、つまりパーティクルが常にカメラの方向を向きます。
Normal Directionってなんでしょうね。スクリプトリファレンスを読んでもいまいちわかりませんし、数値を0 or 1に変えても見た目の差も正直ない。
MaterialはParticles/Standard Surfaceシェーダに5×5のスプライト画像が付与されたマテリアルです。
Sort Modeとはパーティクルを描画する順番だそうで、By Distance (カメラからの距離)、 Oldest in Front (古いものを表面に)、 Youngest in Front (新しいものを表面に)が選べるそうです。DustExplosionではBy Distanceになっていますが、基本的にはこれでよい模様?
Render Alignment=Viewになっており、Billboardはカメラの方向を向くようになってます。単にBillboardにするだけじゃダメなのか?
Flipはパーティクルを反転させる確率を表しているみたい。ランダムに反転させることで、パーティクルをランダムな感じにしてより自然な感じにするのでしょう。

うーん、やっぱりRenderモジュールはすべて理解しようとしないほうがいいんでしょうかね。まあDustExplosionは以上です。

Embers

ここからは1つ目の子要素であるEmbersを見ていきましょう。有効になっているのは次のモジュールです。

  • Main
  • Emission
  • Shape
  • Velocity over Lifetime
  • Color over Lifetime
  • Noise
  • Renderer

Mainモジュール

親要素と同様に様々な値がRandom Between two Constantsになっています。Gravity Modifier=0になっていますね。後述するNoiseだけのほうが火花のふわふわをよく表現できるということでしょうか。Start Colorが無色ではないのでColor over Lifetimeモジュールでは主に透明度を変更する感じでしょうか。最後に、Scaling Mode=Shapeとなっています。よくわからないですがたぶんRendererモジュールのStretched Billboardに関係していそう。

f:id:prupru_prune:20220227223325p:plain
EmbersのMainの設定

Emissionモジュール

親要素と同様にBurstsのみの設定になってますね。

f:id:prupru_prune:20220227223638p:plain
EmbersのEmissionの設定

Shapeモジュール

ShapeがHemisphereになってます。

Velocity over Lifetimeモジュール

下図のような単調減少するグラフですね。ふわっとした感じを出すために0までは落とさないんですね。

f:id:prupru_prune:20220227183716p:plain
Velocity over Lifetimeの設定

Color over Lifetimeモジュール

下図がグラフなのですが、ExplosionDustとは違い透明から始まり着色後また透明になってますね。そうすることでふわっとした感じを表現していることがうかがえます。

f:id:prupru_prune:20220227184044p:plain
Color over Lifetimeの設定

Noiseモジュール

このモジュールは結構設定が多くてよくわからないですね。スクリプトリファレンスを見た感じ、Strengthは散乱の強さ、Frequencyは散乱頻度、Scroll Speedはノイズテクスチャのuv座標をスクロールし、より不規則なノイズを生成させる値、みたいですね。

f:id:prupru_prune:20220227184153p:plain
Noiseの設定

Rendererモジュール

一番の特徴として、Render Mode=Stretched Billboardになってますね。Stretched Billboardにすると現れるプロパティとしてCamera Scale、Velocity Scale、Length Scaleがあり、いずれもパーティクルのテクスチャを引き延ばし方を規定します。EmbersではVelocity Scaleだけ0.1という値を持っていて、速さが大きいほどパーティクルが細長く見えるようになります。逆に、速さが小さいときはパーティクルの形が円形に見えるようになります(正確にはテクスチャ画像ままのように見えます)。今回のように火花のようなエフェクトにはぴったりですね。

f:id:prupru_prune:20220227185818p:plain
Rendererの設定

Embersはこれで以上になります。RenderモジュールのRender Mode=Stretched Billboardが大きな特徴でしょうか。

SmallExplosion

ここからは2つ目の子要素であるSmallExplosionを見ていきましょう。有効になっているのは次のモジュールです。

  • Main
  • Emission
  • Shape
  • Velocity over Lifetime
  • Color over Lifetime
  • Texture Sheet Animation
  • Renderer

Mainモジュール

ほとんど他のオブジェクトと同じようですが、Start Speed=0になっていますね。SmallExplosionは爆発の中心部の小さな煙を表現しているのでパーティクルは移動しなくてもよいということでしょう。Start Colorは無色ですね。

f:id:prupru_prune:20220227224256p:plain
SmallExplosionのMainの設定

Emissionモジュール

他のオブジェクトと同じようにBurstsのみ設定しています。

f:id:prupru_prune:20220227224452p:plain
SmallExplosionのEmissionの設定

Shapeモジュール

ShapeがSphereになってます。

Velocity over Lifetimeモジュール

Embersと似ていますが、2本の単調減少なグラフの間でランダムな値をとるようになっています。ただし、速度の向きは球の中心から放射状に広がる向きです。

f:id:prupru_prune:20220227224622p:plain
SmallExplosionのVelocity over Lifetimeの設定. Radialになっていることに注意

Color over Lifetimeモジュール

徐々に透明色になる設定になっています。

f:id:prupru_prune:20220227191458p:plain
Color over Lifetimeの設定

Texture Sheet Animationモジュール

とくにはないです。しいて言えば、Frame over Timeが直線になっておらず、アニメーションの後半に行くほどフレームがゆっくりになっています。

f:id:prupru_prune:20220227225014p:plain
SmallExplosionのTexture Sheet Animationの設定

Renderモジュール

Normal Direction以外はDustExplosionと同じようですね。

f:id:prupru_prune:20220227192011p:plain
SmallExplosionのRenderモジュールの設定

SmallExplosionはこれで以上になります。3つ目ともなるとあまり目新しい設定というのもないですね。

SandParticle

続いては3つ目の子要素であるSandParticleを見ていきましょう。SandParticleは破片、すなわち固体を表現しているので他のオブジェクトと異なる点が多いです。有効になっているのは次のモジュールです。

  • Main
  • Emission
  • Shape
  • Color over Lifetime
  • Texture Sheet Animation
  • Renderer

Mainモジュール

他のパーティクルとは異なり固体なので、Start SpeedとGravity Modifierが比較的大きいですね。Scaling ModeはEmbersと同様にShapeになっています。

f:id:prupru_prune:20220227225525p:plain
SandParticleのMainの設定

Emissionモジュール

パーティクル数が多いですね。他は変わらず。

f:id:prupru_prune:20220227225819p:plain
SandParticleのEmissionの設定

Shapeモジュール

ShapeはConeです。

Color over Lifetimeモジュール

不透明無色から透明色になっていますね。しかし、Scene上のSandParticleは紛れもなく(Start Colorで設定されている)茶色です。Color over Lifetimeで設定した色そのままパーティクルの色になるのではなく、Color over Lifetimeで設定された色がStart Colorにブレンドされる感じなんでしょうかね。SandParticleのColor over Lifetimeがカラーは白色で透明度だけ変化させているところを見ると、おそらくこのブレンドは乗算でしょうか。ともかく、Start ColorとColor over Lifetimeで設定した色はブレンドされるようです。

f:id:prupru_prune:20220227195419p:plain
Sand ParticleのColor over Lifetimeの設定. 最終的なパーティクルの色はStart ColorとColor over Lifetimeの色の乗算ブレンド

Texture Sheet Animationモジュール

さて、一番すごいなと思ったのがこのモジュールです。2×2のストライプを使用していますが、Frame over Time=0となっています。つまり、SandParticleではTexture Sheet Animationを有効にしていますが、ストライプアニメーションを使っていません。また、Start Frameを0から3のランダムな値にすることで、各パーティクルには4種類のテクスチャがランダムに適用されることになります。つまり、通常はTexture Sheet Animationはストライプの画像を時間に応じて切り替えることでアニメーションを表示するモジュールですが、一枚目の画像をランダムにし、画像を切り替えないようにすることでパーティクルのランダムっぽさを表現してるんですね。

f:id:prupru_prune:20220227195547p:plain
Texture Sheet Animationの設定

Renderモジュール

他のオブジェクトと同じようですね。

f:id:prupru_prune:20220227202901p:plain
Rendererの設定

以上がSandParticleオブジェクトでした。Texture Sheet Animationはスプライトアニメーションを再生するだけではないということ、MainモジュールのStart ColorとColor over Lifetimeの使い分けなど、学べることが多いオブジェクトでした。

Shockwave

最後に4つ目の子要素であるShockwaveを見ていきましょう。有効になっているのは次のモジュールです。

  • Main
  • Emission
  • Color over Lifetime
  • Size over Lifetime
  • Renderer

Mainモジュール

Shockwave、すなわち衝撃波を表現するオブジェクトなので、Start Lifetime=0.5と短かったり、Start Size=10と大きい値だったり、他の流体や固体を表現しているパーティクルとは一線を画す設定をしていることが分かります。

f:id:prupru_prune:20220227203759p:plain
ShockwaveのMainモジュールの設定

Emissionモジュール

親要素と同様にBurstsのみの設定になってますね。

f:id:prupru_prune:20220227231102p:plain
ShockwaveのEmissionの設定

Color over Lifetimeモジュール

色は常に白で不透明度だけ徐々に小さくなる設定ですね。ということはMainモジュールのStart Colorのまま徐々に透明になるだけですね。といってもShockwaveのMainモジュールのStart Colorも白色なので、単に透明度が変わるだけですね。

f:id:prupru_prune:20220227231215p:plain
ShockwaveのColor over Lifetimeの設定

Size over Lifetimeモジュール

衝撃波が徐々に遠方まで広がっていく様を表現していますね。最後に少し収縮するのがさらにそれっぽく見せていてすごいですね。

f:id:prupru_prune:20220227204742p:plain
Size over Lifetimeの設定

Rendererモジュール

Render Mode=Billboard、Render Alignment=Viewというお決まりの設定ですね。Sort Mode=Noneとなっていますが、そもそもパーティクルが1つしかないのでソートの必要がないということでしょうか。

f:id:prupru_prune:20220227205014p:plain
Rendererの設定

以上でShockwaveも最後です。このオブジェクトは粒子を発射するというより衝撃波のテクスチャ一枚絵をBillboardに表示するという感じで、他とは異なるオブジェクトでした。

その他

各オブジェクトに適用しているシェーダーの設定は次のようになっているようです。

GameObject Shader Rendering Mode Color Mode
DustExplosion Particles/Standard Surface Fade x
Embers Particles/Standard Unlit Fade Additive
SmallExplosion Particles/Standard Unlit Fade Multiply
SandParticle Particles/Standard Surface Fade x
Shockwave Particles/Standard Unlit Fade Overlay

まとめ

軽い気持ちでこの記事を書き始めましたが、そのせいで日曜日がつぶれました。しかし、その分得ることも多かったです。やはり何事もプロの仕事を見ることが上達の近道ではないでしょうか。Unity Particle Packはほかにも多くのParticle Systemが入っているので出来れば他のプレハブの記事も書きたいです。まあ、休日が一日つぶれる覚悟が必要ですね。