0 like 0 dislike
I am making a spawner that needs to have an infinite age and when a certain event happens (triggered by an attribute), spawn a single particle, not be able to spawn any more particles until the other particle is gone (8 seconds), then when the event happens again another particle spawns (or is revealed).

What I am working on now is a particle that is constantly emitting every half second and setting the life of ones I don't want to appear to 0 and then when the event happens having the life of that particle set to 10 (which gives me the 8 second actual life that I want).

The problem seems to be that the spawner script is constantly updating so if I set a compare using iif to check if "spawner.EmittedCount > emitCount" or if "timeLookedAt + 8.0f  > spawner.Age" it will always return as true which spawns 2 particles a second.

I'm not sure want I want is even possible in the spawner script but I can't really find much information on what evolver scripts are used for.
by ballen (130 points)

1 Answer

2 like 0 dislike

Hello Ballen,

There is actually a simpler solution to implement this kind of behavior:

You can just create a single particle with an infinite life that will act as the spawner for another layer with the actual particle you want to spawn:

So you can create two layer, one in the "Spawner" folder that will be the layer that will trigger the particle you want to see which will be in a layer in the "LayerGroups" folder.

Both of those layers only spawn one particle so we can setup their properties like that:

But the "RootLayer" will have an infinite life and a local space evolver so that it sticks to the position of the emitter.

You then need to add an event in the "RootLayer" that will trigger the "SpawnedLayer" when necessary:

Then we need to determine when to trigger this event. For this, you will need two additional particle fields which are the current age of the particle in second and the last time the event was triggered.

I have also added two attributes "SpawnParticle" which value is either zero or one and a "DelayBetweenSpawn" which will be 8 seconds in your case.

You can then just write an evolve script in the "RootLayer" like that:

function void Eval()
    // We want to trigger the particle spawn if the attribute "SpawnParticle" value is one
    // and if the last particle was spawned at least DelayBetweenSpawn seconds ago or if no particle was spawned before
    int shouldTrigger = SpawnParticle == 1 && (ParticleAge - LastSpawnTime > DelayBetweenSpawn || LastSpawnTime == 0);
    // Actual trigger of the event with the condition:
    // Updates the LastSpawnTime if necessary
    LastSpawnTime = iif(shouldTrigger, ParticleAge, LastSpawnTime);
    // Updates the ParticleAge (this is used instead of Age or Life which do not work for particles with infinite life)
    ParticleAge += dt;

The "SpawnedLayer" should then spawn a particle when the "SpawnParticle" attribute is equal to one and when the last particle was spawned at least "DelayBetweenSpawn" seconds ago.

Hope this helps,

do not hesitate to send us a mail at support@popcornfx.com if you need an example package for this behavior.


by Paul (7.9k points)
Hello Paul,

Thanks for your answer, I have implemented this method and I'm still getting the same results. Anytime the SpawnParticle attribute is true, the SpawnedLayer is spawned every second or so and repeats while one is spawned regardless of DelayBetweenSpaws. I am probably doing something incorrectly on my end so I will also email the support mail to ask for an example package.

Thanks again.
I got the email back from support and got everything working perfectly. The only thing I was doing incorrectly was not setting the "SpawnedLayer" to "ContinuousSpawner." After doing that, voila!

Thanks again!
Great! Glad I was able to help :)