All tools
ParticlesProjectilesVFX

FX Lab

Tune particle bursts and projectile arcs, export the ParticleSystem setup.

Explosion

Fast radial burst that decays hard. The short lifetime is what sells the impact — long-lived debris reads as fireworks instead.

Alive
0
Particles on screen right now.
Peak
0
Set maxParticles above this.
Lifetime
0.55 s
Blend
Additive
Reads as light

Presets

Impact

Ambient

Gameplay

Emission

40
0 /s
0.55 s
0.30
320
0.60
180°
0°

Motion & look

0
2.40
11
0
0°/s
1.00
0.00
// Explosion — generated by FX Lab
// burakkaan.dev/tools/fx-lab
// Configures a ParticleSystem module by module. Values are in Unity units:
// divide the pixel speeds/sizes below by your pixels-per-unit if you work in sprites.
using UnityEngine;

[RequireComponent(typeof(ParticleSystem))]
public sealed class ExplosionEffect : MonoBehaviour
{
    private void Reset()
    {
        var ps = GetComponent<ParticleSystem>();

        var main = ps.main;
        main.duration            = 0.55f;
        main.loop                = false;
        main.startLifetime       = new ParticleSystem.MinMaxCurve(0.39f, 0.55f);
        main.startSpeed          = new ParticleSystem.MinMaxCurve(1.28f, 3.20f);
        main.startSize           = 0.11f;
        main.startColor          = new Color(1.000f, 0.878f, 0.400f, 1.00f);
        main.gravityModifier     = 0.00f;
        main.startRotation       = new ParticleSystem.MinMaxCurve(0f, 6.28f);
        main.simulationSpace     = ParticleSystemSimulationSpace.World;
        main.maxParticles        = 120;

        var emission = ps.emission;
        emission.enabled      = true;
        emission.rateOverTime = 0.00f;
        emission.SetBursts(new[] { new ParticleSystem.Burst(0f, 40) });

        var shape = ps.shape;
        shape.enabled   = true;
        shape.shapeType = ParticleSystemShapeType.Cone;
        shape.angle     = 90.00f;
        shape.radius    = 0.05f;
        shape.rotation  = new Vector3(0f, 0f, 0.00f);

        // Drag — the difference between a spark that stops dead and one that sails.
        var limit = ps.limitVelocityOverLifetime;
        limit.enabled = true;
        limit.dampen  = 0.60f;

        var sizeOverLifetime = ps.sizeOverLifetime;
        sizeOverLifetime.enabled = true;
        sizeOverLifetime.size = new ParticleSystem.MinMaxCurve(
            1f,
            AnimationCurve.EaseInOut(0f, 1f, 1f, 0.00f));

        var colorOverLifetime = ps.colorOverLifetime;
        colorOverLifetime.enabled = true;
        var gradient = new Gradient();
        gradient.SetKeys(
            new[]
            {
                new GradientColorKey(new Color(1.000f, 0.878f, 0.400f, 1.00f), 0f),
                new GradientColorKey(new Color(0.941f, 0.243f, 0.243f, 1.00f), 1f),
            },
            new[]
            {
                new GradientAlphaKey(1.00f, 0f),
                new GradientAlphaKey(0.00f, 1f),
            });
        colorOverLifetime.color = new ParticleSystem.MinMaxGradient(gradient);

        var rotation = ps.rotationOverLifetime;
        rotation.enabled = false;
        rotation.z       = new ParticleSystem.MinMaxCurve(0.00f, 0.00f);

        var renderer = GetComponent<ParticleSystemRenderer>();
        renderer.renderMode = ParticleSystemRenderMode.Billboard;
        renderer.sortMode   = ParticleSystemSortMode.YoungestInFront;
        // Material: Particles/Additive (or URP Particles Unlit, Blending = Additive)
    }
}

Speeds and sizes are converted from the preview's pixel space by dividing by 100 — set that to your actual pixels-per-unit. Reset() runs when you add the component, so the values land as inspector defaults you can keep tweaking.