Source file unity-csharp/nature-of-code/particle-system-2d/ParticleEmitter2D.cs from the GDnD code examples. Download raw file

// GDnD wiki example
// Demonstrates: a simple 2D particle emitter using pooled sprite particles
// Related pages: [[particle-systems-design]], [[overview-unity-nature-of-code-examples]]
 
using System.Collections.Generic;
using UnityEngine;
 
public class ParticleEmitter2D : MonoBehaviour
{
    [SerializeField] private ParticlePool2D pool;
    [SerializeField] private float emissionRate = 24f;
    [SerializeField] private float particleLifetime = 1.5f;
    [SerializeField] private float startSpeed = 2.5f;
    [SerializeField] private float spreadDegrees = 50f;
    [SerializeField] private Vector2 constantForce = new Vector2(0f, -1.5f);
    [SerializeField] private Color startColour = Color.white;
    [SerializeField] private Color endColour = new Color(1f, 1f, 1f, 0f);
    [SerializeField] private float startScale = 0.15f;
    [SerializeField] private float endScale = 0.02f;
    [SerializeField] private bool emit = true;
 
    private readonly List<Particle2D> liveParticles = new List<Particle2D>();
    private float emitAccumulator;
 
    private void Update()
    {
        float dt = Time.deltaTime;
 
        if (emit && pool != null)
        {
            emitAccumulator += emissionRate * dt;
 
            while (emitAccumulator >= 1f)
            {
                emitAccumulator -= 1f;
                EmitOne();
            }
        }
 
        for (int i = liveParticles.Count - 1; i >= 0; i--)
        {
            Particle2D particle = liveParticles[i];
            particle.AddForce(constantForce);
 
            if (particle.Tick(dt))
            {
                continue;
            }
 
            liveParticles.RemoveAt(i);
            pool.Release(particle);
        }
    }
 
    private void EmitOne()
    {
        Particle2D particle = pool.Get();
        if (particle == null)
        {
            return;
        }
 
        float angle = Random.Range(-spreadDegrees * 0.5f, spreadDegrees * 0.5f);
        float radians = angle * Mathf.Deg2Rad;
        Vector2 direction = new Vector2(Mathf.Sin(radians), Mathf.Cos(radians));
        Vector2 velocity = direction * startSpeed;
 
        particle.transform.SetParent(null);
        particle.Activate(
            transform.position,
            velocity,
            particleLifetime,
            startColour,
            endColour,
            startScale,
            endScale
        );
 
        liveParticles.Add(particle);
    }
}