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;
}
}