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 _pool = new List(); List _emitting = new List(); 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; } } }