namespace Sandbox;
///
/// Particles can have extra controllers that can modify the particles every frame.
///
public abstract class ParticleController : Component, Component.ExecuteInEditor
{
///
/// The particle we're controlling
///
public ParticleEffect ParticleEffect { get; set; }
protected override void OnEnabled()
{
base.OnEnabled();
ParticleEffect = Components.GetInAncestorsOrSelf();
if ( ParticleEffect is not null )
{
ParticleEffect.OnPreStep += OnBeforeStep;
ParticleEffect.OnStep += OnParticleStep;
ParticleEffect.OnPostStep += OnAfterStep;
ParticleEffect.OnParticleCreated += OnParticleCreatedInternal;
ParticleEffect.OnParticleDestroyed += OnParticleDestroyedInternal;
}
else
{
Log.Warning( $"No particle effect found for {this}" );
}
}
protected override void OnDisabled()
{
base.OnDisabled();
if ( ParticleEffect is not null )
{
ParticleEffect.OnPreStep -= OnBeforeStep;
ParticleEffect.OnStep -= OnParticleStep;
ParticleEffect.OnPostStep -= OnAfterStep;
ParticleEffect.OnParticleCreated -= OnParticleCreatedInternal;
ParticleEffect.OnParticleDestroyed -= OnParticleDestroyedInternal;
ParticleEffect.OnControllerDisabled( this );
}
}
///
/// Called before the particle step
///
protected virtual void OnBeforeStep( float delta )
{
}
///
/// Called after the particle step
///
protected virtual void OnAfterStep( float delta )
{
}
///
/// Called for each particle during the particle step. This is super threaded
/// so you better watch out.
///
protected virtual void OnParticleStep( Particle particle, float delta )
{
}
protected virtual void OnParticleCreated( Particle p )
{
}
void OnParticleCreatedInternal( Particle p )
{
try
{
OnParticleCreated( p );
}
catch ( System.Exception e )
{
Log.Warning( e );
}
}
void OnParticleDestroyedInternal( Particle p )
{
try
{
OnParticleDestroyed( p );
}
catch ( System.Exception e )
{
Log.Warning( e );
}
}
protected virtual void OnParticleDestroyed( Particle p )
{
}
}