menu_bookDocumentation

Custom Particle Controller: Code-Based Particle Simulation with Threading

calendar_today May 20, 2026 schedule ~1 min read person PatrickJr verified 50

The s&box particle system allows custom code-based particle controllers by inheriting from ParticleController. Add the component to a GameObject with a ParticleEffect to control particles via code.

Basic Example

CSHARP
public class MyParticleController : ParticleController
{
    protected override void OnParticleStep( Particle particle, float delta )
    {
        // Apply gravity
        particle.Velocity += Vector3.Down * 900 * delta;
    }
}

OnParticleStep

Called for each particle every step. The delta is game time delta multiplied by the particle system's time delta. This runs on a thread — don't create callbacks, delete GameObjects, or modify components here.

Before and After Step

OnBeforeStep and OnAfterStep run on the main thread for safe operations:
CSHARP
public class MyParticleController : ParticleController
{
    Action callbacks;

    protected override void OnBeforeStep( float delta )
    {
        callbacks = null;
    }

    protected override void OnParticleStep( Particle particle, float delta )
    {
        if ( particle.Age > 10.0f )
        {
            lock ( this )
            {
                callbacks += () => SceneUtility.Instantiate( myPrefab, particle.Position );
            }
        }
    }

    protected override void OnAfterStep( float delta )
    {
        callbacks?.Invoke();
        callbacks = null;
    }
}

Use lock when accumulating callbacks from the threaded step, then invoke them safely in OnAfterStep.

Was this helpful?