ホーム < ゲームつくろー! < Unity/パーティクル編

パーティクル編
その1 Unityのパーティクル「Shuriken」


 パーティクル(粒子)は小さな点を沢山発生させて動かす仕組みです。その点の位置に板ポリゴンやモデルを置く事で、煙や炎や魔法効果などを演出する事ができます。Unityには「Shuriken Particle」というパーティクルエンジンが最初から搭載されています。これを使うととても簡単でそして効果的な演出が作れます。ただ、パーティクルは機能よりも「使い方」「応用の仕方」がとっても大切なんです。

 そこでこの章では、Shurikenパーティクルの「機能」についていっきにざざっと見て行き、後の章で使い方を色々研究してみましょう(…と自分に言い聞かせてみました(^-^;)。



@ とりあえず世界に置いてみよう

 Unityを起動して新規のプロジェクトを立ち上げます。ヒエラルキにはMain Cameraのみ、Projectには何もない状態です。ここでメニューの[Game Object]→[Create Other]→[Particle System]を選択すると、ヒエラルキに「Particle System」というパーティクルオブジェクトが一つ作られ、Sceneにはデフォルトパーティクルが早くも出現します(^-^)

 右下にある「Particle Effect」という小さなウィンドウ、これはシーンにあるパーティクルを動かしたり止めたりスローにしたりする事ができ、結構使います。

 さて、このパーティクルのInspectorを見てみます:

どひゃーっと項目があります。最初見ると「ううっ」と尻ごみしてしまうのですが、実際はとても分かりやすい物になっています。一つ一つサンプルを交えて丁寧に見て行く事にしましょう。



A Shurikenの基本パラメータ

 Shurikenの各パラメータについて、簡単にざざっと説明します。まずは基本パラメータです。

○ Duration(継続時間)

 パーティクルを発生させる元を「エミッタ(Emitter)」と言います。Durationはそのエミッタがパーティクルを発生させる時間を秒で指定します:(以後画像をクリックするとサンプルが起動します)

あくまでもエミッタの継続時間なので、パーティクルの寿命ではありません。


○ Looping(ループ)

 Duration(継続時間)で設定した時間が来た時にパーティクル発生を終了させるか、継続してずっと発生させるかを決めます:

LoopingをOnにした時はずっと出るのですが、これはDuration時間を1周としてくるくるループしています。


○ Prewarm(事前実行)

 prewarmは「〜を予め温める」という意味ですが、Shrikenでは予めパーティクルを飛ばしておく事を意味します:

PrewarmはLoopingがOnの時だけ効果があります。サンプルを起動すると、左側のPrewarmをOffにした方はパーティクルが発生し始めますが、右側のOnにした方は起動と同時にある程度まですでに発生しています。これは、例えば常に出続けている煙など、出始めを見られたくないパーティクルの場合に重宝します。


○ Start Delay(発生遅延)

 エミッタが世界に置かれてからパーティクルが発生し始めるまでの遅延時間を設定します:

これはPrewarmがOffの時にだけ効果があります。


○ Start Lifetime(寿命)

 パーティクルが発生してから消滅するまでの寿命を秒で設定します:

サンプルを動かすと、左側の寿命を5秒に設定した方が、右の2秒に設定した方よりも長く生存しているのがわかります。

 ところで、このStart Lifetimeの設定項目の右端に小さな三角がありますね:

これをクリックすると、次のような項目がお目見えします:

これがShuriken Particleでとてつもなく大切な役目をする項目なのです。これらは設定値を変化させてくれます。Constant(定数)はすべてが設定した値になります。上の場合だと、どのパーティクルも狂い無く寿命が5秒になります。Curveを選択すると、設定欄が次のように変わります:

数字ではなくて何かボックスになりました。これはグラフになっていまして、より大きなグラフに対応しています:

グラフの横軸は時間です。これはDuration時間に対応しています。縦軸は上の場合ですとStart Lifetimeです。つまりこのグラフは、発生し始めのパーティクルはあっという間に寿命がきてしまいますが、後に発生するパーティクルになるほど寿命が延びる事がわかります。

 Random Between Two Constants(2つの定数の間をランダム)は、発生するパーティクル毎にその寿命が2つの定数の間でランダムに決定されます。このランダムさによってパーティクルの挙動はより自然になります。

 Random Between Two Curvesは、先のグラフと乱数の合わせ技であり、最も自由度の高い設定方法です:

2つの曲線が出てきます。そして、その間に色が塗られます。横軸のDuration時刻毎に、この色を塗られた縦軸範囲でランダムに寿命が決まります。上のグラフはDurationが経過する程に寿命の短い物と長い物の差が大きくなる訳です。


○ Start Speed(初速)

 パーティクルの発生初速を設定します。この数値はUnityの1単位長(1Unit)を基準としてUnit/secになっています:

左側は1秒間に5Unit進みますが、右側は20Unitも進みます。びゅーんです。Start Speedも数値をカーブ設定ができます。


○ Start Size(初期サイズ)

 パーティクルの発生時の大きさを設定します。これはパーティクルにアタッチする板ポリゴンやメッシュのスケール値になります:

これはわかりやすですよね。でも、これもまた極めて重要なパラメータで、カーブ設定もできます。


○ Start Rotation(初期回転角度)

 発生時の回転角度を設定します。これは上のような丸い形だとわかりませんので、矩形の板ポリををアタッチしました:

右は45度と設定した場合です。45度回転したまま移動していきます。


○ Start Color(初期色)

 発生時の色を設定します:

この色指定の設定方法にもカーブが使えるのですが、その中に「Gradient」というのがあります。これを選択するとこんな感じのウィンドウが出てきます:

上はちょっと色々設定した例です。上と下に短冊のような物が付いていますが、上側がα値、下側が色を表します。この色の帯は横方向にDuration時間を表しています。最初の方に発生したパーティクルは薄い赤色、真ん中辺りのパーティクルは青緑という訳です。発生したパーティクルの色が動的に変わるという事では無いのに注意して下さい:


○ Gravity Multiplier(重力)

 Y軸と反対方向へ重力をかけます。数値がプラスで下向きへ、マイナスだと上向きへ落ちて行きます:

この値は加速度なので、大きくすればするほど落下速度が飛躍的に大きくなっていきます。


○ Inherit Velocit(継承速度)

 これはエミッタが動いた時に、その動いた方向に対してパーティクルを飛ばす事ができます。数値はその速度です:

この機能を有効にするには、次の項目であるSimulation SpaceがWorldでないとうまくいかないようです。双方とも初速は0にしています。左は継承速度を設定していない(0)の場合で、初速が0なのでエミッタが動いてもその場にとどまるだけです。一方右側は継承速度を1にしたもので、エミッタが動く方向にパーティクルが投げだされています。この数値をマイナスにすると、逆にパーティクルの後ろに噴き出すような動きになります。これ、つまりはロケットなどの煙を演出するのにもってこいという訳です。


○ Simulation Space

 飛ばしたパーティクルが独自に飛んでいくかエミッタの動きにくっつくかを設定します:

Localに設定するとパーティクルがエミッタの動きに合わせて動きます。エミッタの位置から相対的になる訳です。一方Worldにするとパーティクルはエミッタの位置によらず自ら飛んでいきます。



○ Play On Awake

 エミッタを世界に置いた瞬間に発動させるか、命令あるまで沈黙させるかを指定します。


○ Max Particle

 1Duration時間内での最大パーティクル数を指定します。発生数に頭打ちを作るという事です。



B Emission(発生方法)

 Emissionはパーティクルを発生させる元となるエミッタの設定を行います。

○ Rate(発生数)

 1秒あたりのパーティクル発生数を設定します。数値を大きくするともちろん大量に出るようになります。Rateにはその下にもう一つ設定項目として「Time」と「Distance」があります。Timeを指定するとさらに下に「Bursts」という設定欄が出ます。ここのTimeに発生開始からの時間、Particlesにパーティクルの数を指定すると、その時間が来た時に指定数のパーティクルが追加で「どば!」っと出ます。一方Distanceの方はエミッタが動くと追加パーティクルが発生します:

 左側はTimeのサンプルで通常は秒間3個のパーティクルを発生させていますが、5秒置きに100個の追加パーティクルが発生します。右側はDistanceのサンプルでエミッタが1秒おきに左右に10Unit移動しています。設定値は10なので、10Unit移動すると100個のパーティクルが出る事になります。



C Shape(形状)

 エミッタの放出する方向(形状)を設定します。

○ Shape(形状)

 形状にはSphere(球)、Hemisphere(半球)、Cone(錐体)、Box(直方体)そしてMesh(メッシュ)があります。それぞれの形状を指定したエミッタのサンプルは以下の通りです:

Sphereは全方位に放射するエミッタで、花火などを表現する時に使えます。Hemisphereは半球状に放射します。Coneは指向性のあるエミッタとなります。放射角度やその半径などを設定し調節します。煙突などの煙はこれで作ると雰囲気が出ますね。Boxは立方体の中からパーティクルを発生させるエミッタです。使い道は…んー時と場合によりけりでしょうか(^-^;。最後のMeshは任意のメッシュの表面からパーティクルを発生させる事ができます。メッシュはFBXなどで予め用意する必要があります。

 それぞれのShapeタイプによって設定項目が異なります。



D Velocity over Lifetime(寿命中速度)

 発生したパーティクルの速度変化を促すパラメータです。ConstantやCurveなどの設定方法が選べます。Constantの場合は発生時の初速になります:

これは基本設定の「Start speed」との合算になるので注意して下さい。Curve等を選択すると次のような設定欄に変わります:

XYZ軸それぞれの速度の時間変化をカーブで指定できます。例えば最初は遅く、後半は速くという時間変化を付けられるわけです。



E Limit Velocity over Lifetime(寿命中速度制限)

 これはパーティクルがある速度を超えた時にその速度を意図的に制限する機能です。ピンとこない所もあるかと思いますので下記のサンプルを実行してみて下さい:

双方とも同じエミッタにしていますが、左側はLimit Velocityを付けていないもの、右側は速度が5を超えたらその速度を保つようにしたものです。起動させてみると、左側はパーティクルが上にす〜っと上がった後に勢い良く下に落ちていますが、右側は上がった辺りで速度が5になるのか、そこからは等速で下に落ちています。

 このLimit Velocity over Lifetimeには「Dampen」というパラメータがあります。これは、速度超過したパーティクルに対してどのくらいの割合でその速度を低下させるのか、というのを0〜1の間で指定します。1だと速度超過した瞬間に指定の速度になりますが、0に近づけるにつれて減速時間が長くなっていきます。これは、例えば抵抗を受ける落下物など、落下速度がそのうち一定になるような効果に使えるかもしれません。



F Force over Lifetime(寿命中力)

 パーティクルが発生してから消滅するまで与え続ける力を設定します。Velocity over Lifetimeは経過時間に対してその速度に強制設定しますが、Force over Lifetimeは指定の時刻に指定の力を「くいっ」と加えます。そのため、発生時に動いていないパーティクルの場合は重力のような等加速度運動になります:

 Force over Lifetimeにも設定方法がいくつかあり、上の例はConstantで力をかけるベクトルを指定したものです。真ん中が(-1, 2, 0)というベクトル、右が(-2, 4, 0)と真ん中の2倍の力をかけています。そのため、右側のパーティクルの方が加速が強くかかります。

 設定にカーブを使うと、時間と共に掛かる力を変化させる事ができます。煙が上空で速い流れに流されるなど、力が変化する場合などに使えそうです。



G Color over Lifetime(寿命中色)

 発生したパーティクルの色味を時間変化させます。これ、実はとても大切な設定項目です。パーティクルは発生する時に「ぱ!」と発生します。それで煙などを表現しようとすると、いきなり煙の塊が世界に登場するように見えてしまい違和感となってしまいます。消える時も同様で、いきなりぱっと消える煙はありません。これを防ぐには発生時と消滅時間際で透明度を上げていくと自然に見えます:

このサンプルの左側はColor over Lifetimeを設定していないパーティクルです。消滅時にパーティクルが「ぱ!」と消えるのがわかります。一方右側はColor over Lifetimeを設定したパーティクルです。発生時と消滅時に透明度を変化させています。色自体も時間変化させました。特に消滅時に自然に「ふわ…」と消えているのが分かると思います。ちなみに、色設定はこんな感じです:

丸い形のデフォルトパーティクルだと表現に限界はありますが、炎っぽいパーティクルを作ろうと思ったら、この辺りの設定が必須になってきます。



H Color by Speed(速度による色)

 先程のColor over Lifetimeが寿命の時刻に対する色味なのに対し、Color by Speedはパーティクルの速度に対応した色味になります:

左側はColor by Speedを付けていないパーティクルで、同じ所から同じ色でパーティクルがふわふわと上がっていきます。一方右側はColor by Speedを付けたパーティクルで、速度が上がるにつれて色味と透過度が変わっています。これは次のような色設定を行いました:

この色帯の左端と右端に対応する速度は、設定欄の次にある「Speed Range」で指定します:

この辺りは目標とするパーティクルを作りながら微調整を繰り返す所になります。



I Size over Lifetime(寿命中サイズ)

 寿命中のサイズ変化を設定する項目です:

サンプルが如実に表しているように、時間と共にサイズを変化させたい時に使います。パーティクルは同じサイズだとつまらなさが出たりしますので、この辺りで調節するとよりかっこ良くなります(^-^)



J Size by Speed(速度によるサイズ)

 Colorの時と同様に、速度によってサイズを変化させる項目も用意されています:

左側はColor by Speedの右側のパーティクルです。速度が変化してもパーティクルのサイズは一定です。それに対して右側は速度が速くなるほどサイズを小さくしています。Size by Speedはカーブでの設定となります。



K Rotation over Lifetime(寿命中回転)

 パーティクルが発生している最中の回転(1秒あたりの回転角度)を設定します。基本設定のStart Rotationは発生直後の回転角度でしたが、こちらは設定すると指定の回転速度で回転し続けてくれます:

Constantだと一定の回転速度になりますが、カーブを使うと発生してからの時間で回転速度を変化させる事もできます。またランダムで回転速度を指定する事もできるため、個々のパーティクル単位で回転が変わります。この辺りのパラメータを調節するとより自然な変化を期待できます。



L Rotation by Speed

 パーティクルの速度によって回転速度を変化させるパラメータです:

左側は速度0〜20で回転速度を0〜180にカーブで変化を付けた場合、右側は速度20〜30で回転させ始めた場合です。動かしてじ〜っと見ていると分かるのですが、右側はしばらく回転せずにそのまま昇っていき、ある速度(20Unit/sec)になった時にくるくると回転を始めます。何に使えるかなと考えると、例えばろうそくの炎の揺らめきをこれで表現できます。ろうそくの炎は根元は殆ど動きませんが、炎の先端に近付くにつれてふらふらと揺れが生じます。これをRotation by Speedで表現できそうです。



M External Forces(外力)

 パーティクルが「Wind Zone」という風の影響を受けるようになります。Wind Zoneは[Game Object]→[Create Other]→[Wind Zone]で世界に設置できます。

 Wind Zpneには「Directional」と「Spherical」という2つのタイプがあります。Directionalは一定方向に吹くグローバルな風で、External Forcesが設定されているパーティクルすべてに影響を与えます。一方のSphericalは中心に吸収点を持った掃除機のような風で、パーティクルを吸い込んで外に投げ出します:

 上のサンプルはSphericalなWind Zoneを置いた例で、目に見えるように設置場所に球体を置いています。左側はExternal Forcesを設定していないので、Wind Zoneお構いなく独自に動きます。一方右側のパーティクルにはExternal Forcesを設定しているため、Wind Zoneに吸い込まれて吐き出されています。大変にドラスティックな動きをするため、木の葉や塵などの表現にもってこいです。

○ Multiplier(乗数)

 Wind Zoneに対する影響力を設定します。数値が大きい程影響されやすくなります。



N Collision(衝突)

 パーティクルが世界にあるオブジェクトと衝突するようになります。Unity3ではある特殊な平面だけと衝突できていましたが、Unity4になってあらゆる物と衝突できるようになりました!これで表現の幅が劇的に増えます。

○ Planes/World

 パーティクルと衝突する対象物を平面限定にするかワールドにある物にするかを設定します。Unity3にはWorldはありません。Planesにすると「Planes」という項目欄が出て、ここに平面の姿勢(Transform)を持ったGameObjectをドロップできるようになります。

 一方Worldに設定すると、世界に置いてある物とゴンゴンぶつかって跳ね返るようになります。Planesに比べ計算負荷が高くなるため、使用には注意が必要かもしれませんが、見た目の効果は非常に高いです。

左側はCollisionを有効にしていないのですり抜けていますが、右側は有効にしてWorldに設定したため球面に当たって跳ね返っています。

○ Dampen

 衝突した時に吸収される力具合を指定します。0だと吸収されないため元気に跳ね返りますが、1にすると完全に吸収されてしまうためメッシュに貼り付いてしまいます:

左側はDampen = 0なのでコココココ!っと跳ね返っています。一方右側は0.8くらいに設定してみました。わずかに跳ね返った後球面をずずずっとずり落ちるので、面白い効果が演出できそうです。

○ Bounce

 反発係数、つまり物に当たって跳ね返る力強さを設定します。1にすると当たっ時の力でそのまんま跳ね返ります。0に近づける程跳ね返りが弱くなります:

左側はBounceを1にしているのでスココココ!っと元気に跳ね返ります。右側は0.2したため、殆ど跳ね返りません。雨粒などの表現に向いているかもしれませんね。

○ Lifetime Loss

 物に衝突して失う寿命を設定します:

左側はLifetime Lossを0にしているため、どれだけ当たっても寿命が余計に減りません(=自分の寿命通りに消滅する)。一方左側は0.85と高く設定しています。そのため、球に当たると寿命が殆どなくなり、途中で消滅してしまいます。

○ Min Kill Speed(消滅最小速度)

 Min Kill Speedを0より大きな値に設定すると、設定速度以下で衝突したパーティクルがその場で消滅してしまいます:

左側はMin Kill Speedを0に設定しているため、動いて衝突したパーティクルは消えることなく跳ね返ります。右側は値を10に設定しました。このサンプルのエミッタは重力を0にして弾の方向に初速10でパーティクルを飛ばしています。そのため、球に当たったパーティクルはMin Kill Speed以下と判定されて消滅。これにより右側のパーティクルは跳ね返りが無いんです。

○ Collide With

 衝突対象となるオブジェクトの種類を限定します。何とでも衝突させると判定に時間がかかってしまうため、なるべく限定させた方が良いと思います。

○ Collision Quarity(衝突精度)

 衝突の精度をHigh、Midium、Lowで設定します。Highにするとかなり厳密に判定を取りますが、その分計算時間が掛かります。Midium及びLowにすると「Voxel Size」という項目欄が出現します。これらの精度にすると、コリジョン対象の大きさを立方体で一次近似するようになります。その立方体の大きさを指定するわけです。上の球は大きさが1ですが、もし立方体の大きさを0.2などとすると、球の外側付近に近付いたパーティクルは、立方体と交差しないのでそのまますり抜けてしまいます。近似が入る分衝突判定は速くなります。



O Sub Emitters(サブエミッタ)

 Sub Emittersは一つのパーティクルから派生して発生するパーティクルを設定します。この典型例が「打ち上げ花火」です。打ち上げ花火は1つのパーティクルがひゅるるるる〜っと空を昇って行き、ある所で弾けます。これをSub Emittersで表現すると、「最初のパーティクルの寿命が尽きた時にそこから次のエミッタでパーティクルを発生させる」となります:

Sub Emittersには「Birth(発生時)」「Collision(衝突時)」「Death(消滅時)」という3つの発生のきっかけがあります。意味はもう文字通りです。

 上の打ち上げ花火の例の場合、ぴるる〜っと打ち上がる種パーティクルを最初に作ります。次にSub Emittersにある「Death」の右側のプラスボタンを押すとサブエミッタがすぐに設定されます:

ヒエラルキ上では種パーティクルの子パーティクルとして設定されます:

各パーティクルは個別に設定できますが、SubEmitterのEmissionsはRateが0(つまりデフォルト発生はしない)でTimeを0としないと発生しないようです。SubEmitterからさらにSubEmitterも発生出来ます。何段階もの複雑なパーティクルを作るには必須です。



P Texture Sheet Animation(パラパラアニメ)

 パーティクルの位置にテクスチャ内に並べたアニメーションチップをパラパラアニメの要領で再生します。STGの爆発など連続的に変化するアニメーションを表現したい時に重宝します:

上のサンプルは爆発のパラパラアニメチップをShapeをBoxにして連続的に発生させた物です。チップはこういう感じです:


※「発色弾」というフリーソフトで作成しました(^-^)

○ Tiles

 チップの並びをXYで指定します。上の場合、Xは8、Yは2となります。

○ Animation

 チップのアニメーションが全部を使うのか(Whole Sheet)、横一列単位なのか(Single Row)を指定します。上の場合はWhole Sheetですね。Single Rowを指定した場合、さらにRandom Rowというチェックボックスが出てきます。これをOnにするとパーティクルが発生する度にどれかの行が再生されます。Offにすると最初の1行目のみの再生となります。

○ Frame over Time

 パーティクルの寿命のどの時刻にどのフレームを再生するかカーブで指定します。普通は発生直後が0フレームで、発生終わりが最終フレーム、それを等間隔で再生させると思います。

○ Cycles

  パーティクルの寿命中に何周アニメーションさせるかを指定します。

 で、具体的な使用方法は、まず上のようなパラパラアニメーションな絵を1枚用意して、新規にマテリアルを作成しそれにアタッチします。上の場合はマテリアルのシェーダをParticles/Additive(加算合成)にしました。後はヒエラルキ上のパーティクルにドラッグするだけです。



Q Renderer(描画設定)

 設定の最後はRendererです(死ぬほど疲れた…orz)。

○ Render Mode

 パーティクルの位置にどういうオブジェクトを置くか指定します。デフォルトはBillboard(板ポリ)です。Stretched Billboadにすると、「Camera Scale」「Speed Scale」「Length Scale」という3つの項目欄が出てきます。Camera Scaleに0より大きい値を設定すると、カメラの動きに合わせてパーティクルが伸びます。Speed Scaleにするとパーティクルの速度に合わせてそのパーティクルが伸びます。Length Scaleは一定の長さに伸びるようです。これをうまく使うと放射状のエフェクトなど面白い効果も期待できます。

 Horizontal Billboardにすると、強制的にXY平面に平行なパーティクルになります。一方Vertical BillboardにするとXZ平面に平行なパーティクルになります。

 Meshにすると、パーティクルの位置から指定のメッシュが沢山生成されます。メッシュなのでポリゴンが爆裂するので注意です。

○ Material

 パーティクルを描画するのに使われるマテリアルを設定します。デフォルトではDefault-Paricleが設定されています。これは加算合成をするマテリアルです。ここに別のマテリアルを設定するか、シェーダを独自に書くともっと多様なパーティクル表現ができるようになります。

○ Sort Mode

 パーティクルを描画する時のソート順を指定します。パーティクルはほぼ100%透過テクスチャを使うでしょうから、このソート順が大切になります。Noneにすると特にソートしません。Distanceにするとカメラからの深度を元にパーティクルの描画が行われます。Youngest firstにすると後から発生した物が先に描画されるようになります。逆にOldest firstにすると先に発生したパーティクルが先に描画されます。

○ Sorting Fudge

 パーティクル間の描画順序を指定します。デフォルトは0で、数字が小さい程より先に描画されるようになります。描画順番に依存性があるパーティクルの場合は設定しないとおかしなことになります。

○ Cast Shadow、Receive Shadow

 パーティクルが影を生成する(Cast Shadow)もしくは影を受ける(Receive Shadow)かどうかを設定します。

○ Max Particle Size

 画面のサイズ(ビューポート)に対して、パーティクルが最大でどのくらい大きくなれるかを設定します。例えば、画面が500×500だとして、この値を0.01にすると、パーティクルは見た目で5ピクセル以上の大きさにはなれません(500×0.01=5)、これを1にすると画面サイズのパーティクルも発生出来ます(1を超える値を設定する事もできるようです)。



 ぐはー!疲れました orz。という事で、すべて網羅ではないのですが、Shurikenの機能を一通りサンプル付きで説明しました。ただ、冒頭でも述べたように、パーティクルは機能ではなくてその「使い道」「応用」がすべてです。後章で少しずつ使い道を試行錯誤して行きましょう〜(^-^)/