- Home /
The question is answered, right answer was accepted
Auto-destroying particle system
I'm going through the 3D Buzz 2D shooter tutorial series and they obviously use an earlier version of Unity as the options for particle systems has changed beyond recognition. In the older version there was a tick box to tell the particle system to auto-destroy once it's finished playing. The new version of Unity doesn't have that option and as a result every time I kill an enemy an empty particle system is left behind after the explosion finished playing, which is obviously not good.
How do I destroy them now?..
Answer by Jenster · Jun 12, 2012 at 05:36 AM
I have some particle systems that are one-shots, so here is what I do to auto-destroy them when they are complete. IsAlive() is the key method. Just attach this script, fire off the system any way you like, and it will autodestroy.
private var ps : ParticleSystem;
////////////////////////////////////////////////////////////////
function Start () {
ps = GetComponent(ParticleSystem);
}
function Update () {
if(ps)
{
if(!ps.IsAlive())
{
Destroy(gameObject);
}
}
}
In C#
using UnityEngine;
using System.Collections;
public class ParticleSystemAutoDestroy : $$anonymous$$onoBehaviour
{
private ParticleSystem ps;
public void Start()
{
ps = GetComponent<ParticleSystem>();
}
public void Update()
{
if(ps)
{
if(!ps.IsAlive())
{
Destroy(gameObject);
}
}
}
}
This is the winner right here. This needs to be accepted as the answer. It makes the most sense, if you're wanting the particles to destroy themselves on completion, do just have them destroy themselves on completion, lol. No need to specify the time. :)
Some truth here, but ideally you'd want to return the particle system to a pool for re-use later. Constantly creating/instantiating/destroying objects can/will impact performance.
Well done. I implemented this on my project and it worked flawlessly. Thanks!
I think this will be slightly easier. Came up with this just after watching one of a good standard tutorials (Space Shooter):
Attach this script right to the Particle System object:
using UnityEngine;
using System.Collections;
public class DestroyParticles : $$anonymous$$onoBehaviour
{
private IEnumerator Start()
{
yield return new WaitForSeconds(GetComponent<ParticleSystem>().duration);
Destroy(gameObject);
}
}
Literally we are interrupting Start() method to wait for ParticleSystem.duration in seconds, then we get back in method and continuing from next line and destroying ParticleSystem object. Not very complex code, and i think it more efficient, because you don't need to call method update for checking =)
Because I don't know deep theory well, i must only say: for more info take a look at Space Shooter tutorial (video number 12-13) and Coroutine tutorials linked below on of them.
That guy below got even better solution... Destroy with "duration" delay:
using UnityEngine;
using System.Collections;
public class DestroyParticles : $$anonymous$$onoBehaviour
{
private void Start()
{
Destroy(gameObject, GetComponent<ParticleSystem>().duration);
}
}
The issue with using a time driven Coroutine or Destroy is time scale changes and pauses. If you turn on slow motion after the system starts, the particle system in will then end before it should. $$anonymous$$y answer below has the same issue using Destroy, which is fine if you do not have slow motion or do not care that the particle system will end during pause. If time scaling does matter in your project, an Update based solution will be better, such as the one from RkSandswept.
Also, using only 'duration' will not give time for the last emitted particles to burn out. See my solution below with 'StartLifetime' added to allow particles emitted at the end of the duration to linger on appropriately.
@$$anonymous$$evinCodes4Food Coroutines that use WaitForSeconds are affected by Time.timeScale; so is Invoke. Go ahead and try it out. The only one I'm not sure about is Destroy.
Answer by fireomega · Feb 22, 2012 at 08:23 PM
A simple Destroy code and then just add the time the particle lasts for. e.g. say the time it lasts for is 5 seconds than you do: Destroy(gameObject, 5);
If this answered your question please click on the tick
thanks fireomega, that was perfect for me as I'm still using u3.4. When my missile object (that has the particle system attached to it) gets a signal to explode, this is how I handle the smoke trail:
particleSystem.particleEmitter.emit=false;
particleSystem.transform.parent=null; // detach particle system
Destroy(particleSystem.gameObject, 3);
Destroy(gameObject);
Answer by RogueHydra · Mar 08, 2012 at 12:14 AM
I saw this and made a minor adjustment. It works for me in my situation but I'm fairly new to using Unity so I'm not sure how valid it will be for anyone else. This lets you put it on any particle system and it will kill it when it's done playing (no need to set the duration).
var psys = this.GetComponent(ParticleSystem);
Destroy(this.gameObject, psys.duration);
This is the simplest solution, without the need to attach scripts. I'd make one small change to the duration though to ensure no particles are cut off in their prime:
Object.Destroy(gameObject, psys.duration + psys.startLifetime);
This is even simpler. Only 1 line of code.
Destroy(gameObject, gameObject.particleSystem.duration);
The solution from $$anonymous$$GB and windterfresh works perfectly, and makes for a very simple and reliable auto destruct component that can be added to any particle system object.
Here is the complete script:
using UnityEngine;
using System.Collections;
public class ParticleSystemAutoDestroy : $$anonymous$$onoBehaviour {
// Use this for initialization
void Start () {
if(gameObject.particleSystem)
{
GameObject.Destroy(gameObject, gameObject.particleSystem.duration + gameObject.particleSystem.startLifetime);
}
}
}
Thanks $$anonymous$$evinCodes4Food! The solution you added above worked perfectly for what I needed! I am no longer getting dead particle systems hanging around wasting resources :]
Answer by Imi · Mar 07, 2012 at 11:46 PM
I recommend the following script, as it does not need to know how long the particle system will go (this can vary depending on the start lifetime and in worst case a lot of curves..)
function Update ()
{
if (particleSystem != null && particleSystem.particleCount == 0)
Destroy(gameObject);
}
I would recommend to use LateUpdate() ins$$anonymous$$d of Update(). Thanks for your code anyway. ;)
Answer by RogueHydra · Mar 08, 2012 at 12:14 AM
I modified it just a little so you can just attach this to any particle system and it'll kill it after the duration is up. I'm a not sure if this'll work for everyone but it works perfect for me and all my systems (haven't had any issues and haven't seen any bugs yet).
function Start () {
var psys = this.GetComponent(ParticleSystem);
Destroy(this.gameObject, psys.duration);
}
Follow this Question
Related Questions
How to pause emitter in new Particle System? 2 Answers
How do you change the colour of individual particles having assigned them a material? 1 Answer
particles dont have color 2 Answers
Particle System - Texture Sheet Animation, Flip U/V greyed out? 1 Answer
How to keep particles moving past an obstacle after they have collided with it? 3 Answers