rj-action-library/Runtime/Actions/Node3D/PlayParticles.cs

104 lines
2.0 KiB
C#

using Godot;
using System.Collections.Generic;
namespace Rokojori
{
[Tool][GlobalClass]
public partial class PlayParticles:Action
{
[Export]
public GpuParticles3D particles3D;
[Export]
public bool usePooling = false;
[Export]
public float godotFinishedReporingBugOffset = 0.2f;
[Export]
public TimeLine timeLine;
List<GpuParticles3D> _pool = new List<GpuParticles3D>();
List<bool> _emitting = new List<bool>();
protected override void _OnTrigger()
{
if ( ! usePooling )
{
particles3D.Restart();
return;
}
if ( _emitting.Count == 0 )
{
_emitting.Add( false );
}
var p = GetFreeParticles();
if ( p == null )
{
p = DuplicateParticles();
}
this.LogInfo( "Using Particles", p );
var index = IndexOf( p );
_emitting[ index ] = true;
p.OnFinishedOnce(
() =>
{
if ( godotFinishedReporingBugOffset <= 0 )
{
_emitting[ index ] = false;
return;
}
TimeLineManager.ScheduleEventIn(
timeLine,
godotFinishedReporingBugOffset,
t => _emitting[ index ] = false
);
}
);
p.Restart();
}
public int IndexOf( GpuParticles3D p )
{
return p == particles3D ? 0 : _pool.IndexOf( p ) + 1;
}
public bool IsEmitting( GpuParticles3D p )
{
return _emitting[ IndexOf( p ) ];
}
GpuParticles3D GetFreeParticles()
{
if ( ! IsEmitting( particles3D ) )
{
return particles3D;
}
return _pool.Find( p => ! p.Emitting );
}
GpuParticles3D DuplicateParticles()
{
this.LogInfo( "Duplicating Particles" );
var duplicate = particles3D.Duplicate() as GpuParticles3D;
_pool.Add( duplicate );
particles3D.GetParent().AddChild( duplicate );
_emitting.Add( false );
return duplicate;
}
}
}