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

// GDnD wiki example
// Demonstrates: a pooled particle with lifespan, force accumulation, and visual fade
// Related pages: [[particle-systems-design]], [[overview-unity-nature-of-code-examples]]
 
using UnityEngine;
 
[RequireComponent(typeof(SpriteRenderer))]
public class Particle2D : MonoBehaviour
{
    private SpriteRenderer spriteRenderer;
    private Vector2 velocity;
    private Vector2 acceleration;
    private float lifetime;
    private float age;
    private Color startColour;
    private Color endColour;
    private float startScale;
    private float endScale;
 
    public bool IsActive { get; private set; }
 
    private void Awake()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();
        Deactivate();
    }
 
    public void Activate(
        Vector2 position,
        Vector2 startVelocity,
        float lifeSeconds,
        Color initialColour,
        Color targetColour,
        float initialScale,
        float targetScale)
    {
        transform.position = position;
        velocity = startVelocity;
        acceleration = Vector2.zero;
        lifetime = Mathf.Max(0.01f, lifeSeconds);
        age = 0f;
        startColour = initialColour;
        endColour = targetColour;
        startScale = initialScale;
        endScale = targetScale;
        IsActive = true;
        gameObject.SetActive(true);
        ApplyVisuals(0f);
    }
 
    public void AddForce(Vector2 force)
    {
        acceleration += force;
    }
 
    public bool Tick(float dt)
    {
        if (!IsActive)
        {
            return false;
        }
 
        age += dt;
        velocity += acceleration * dt;
        transform.position += (Vector3)(velocity * dt);
        acceleration = Vector2.zero;
 
        float life01 = Mathf.Clamp01(age / lifetime);
        ApplyVisuals(life01);
 
        return age < lifetime;
    }
 
    public void Deactivate()
    {
        IsActive = false;
        gameObject.SetActive(false);
    }
 
    private void ApplyVisuals(float life01)
    {
        if (spriteRenderer == null)
        {
            return;
        }
 
        spriteRenderer.color = Color.Lerp(startColour, endColour, life01);
        float scale = Mathf.Lerp(startScale, endScale, life01);
        transform.localScale = Vector3.one * scale;
    }
}