VFX & Particle System
Unity には二つの粒子系があります——柔軟な CPU ベース Particle System と、GPU で数百万粒を扱える VFX Graph。炎・煙・雨・魔法 FX の選び方と、Play・Emit・SendEvent の制御を学べます。図解とシミュレーターで粒子パラメータを試し、自学にも使えます。
想像してみてください...
Particle System は手で打ち上げる花火——発射レート、角度、色を設定し、CPU が各粒子を更新します。 精密ですが数が増えると遅い。VFX Graph は産業用花火マシン——すべて GPU で並列なので 数百万粒が可能ですが、強力な GPU と URP/HDRP が必要。粒子数、対象プラットフォーム、挙動の複雑さで選びます。
概念の詳細
Particle System(別名 Shuriken)は GameObject 上のコンポーネントで、 CPU 上で粒子を生成・更新します。各粒子は位置、速度、色、サイズ、寿命を持ちます。モジュール (Emission、Shape、Velocity、Color over Lifetime、Force、Collision…)で細かく制御。向き:小さな炎、雨、雪、ヒット FX、煙——数十〜数千粒。
VFX Graph(Visual Effect Graph)はすべて GPU コンピュートシェーダーで動きます。 Shader Graph に似たノードグラフで更新ロジックを組み立てます(Initialize、Update、Output)。 良い性能で数百万粒。要件:URP または HDRP、Compute Shader 対応 GPU(2015+ の大半)、古い Android/iOS は非対応。
VFX Graph は粒子を分けます:Spawn(rate/burst)、 Initialize(初期属性)、Update(毎フレームの物理・色・サイズ)、 Output(描画方法:quad、mesh、ribbon)。コンテキストはデータフローでつながり、レンダーパイプラインのようです。
性能:Particle System はライブ粒子がおおよそ 1000 未満ならモバイル/コンソールでも問題ありません。
maxParticles で上限し、再生後は Stop Action = Disable。
VFX Graph の方がスケールしますが、対象プラットフォームでプロファイリングしてください。
Particle System と VFX Graph
| 比較項目 | Particle System | VFX Graph |
|---|---|---|
| 処理 | CPU | GPU (Compute Shader) |
| 最適な粒子数 | 100 – 10,000 | 10,000 – 10,000,000+ |
| Pipeline | Built-in, URP, HDRP | URP, HDRP only |
| Mobile | ✅ 良好 | ⚠️ 制限あり |
| Interface | Inspector module | Node graph editor |
| Script API | 完全な C# API | Limited (SetFloat, SetTexture) |
| 使うとき | 炎、雨、ヒット FX、煙 | 銀河、流体、群衆、破壊 |
ハンズオン手順(Particle System)
Particle System を作成
GameObject → Effects → Particle System、または既存 GameObject に Add Component → Particle System。
Main モジュールを設定
Duration、Looping、Start Lifetime、Start Speed、Start Size、Start Color — 基本項目。
放出形状を選ぶ
Shape モジュール:Cone(炎)、Sphere(爆発)、Box(上からの雨)、Circle(リング)。Radius と Arc を調整。
Color over Lifetime を有効化
グラデーションを追加:赤 → オレンジ → 黄 → 透明で炎をフェードアウト。
必要時にコードから再生
ps.Play() / ps.Stop() / ps.Emit(count) — または EmitParams で瞬間バースト。
インタラクティブシミュレーター
Particle System パラメータを調整し、Burst / プリセットで効果を確認。
コード例
基本Particle System の Play/Stop と、必要時のバースト Emit(例:ヒット効果)。
using UnityEngine;
public class HitEffect : MonoBehaviour
{
public ParticleSystem sparks;
public ParticleSystem smoke;
// Call on bullet impact — PlayOneShot a prefab at a position
public static void PlayAt(Vector3 pos, Vector3 normal,
GameObject fxPrefab)
{
GameObject fx = Instantiate(fxPrefab, pos,
Quaternion.LookRotation(normal));
Destroy(fx, 2f); // Clean up after 2 seconds
}
// Burst emit: 30 particles immediately, no looping
public void BurstEmit()
{
ParticleSystem.EmitParams ep = new ParticleSystem.EmitParams();
ep.position = transform.position;
sparks.Emit(ep, 30);
smoke.Play();
}
// Change particle color at runtime via Main module
public void SetColor(Color color)
{
var main = sparks.main;
main.startColor = new ParticleSystem.MinMaxGradient(color);
}
}コード例
上級C# から VFX Graph を駆動——ExposedProperty でプロパティ設定とイベント発火。
using UnityEngine;
using UnityEngine.VFX;
public class VFXController : MonoBehaviour
{
public VisualEffect vfx;
// Property IDs — must match Exposed Property names in VFX Graph
static readonly int SpawnRateID = Shader.PropertyToID("SpawnRate");
static readonly int ColorID = Shader.PropertyToID("BaseColor");
static readonly int ExplodeID = Shader.PropertyToID("OnExplode");
void Start()
{
vfx.SetFloat(SpawnRateID, 50f);
vfx.SetVector4(ColorID, new Vector4(1f, 0.5f, 0f, 1f));
}
public void Explode()
{
// SendEvent fires an event in VFX Graph (Burst spawn)
vfx.SendEvent(ExplodeID);
}
public void SetIntensity(float t)
{
// Spawn rate 0 → 500 from intensity
vfx.SetFloat(SpawnRateID, Mathf.Lerp(0f, 500f, t));
}
}📌 要点
- ▸Particle System: CPU、全プラットフォーム、<10k 粒子
- ▸VFX Graph: GPU、URP/HDRP のみ、数百万粒
- ▸Stop Action = Disable で再利用(オブジェクトプーリング)
- ▸ps.main.startColor は struct として再代入が必要
- ▸VFX Graph: SendEvent() が Burst コンテキストを発火
⚠️ よくあるミス
❌ Destroy なしで多数の PS プレハブをスポーン
何千もの Particle System が積み上がり重いラグ
✅ PS をプールするか、終了後 Destroy(fx, lifetime)
❌ ps.main.startColor.color を直接編集
struct コピー——変更が反映されない
✅ var main = ps.main; main.startColor = new MinMaxGradient(c);