Summary

A particle system is a way of simulating many small, short-lived objects as a group rather than treating each one as a heavyweight unique entity. Smoke, sparks, rain, magic bursts, embers, and debris are common particle-system effects.

In The Nature of Code, particle systems are presented as a design-and-programming pattern built from emitters, particles, lifespan, and per-frame updates. The important idea is that the system produces rich behaviour from many simple units following the same rules (Shiffman, The Nature of Code, see source-nature-of-code).

Key ideas

  • An emitter spawns particles over time.
  • Each particle usually tracks position, velocity, acceleration, and lifespan.
  • Systems feel organic because many simple updates overlap.
  • Pooling or reuse matters when many particles are created and destroyed frequently.

In practice

For game development, particle systems sit at the intersection of simulation and feedback:

  • in code, they are collections updated each frame
  • in design, they are a major part of impact, readability, and polish
  • in Unity, many of these ideas are implemented through the editor-facing Particle System component

In practice in Unity

For a lightweight teaching version, a sprite-based particle system is often clearer than Unity’s full Particle System component because students can see the core pattern directly:

  • Particle2D.cs — one particle holding velocity, acceleration, lifespan, and colour/scale fade
  • ParticleEmitter2D.cs — spawns particles over time and applies shared forces such as gravity
  • ParticlePool2D.cs — reuses particle instances instead of constantly allocating and destroying them

This is a good bridge between the conceptual model in The Nature of Code and Unity’s higher-level VFX tools. It also makes the update pattern easier to inspect before moving to optimised engine systems. See overview-unity-nature-of-code-examples for the wider teaching route.

Scene setup for the Unity example

Use the pooled sprite-particle scripts as a small emitter lab:

  1. Create a simple circular sprite prefab named Particle2D.
  2. Add SpriteRenderer and Particle2D to the prefab.
  3. Create an empty GameObject named ParticlePool.
  4. Add ParticlePool2D to ParticlePool.
  5. Assign the Particle2D prefab to the pool.
  6. Create an empty GameObject named ParticleEmitter.
  7. Add ParticleEmitter2D to the emitter.
  8. Assign the pool object to the emitter.
  9. Press Play and tune the emitter values in the Inspector.

Start with a low emissionRate, such as 10, so each particle can be seen as an individual object before the effect becomes dense.

Code walkthrough

Particle2D owns one particle’s state. Activate() sets its position, velocity, lifetime, colours and scale range. Tick() advances age, applies acceleration to velocity, moves the Transform, fades colour and changes scale. When the particle reaches the end of its lifetime, Tick() returns false.

ParticleEmitter2D owns emission timing and live-particle updates. emissionRate is converted into an accumulator so the emitter can spawn a stable number of particles per second even when frame time varies. The emitter updates particles backwards through the list, which makes removal safe while iterating.

ParticlePool2D owns reuse. Get() returns an inactive particle or creates a new one when the pool is empty. Release() deactivates a finished particle and pushes it back onto the stack. This avoids constant allocation and destruction during an effect.

What to change first

ChangeExpected effect
emissionRatechanges density and rhythm
particleLifetimechanges trail length and how long particles remain visible
startSpeedchanges burst force
spreadDegreeschanges whether the effect is narrow or wide
constantForcecreates gravity, wind or upward drift
startColour and endColourchanges fade, heat, smoke or magic feel

Debugging checklist

  • If no particles appear, check that ParticlePool2D has a prefab assigned.
  • If particles appear once then stop, check emissionRate, emit, and pool references.
  • If Unity logs a prefab error, check that the prefab has Particle2D and SpriteRenderer.
  • If particles never fade, check particleLifetime, startColour, and endColour.
  • If the effect becomes slow, reduce emissionRate before rewriting the system.

Practice

Make three variants from the same emitter:

  1. Spark: short lifetime, high start speed, narrow spread, warm colour fade.
  2. Smoke: longer lifetime, low speed, wide spread, upward force, grey fade.
  3. Magic trail: medium lifetime, low speed, bright start colour, transparent end colour.

For each variant, write down which two values changed the feel most.

Self-test

  1. What does the emitter control?
  2. What does each particle control?
  3. Why does the example use a pool?
  4. Why does the emitter loop backwards through liveParticles?
  5. Which setting would you change first to make a trail longer?

Answers

  1. The emitter controls when particles spawn and which shared settings they receive.
  2. Each particle controls its own velocity, age, lifetime, colour fade and scale fade.
  3. The pool reuses particle objects so the effect does not constantly allocate and destroy GameObjects.
  4. Looping backwards allows the emitter to remove finished particles without shifting unprocessed items in the list.
  5. Increase particleLifetime, then adjust emissionRate if the longer trail becomes too dense.

Evidence

Shiffman presents particle systems as a layered pattern: emitter, particles, lifespan, and repeated per-frame update. The important design lesson is that complexity comes from quantity and overlap, not from making each particle individually sophisticated (Shiffman, The Nature of Code, see source-nature-of-code).

Implications

  • Particle systems are useful not just for decoration, but for communicating force, timing, and reward.
  • Pooling is part of the design pattern, not just an optimisation afterthought, because particle effects tend to create many temporary objects.
  • Sprite-based examples are ideal for teaching because they expose the system structure that Unity’s built-in component otherwise hides.

Open questions

  • When should a student move from manual sprite particles to Unity’s built-in Particle System?
  • At what scale does a per-particle MonoBehaviour become harder to justify than batched or GPU-driven rendering?

unity-particle-system-scripting | game-feel | procedural-generation | cellular-automata | steering-behaviours | overview-unity-nature-of-code-examples