What's the best practice for destroying actors with an active particle system?

I’m just curious to know how other people are destroying actors which have an active particle system.

In my case, I have a fireball which impacts with the terrain. The fireball has a trail emitter attached to it. As soon as the fireball hits the ground, I stop emitting fire particles from the particle emitter. If I destroy the actor right away, the particle emitter gets destroyed as well and any fire trails instantly disappear instead of fade away.

Currently, my solution is to maintain a boolean flag to indicate whether or not the fireball is pending destruction. As soon as the fireball impacts with the ground, this flag gets toggled, I turn off the particle system, and create a hard coded “delay” which has a “destroy actor - self” at the end of it. It works, but it seems sort of “hackish” and I was wondering if anyone else has better techniques for destroying their actors while letting any particle trails finish up their particle lifetime sequences. Is there a way to just detach particles from the owning actor and put them into the global world?

You said the trail fades away right? How about hiding the fireball first with a delay and then destroy the actor (approx when trail ends)

Bumping this thread because I am also running into this issue and it is a very common feature that every engine should have. We need a better way to destroy an actor without immediately destroying all the particles that were spawned from particle system components in that actor. Something like a rocket trail is a good example but really in most use case of particles this is what is desired versus popping particles off.

What I am doing for now is basically what you suggest, deactivating the particle system and waiting to destroy the actor. Every frame it calls GetNumActiveParticles to poll if the particle system has 0 active particles left, then destroys the actor. This works well enough for a one off case but seems really sloppy to be using all over the place and error prone to have an actor stick around when for gameplay purposes it is destroyed. I have several ideas for alternatives, haven’t decided which to implement yet. Here are some options…

  1. Somehow detach the particle system from it’s parent and reattach it to GameWorldSettings actor and set bAutoDestroy to true (as if it was spawned via SpawnEmitterAtLocation). This would be ideal but I know of no way to move a component from one actor to another.

  2. Make an actor component that manages attached particles. Instead of destroying the actor directly you call something like StopParticlesAndDestroy on the particle manager. It deactivates all particle systems and iterates through all components each frame, checking if any particle systems have active particles. When all the particles are gone it destroys the owning actor. Basically packaging up our current solution in a slightly more generic way. I know this would work but it is error prone because the owning actor would still be around though it should be destroyed which could cause bugs.

  3. Create attached particle system in a separate actor that is attached to the parent. Then when the parent dies the attached particle system actor can deactivate it’s particles and be set to auto destroy so it goes away on it’s own.

Any thoughts on which idea is best, or how something like option 1 would be possible.

On hit, do once, set collision off, hide mesh, spawn whatever fireball impact effect, set lifetime for your delay. You want the attached emitter to last?

Hmm yeah that is exactly what I am currently doing and want to find a better way.

This is not a good solution because nearly every actor in my game can have any number effects attached to it and there isn’t a single case where I want the particles to disappear immediately. So if I was to do that, pretty much every single actor must have a long delay when it is destroyed (which can happen in more ways then just a hit event) to account for the longest particle life time of any effect that could be attached. And a simple delay is not enough to solve the issue because it needs to ignore any other thing the actor can normally do, so it also needs to be put into a special dead state and check for that in other places. The worst problem is just that it is error prone to have dead actors sticking around like that with any number of components attached to them that also need to be removed or put in a special dead state.

Ideally this would be more automatic, rather then requiring extra hacky workaround code duplicated a hundred times throughout our project. If it was possible to design a simple function call to move the particle systems to a persistent actor where they can die off, or something to streamline the process that would be perfect.

@FrankForce Did you find a solution? I’ve been looking for the past week on how to do this without a “hacky workaround”. No luck.

Does this help you?