~3 min read

Particle System and VFX Graph

Two visual-effects systems — when to choose each, and the basic techniques.

Visual effects in Unity are split into two large systems: the Built-in Particle System (often called Shuriken) and VFX Graph (part of the Visual Effect Graph package). They coexist and don’t compete — each has its own use case.

When to choose which

ParameterParticle System (Shuriken)VFX Graph
Where it worksEverywhere, any pipelineURP / HDRP (not Built-in)
Computed onCPUGPU (compute shader)
Maximum particles~10,000 without dropsMillions
Scripting interactionSimple (properties, methods, events)Via Exposed Properties and the Event API
Learning curveLowMedium (visual graph)
Suited forSmoke, sparks, hits — simple effectsCrowds, fluid, ribbon trails, GPU simulation

Rough rule: if the effect is simple and needed on mobile — Particle System. If you need lots of particles or a complex GPU simulation — VFX Graph.

Particle System — the main module

ParticleSystem is a component attached to a GameObject. In the Inspector — dozens of module sections you can enable and disable. The key ones in Main:

  • Duration — the length of the “emission” in seconds.
  • Looping — repeat or one-shot.
  • Start Lifetime — how long each particle lives.
  • Start Speed / Size / Color / Rotation — initial values. Can be a constant, a range, or a curve over time.
  • Simulation SpaceLocal (particles move with the GameObject) or World (they stay in place, even if the emitter has moved).
  • Max Particles — a hard limit.
using UnityEngine;

public class Explosion : MonoBehaviour
{
    [SerializeField] private ParticleSystem effect;

    public void Boom() {
        effect.Play();
    }

    private void OnParticleSystemStopped() {
        // All particles have lived out their lifetime — safe to delete
        Destroy(gameObject);
    }
}

Play(), Stop(), Pause(), Clear() are the main methods. For a one-shot effect in a script people often set the “Play On Awake” + “Stop Action: Destroy” flags on the ParticleSystem itself.

Key modules

  • Emission — emission rate: rate over time / rate over distance / bursts.
  • Shape — the source shape: Sphere, Cone, Box, Mesh, …
  • Velocity over Lifetime — how velocity changes over time.
  • Color over Lifetime — for example, sparks: yellow → red → fade out.
  • Size over Lifetime — growth or shrinkage.
  • Rotation over Lifetime — rotation of each particle.
  • Noise — adds turbulence for a more natural look.
  • Trails — trails behind each particle.
  • Sub Emitters — a particle itself becomes an emitter (explosion → flying shards → sparks from the shards).
  • Collision — particles collide with the world (cheap in Planes mode, more expensive in World).
  • Renderer — how they are drawn: Billboard (always facing the camera), Mesh, Stretched Billboard.
Sub-emitters — a game designer's best friend

A good explosion isn’t a single particle effect, but 4-5 layered ones: a flash, smoke, sparks, a shockwave, debris. Each is a separate child Particle System inside a single prefab. Sub-emitters allow chains: “a large chunk of debris emits 10 sparks when it touches the ground”.

Reacting to collisions

If you enable the Collision module and turn on Send Collision Messages, your script will receive OnParticleCollision:

private void OnParticleCollision(GameObject other) {
    // other is the object the particle hit (if it has a Rigidbody / Collider)
    if (other.TryGetComponent<Health>(out var hp)) {
        hp.TakeDamage(1); // fire burns!
    }
}

VFX Graph — GPU simulation

Visual Effect Graph is a separate package (com.unity.visualeffectgraph). An effect is described by a node graph: Spawn → Initialize → Update → Output. Similar to Shader Graph, but for the entire particle lifecycle.

Basic graph structure

[Spawn Context]       — how many particles per second


[Initialize Context]  — starting velocity, position, color, lifetime


[Update Context]      — each frame: velocity, force, turbulence, age


[Output Context]      — how it's drawn (Quad, Mesh, Lines)

Each block is a compute shader that runs on the GPU. This gives millions of particles without FPS drops.

Graph properties can be “exposed” — they appear in the Inspector of the VisualEffect component on a GameObject:

public class FireEffect : MonoBehaviour
{
    [SerializeField] private UnityEngine.VFX.VisualEffect vfx;

    public void SetIntensity(float value) {
        vfx.SetFloat("FlameIntensity", value);
    }

    public void TriggerExplosion() {
        vfx.SendEvent("OnExplosion"); // named event from the graph
    }
}

When VFX Graph is critical

  • Crowds of particles — snow, rain, a sandstorm, a locust swarm.
  • Simulations — fluids, fields, ribbons.
  • Complex portal effects — where you need thousands of particles with interactive physics.
  • VFX tightly integrated with Shader Graph — VFX Graph can read from textures and signed distance fields, and plugs natively into the renderer.

What NOT to do in the Particle System

  1. 5 different “explosion” prefabs emitted at once. Better one with sub-emitters.
  2. Mesh particles from heavy meshes. Each particle is a draw call… well, not exactly (batching helps), but it’s still expensive.
  3. Heavy computations in OnParticleTrigger. This callback is called often, and allocations here are a path to lag.
  4. A simple effect via VFX Graph “just in case”. A compute shader isn’t free; for chimney smoke the Particle System is far cheaper.

In the next chapter — Timeline and cutscenes: tying it all together into a cinematic sequence.