今回はUnityのParticleSystemの設定項目について見ていきたいと思います。
UnityのParticleSystemを使えばゲーム内で使用するエフェクトを自分で作成する事が出来ます。
以前からParticleSystemを使って血のエフェクトの作成をしたり、
作成したエフェクトをスクリプトからゲーム内に登場させる。
等を行ってきました。
今後、ParticleSystemを使う時にもっと細かく設定項目の内容を知ることが出来れば作りたいエフェクトが作れるかなと思ったので、今回の記事を作成する事にしました。(*‘∀‘)
自分用の記録記事ってわけですね。(-_-)
ParticleSystemの設定項目を見ていく
ParticleSystemはヒエラルキー上で右クリック→Effects→Particle Systemを選択する事で作成出来ます。
作成したParticleSystemを選択するとインスペクタに設定項目が表示されます。
モジュール毎に分かれており、使用したいモジュールを選択するとそのモジュールを使用します。
それではParticleSystemの設定項目を見ていきましょう。
メインモジュール
まずはParticleSystemのメインモジュール設定を見ていきましょう。
それぞれの設定項目の右側に↓の矢印項目があるものは、値をどのように決めるかの設定が出来ます。
Constant(1つ)、Curve(カーブで設定)、Random Between Two Constants(2つの間でランダム)、Random Between Two Curve(2つのカーブ内でランダム)を選べます。
これ以降のモジュールでも同じように右側に↓の矢印がある項目がありますが、説明は同じなので割愛します。
Emissionモジュール
Emissionモジュールはパーティクルの放出の設定項目です。
Shapeモジュール
Shapeモジュールはパーティクルを放出する場所の形状等を設定出来ます。
上の画像のような形状からパーティクルを放出します。Mesh RendererはMesh Rendererコンポーネント、Skinned Mesh RendererはSkinned Mesh Rendererコンポーネントを持っているゲームオブジェクトを指定する事が出来ます。
Shapeの設定によってその下に表示される形状の設定項目が変わります。
一部違う設定項目になるのでまずはそれを見ていき、最後に共通部分を見ていきます。
Sphere、Hemisphereで表示される項目
Radiusは半径です。
Radius Thicknessは半径の厚さです。0だと外面から、1だと全体からパーティクルを放出します。
Cone、Circleで表示される項目
Angleはコーンの角度。
Radiusは半径。
Radius Thicknessは半径の厚さ。
Arcはパーティクルを放出する円弧の角度を指定します。
Modeはどのように円弧の周りにパーティクルを放出するかです。Randomはランダムに、Loopは円弧の周りに連続的に、Ping-PongはLoopと同じですが1週したら反対方向になります。Burst Spreadは形状の周りに均等に分散します。
Spreadは広がりの設定です。
Speedは放出位置が円弧の周りを移動する速度です。
Emit Fromはパーティクルを放出する位置で、Baseはコーンのベース部分から、Volumeは内部からでLengthでコーンの長さを指定出来ます。
CircleはAngleやEmit Fromはありません。
Donutで表示される項目
Radiusはドーナツ全体の半径。
Donut Radiusはドーナツの厚みの円の半径。
Radius Thicknessはパーティクルを放出する場所の設定で、0はドーナツの外側、1は領域全体から放出されます。
後はSphereのArcの設定項目等と同じです。
Boxで表示される項目
Emit Fromはどこからパーティクルを放出するかで、Volumeは体積全体、ShellはBoxを形成している外面、Edgeは外面を形成している辺。
ShellとEdgeはBox ThicknessでXYZの値を設定する事が出来、0は外側、1は領域全体となります。
Mesh、Mesh Renderer、Skinned Mesh Rendererで表示される項目
Typeはパーティクルが放出される位置を指定します。Vertexは頂点から、Edgeは辺から、Triangleは面の三角形部分(面を三角形で構成しているので面)からになります。
MeshやMesh Renderer、Skinned Mesh Rendererにはそれぞれ対応するMesh、Mesh Rendererコンポーネントを持つゲームオブジェクト、Skinned Mesh Rendererコンポーネントを持つゲームオブジェクトを指定します。
Single Materialは特定のサブメッシュから放出する場合にチェックし、数値はマテリアル番号を指定します。
Use Materialにチェックを入れると設定したメッシュの頂点カラーをパーティクルに適用します。
Normal Offsetは放出するメッシュの面からの法線方向の距離を指定します。
Rectangleは設定する項目が個別にありません。
Shapeモジュールの共通項目
一部Shapeの設定によって変わりますが、ほとんど同じなので一括で見ていきます。
ここまでの設定は元のパーティクルの色やアルファ値(透明度)に指定したテクスチャの色やアルファ値をかけて変化させる項目のようです。
Velocity over Lifetimeモジュール
Velocity over Lifetimeモジュールはパーティクルが生成されてから消滅するまでの速度の設定が出来ます。
Limit Velocity over Lifetimeモジュール
Limit Velocity over Lifetimeモジュールはパーティクルが生成され消滅するまでのパーティクルの速度の減衰の設定をすることが出来ます。
Multiply by SizeはDragの値によってパーティクルのサイズが大きいほど抵抗が大きくなります。
Multiply by VelocityはDragの値によってパーティクルの速度が大きいほど抵抗が大きくなります。
Inherit Velocityモジュール
Inherit Velocityモジュールは時間経過でParticleSystemのオブジェクトの移動に対してのパーティクルの速度変化についての設定です。
Inherit Velocityモジュールを有効にしてParticleSystemのゲームオブジェクトを動かすとパーティクルの速度に変化が現れます。
Force over Lifetimeモジュール
Force over Lifetimeモジュールではパーティクルに力を加えることが出来ます。
Color over Lifetimeモジュール
Color over Lifetimeモジュールはパーティクルの生存期間での色と透明度の遷移を設定出来ます。
Colorの色の部分をクリックするとGradient Editorが開きます。Gradient Editorの設定の↓の矢印部分が透明度の設定マークで、↑の矢印部分が色の設定マークになります。
左側がパーティクル生成時、右側がパーティクル消滅時になるのでそこにマークを追加し、パーティクルの色や透明度を変化させていくということになります。
マークは追加したい部分をクリックし、削除したい時は選択した状態でDeleteキーを押します。
Color by Speedモジュール
Color by Speedモジュールでは速度によってパーティクルの色を変化させる設定が出来ます。
Size over Lifetimeモジュール
Size over Lifetimeモジュールはパーティクルの生存期間でサイズを変化させる設定が出来ます。
Size by Speedモジュール
Size by Speedモジュールは速度によってサイズがどのように変化するかを設定出来ます。
Rotation over Lifetimeモジュール
Rotation over Lifetimeではパーティクルの生存期間での角度の変化を設定出来ます。
Rotation by Speedモジュール
Rotation by Speedモジュールでは速度に応じて回転する角度を設定出来ます。
Speed Rangeが設定出来るのはAngular Velocityの右の矢印でCurve系の設定をした時だけです。
External Forcesモジュール
External Forcesモジュールを有効にすると、Wind Zoneによる影響を設定する事が出来ます。
Wind Zoneに関しては
の記事や
を参照してみてください。
Noizeモジュール
Noiseモジュールでパーティクルの動きにノイズを加える設定が出来ます。
Collisionモジュール
Collisionモジュールはパーティクルが他のゲームオブジェクトと衝突した時の設定をすることが出来ます。
Typeで選択したものによってこの後の項目が変わります。
ここでSend Collision Messagesにチェックを入れた時に発生するOnParticleCollisionメソッドについて見ていきます。
Send Collision Messagesにチェックを入れるとParticleSystemのゲームオブジェクト、衝突したコライダを持つゲームオブジェクト、またはその両方を持つゲームオブジェクトでOnParticleCollisionメソッドが呼び出されます。
そこで以下のようなスクリプトを作成し、ParticleSystemを持つゲームオブジェクトと衝突されるゲームオブジェクトに取り付けます。
1 2 3 4 5 6 7 8 9 10 11 12 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class ParticleCollisionTest : MonoBehaviour { private void OnParticleCollision(GameObject other) { Debug.Log("メソッドが呼ばれた側" + gameObject.name + " 衝突した相手" + other.name); } } |
すると衝突したパーティクル側、衝突されたゲームオブジェクト側のどちらもOnParticleCollisionメソッドが呼ばれることが確認出来ました。
Triggers
Triggersモジュールはパーティクルが接触した時の動作を設定する事が出来ます。
コライダの発生タイミングは4つあります。
それぞれIgnore(無視)、Kill(消滅)、Callback(イベントをトリガー)を選択できます。
少し勘違いしやすいのがCollidersに設定するコライダはパーティクルが接触する相手のコライダを指定する事です。
ここで接触相手のコライダを設定しない限りコライダの接触判定は行われません。
スクリプトでの操作について少し見ていきます。
例えばInside、EnterにCallbackを指定したとします。
CallbackにするとイベントをトリガーするのでOnParticleTriggerメソッド内でトリガー条件に合致するものを取得する事が出来ます。
OnParticleTriggerメソッド自体はParticleSystemのTriggersにチェックを入れると呼び出されるようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | using System.Collections.Generic; using UnityEngine; public class ParticleTriggerTest : MonoBehaviour { private ParticleSystem ps; private List<ParticleSystem.Particle> insideLists = new List<ParticleSystem.Particle>(); private List<ParticleSystem.Particle> outsideLists = new List<ParticleSystem.Particle>(); private List<ParticleSystem.Particle> enterLists = new List<ParticleSystem.Particle>(); private List<ParticleSystem.Particle> exitLists = new List<ParticleSystem.Particle>(); private void Start() { ps = GetComponent<ParticleSystem>(); } void OnParticleTrigger() { if (ps != null) { // トリガーされたイベント毎にリストにパーティクルを保持し、パーティクルの数を取得する int insideNum = ps.GetTriggerParticles(ParticleSystemTriggerEventType.Inside, insideLists); int outsideNum = ps.GetTriggerParticles(ParticleSystemTriggerEventType.Outside, outsideLists); int enterNum = ps.GetTriggerParticles(ParticleSystemTriggerEventType.Enter, enterLists); int exitNum = ps.GetTriggerParticles(ParticleSystemTriggerEventType.Exit, exitLists); // コライダに侵入したパーティクルの最小寿命を0にする for (int i = 0; i < enterNum; i++) { ParticleSystem.Particle p = enterLists[i]; p.remainingLifetime = 0f; enterLists[i] = p; } // コライダ内のパーティクルの最小寿命を0にする for (int i = 0; i < insideNum; i++) { ParticleSystem.Particle p = insideLists[i]; p.remainingLifetime = 0f; insideLists[i] = p; } // パーティクルの変更値を反映させる ps.SetTriggerParticles(ParticleSystemTriggerEventType.Enter, enterLists); ps.SetTriggerParticles(ParticleSystemTriggerEventType.Inside, insideLists); } } } |
上のスクリプトをParticleSystemのオブジェクトに取り付けます。
このスクリプトでは設定したコライダに接触、コライダ内に入ったパーティクルを削除しています。
削除するだけならEnterやInsideをKillにすれば出来ますが、今回はスクリプトでパーティクルを操作したい時の為のサンプルなので気にしないでください。
GetTriggerParticlesでイベントが発生したパーティクルのリストを取得出来ます(Callbackにしていない場合は取得出来ない)。
そのイベントがトリガーされたパーティクルのremainingLifetime(パーティクルの最小寿命)を0にし、ParticleSystemのSetTriggerParticlesメソッドでそのパーティクルを再設定し、消滅するようにしています。
OnParticleTriggerメソッド内でpsがnullでないかどうかを判定していますが、これはParticleSystemのメインモジュールのPrewarmをチェックしているとStartメソッドでParticleSystemの参照がpsに入っていないことがある為です。
取得したパーティクルのリストからパーティクル1つ1つに対する何らかの処理をしたい時はCallbackにして操作出来ます。
TriggerモジュールとCollisionモジュールは似ていますが、Collisionの場合は衝突が発生し、パーティクルが移動してしまいます。パーティクルが何らかのゲームオブジェクトと接触したが衝突はさせずに接触したという状況で何らかの事をしたい時はTriggerが良さそうですね。
Sub Emittersモジュール
Sub EmittersモジュールはメインのParticleSystemの特定の段階でサブのパーティクルを発生させる為の設定です。
Sub Emittersでは自身の子要素に配置したParticleSystemを設定し、自身の特定のタイミングで子要素のParticleSystemのパーティクルを発生させます。
タイミングとしてはBirth(パーティクルが発生した時)、Collision(パーティクルが衝突した時)、Death(パーティクルが消滅した時)、Trigger(パーティクルが接触した時)、Manual(スクリプトから)となります。
タイミングがCollision、Death、Trigger、Manualの場合は子要素のサブエミッターとして使うParticleSystemはEmissionモジュールのBurstsを設定しておく必要があります。
上はサブエミッターとして使う子要素のParticleSystemのEmissionモジュールの設定です。
Inheritでは親のパーティクルシステムのプロパティ値を子のパーティクルシステムのプロパティに継承することが出来ます。
継承出来るプロパティ値はColor、Size、Rotation、LifetimeでEverythingを選択すると全てのプロパティ値を継承します。
サブエミッターの使い方は文字だけだとわかりにくいので少しサンプルを作成してみます。
ヒエラルキー上で右クリック→Effects→Particle Systemを選択し親のパーティクルシステムを作成し、
上のようにCubeにパーティクルがぶつかるような感じで設定を行います。
CollisionモジュールでTypeをWorldにし、物理的に当たるようにします。
次は今作成したParticleSystemの子要素に新たにParticleSystemを作成し、名前をSub Particle Systemとします。
子要素のParticleSystemのEmissionモジュールを有効にし、Burstsを追加します。
Rendererモジュールを有効にし、Materialの部分を適当なマテリアルを設定します。
これで子要素のパーティクルシステムの設定が終わったので、親のパーティクルシステムを選択し、Sub Emittersに子要素のパーティクルシステムをドラッグ&ドロップして設定し、タイミングにCollisionを選択します。
すると、
上のように親のパーティクルがCubeにぶつかるとその位置から子のパーティクルが発生します。
タイミングをManualにした時にスクリプトからサブエミッターを起動する方法もやってみましょう。
親のパーティクルシステムのCollisionモジュールを有効にし、他のゲームオブジェクトと衝突出来るようにしておきます。
親のパーティクルシステムのゲームオブジェクトに以下のスクリプトを取り付けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using System.Collections; using System.Collections.Generic; using UnityEngine; public class SubEmittersTest : MonoBehaviour { private ParticleSystem ps; // Use this for initialization void Start () { ps = GetComponent<ParticleSystem>(); } private void OnParticleCollision(GameObject other) { ps.TriggerSubEmitter(0); } } |
StartメソッドでParticleSystemコンポーネントを取得します。
OnParticleCollisionメソッドはパーティクルが衝突した時に呼ばれるので、その時にParticleSystemのTriggerSubEmitterメソッドに設定したサブエミッターの番号を指定し、そのサブエミッターをトリガーしています。
Texture Sheet Animationモジュール
Texture Sheet AnimationモジュールはTextureを使ってパーティクルのグラフィックを静止画でなくアニメーションを用いることが出来るようになります。
GridモードはRendererモジュールに設定したMaterialをタイル毎に分けその分割した画像をアニメーションにし、Spriteはスプライト内の個々の画像をアニメーションにします。
このモジュールも説明だけ見ると分かりづらいのでサンプルを作成してみます。
まずは以下のような画像を用意します。
Unityに取り込みます。
次にGridモードで使用する為に、Assetsエリアで右クリック→Create→Materialを選択し、名前をNumberMaterialとします。
NumberMaterialのインスペクタのAlbedoに先ほど作成し取り込んだ画像をドラッグ&ドロップします。
ParticleSystemのRendererモジュールのMaterialにNumberMaterialをドラッグ&ドロップします。
次にTexture Sheet Animationを有効にします。
上のようにTilesのXYを2にし、Textureを縦横2分割にして4つの領域をアニメーションするようにします。
Frame over Timeは
上のようなグラフにし、パーティクル生存期間中に4→0へと遷移するようにします。
こうすることで作成した4つの領域が順番にアニメーションされていく為、4、3、2、1というアニメーションになります。
ModeをSpriteにする時はUnityに取り込んだ数字の画像をSpriteにしSprite Editorでアニメーションに使う画像に分割します。
上のようにSpriteの画像を4分割にします。
Texture Sheet AnimationのModeをSpriteにし、個々の画像を設定します。
RendererモジュールのMaterialにはNumberMaterialを設定しておきます。
後はGridモードと同じような感じでアニメーション設定を行います。
Lightモジュール
Lightモジュールはパーティクルが光を放射する為の設定が出来ます。
それでは実際にPoint Lightを設置してそれをParticleSystemのLightモジュールに設定し、パーティクルが光を放射するサンプルを作成してみます。
まずはヒエラルキー上で右クリック→Light→Point Lightを選択します。
上のようにRangeを10にし、Colorを赤色にしました。
Transformが影響しないことを確認する為、Xの位置を-1000にしました。
ParticleSystemのLightモジュールに作成したPoint Lightを設定します。
Point Lightの色を使用する為に、Use Particle Colorのチェックを外しました。
上のようになりました。
Trailsモジュール
Trailsモジュールはパーティクルに軌跡を設定する事が出来ます。
Modeによって、多少設定項目が異なるのでまずはParticleの設定項目を見ていきます。
次はModeがRibbonの時の設定項目です。
Modeで設定が変わるのはここまでで後は共通の設定項目になります。
Trailsモジュールを使ったサンプルを作成してみましょう。
メインのParticleSystemの子要素にサブエミッターとして使用するParticleSystemを設置している状態にします。
メインのParticleSystemのTrailsにチェックを入れますが、軌跡に使用するマテリアルがRendererのTrail Materialに設定されている必要がある為、そこに設定をします。
子要素のParticleSystemのTrailsを有効にし、ModeをRibbonにし、Split Sub Emitters Ribbonにチェックを入れます。
メインのParticleSystemのSub Emittersで子要素のParticleSystemを設定し、Collisionでサブエミッターが軌道するようにしておきます。
Collisionモジュールも有効にし、他のゲームオブジェクトと衝突出来るようにしておきます。
これで設定が出来たので確認してみましょう。
メインのパーティクルは通常の軌跡でサブのパーティクルではリボンでパーティクルが連結されているのがわかります。
custom Dataモジュール
Custom Dataモジュールはパーティクルにアタッチ出来るカスタムのデータをエディターで定義出来るようです。
スクリプトとシェーダーでこのデータを使うようですが、使い方がわからない為、この項目は省略させて頂きます・・・・・(-_-)
Rendererモジュール
Rendererモジュールはパーティクルの表示に関する設定を行う事が出来ます。
Render ModeがStretched Billboardの時だけ設定出来る項目があるのでそれについて見ていきます。
Motion Vectorsに関しては
や
UnityスクリプトリファレンスーRenderer.motionVectorGenerationModeー
を参照してください。わたくしにはわかりませぬ・・・・(-_-)
一部わからない部分はだいぶ端折ってあります・・・・(^_^;)
詳細は最後に記載した参考サイトのUnityマニュアルから見てみてください。
終わりに
ここまででParticleSystemの全モジュールの設定項目を見てきました。
本来であればこの後は
「実際にサンプルのパーティクルを作成してみましょう!」という「僕の悪い癖」(杉下右京風)が出てしまうところですが、
さすがに
「もう疲れたよパトラッシュ」(ネロ風)状態になるまで疲弊しているので、パーティクルの実例はまた今度別の機会にでも記事に出来たらと思っております。
参考サイト
正確で詳細な内容はUnityマニュアルの
上の記事から順に辿ると設定項目の詳細が書かれています。