Shuriken: Stopping Emission but NOT destroying existing particles

Hey guys,

The title says it all. I want a particle system to stop emitting particles, but to leave the ones that had been already emitted intact. I already tried particlesystem.enableEmission = false AND particlesystem.Stop(), but they both are yielding the same results…

What is strange is that I remember that using exactly this code used to work before and particles remained… is there something that changes this behavior, making them all disappear immediately?

Thanks!

You need to attach a destroy script to the emmiter to be sure.

var destroyTime : float;

function Start()
{
    Destroy(this.gameObject, destroyTime)
}

Set emissionRate to zero?

Stop() should leave the particles for the remainder of their lifetime. Clear() will remove existing particles immediately. Are you sure your code is correct? If so, it could be a bug.

If you’ve tried .enableEmission and it didn’t work, I’d suspect there’s something wrong with your code or with the way the object is configured. Are you getting any errors in the console?

Yes, im pretty sure… it is as follows:

void Awake()
{
     system = GetComponent<ParticleSystem>();
     systems = GetComponentsInChildren<ParticleSystem>();
}

void WhenIWantToStop()
{
     for (byte i = 0; i < systems.Length; i++)
     {
          systems[i].enableEmission = false;
     }
}

void WhenIWantToStop2()
{
     system.Stop(true);
}

This is kind of pseudo code, but is exactly what happens in my class… I tried both forms, and the script is always attached to the parent Particle System… in this case to be honest it is only 1 particle system, and as I said, it really used to work, both ways… but this time, it is just hiding everything, I dont know why =/

@Fluzing : What you are suggesting is the inverse of what I want. I want that the existing particles remain existing for their lifetime values, and not to instantly disappear when I stop the emitter. My class is actually responsible for enabling and disabling the game object for performance purposes, but I checked and it is working correctly as well, it is not disabling the game object at the wrong time and is not what is causing the problem.

@hpjohn : Reason I dont want to do that is that if Im not mistaken, emissionRate only refers to the Emission/Time and Emission/Distance, but not the burst emissions. Also, I would have to save the number, so I can set it back up when I want to use that system again… and I want to use this class for the whole project, all kinds of particles, which is what I have been doing to be honest.

Something unexpected is happening now… I play the scene, have the particle system going, then through the inspector I disable the emitter component of shuriken. For exactly 7 frames (going through step by step) the particle system is still visible, and I can see it stopped emitting, while the remaining particles are still alive and behaving normally, but on the 8th frame, all particles abruptly disappear. THEN, the mysterious bit is that if I click on another window (for example on the browser, or Monodevelop… take the focus out of unity) when I click on unity again… the particles that were gone, appear again… but only for one frame… Idk but this is beginning to smell like a bug to me…

No errors in the console. Even if I manually disable the Emission component of shuriken by hand, through the inspector, the problem happens… also, I’ve been using this code for a long time and this is the first time its happening…

Ok I think I found out what is causing the problem, BUT it still seems like a bug to me… I was turning everything out and on one thing at a time… and the PARENT of the particle systems (and parent of the code I posted above) had the following coroutine:

    protected virtual IEnumerator UpdateProjectile()
    {
        while (myGameObject.activeInHierarchy)
        {
            myTransform.rotation = casterHealthHandler.transform.rotation;
            yield return null;
        }
    }

For some reason, updating the rotation of the parent transform… is making the particles completely disappear… lol -.-. And the worst is, even though this coroutine was active, the rotation was NOT changing, both objects were not rotating… (not myTransform and casterHealthHandler.transform…)

Anyway… I will probably reparent the script to casterHealthHandler.transform and then unparent it later on… but this is VERY strange… and yes, THIS is what was causing the problem… if anyone cares to explain why, I would love to know…

Anyway, thanks for the suggestions everyone!

Probably just an edge case they didn’t account for. Should the particles of an inactive/non-emitting system simulating in local space continue to update with respect to the parent object’s transform? The answer probably shouldn’t be “no and we’re also going to disrespect particle lifetime and turn them all off anyway”.

Thing is… its in World space… reparenting and then rotating did work though…

world space particle systems shouldn’t be affected by transformations to their parent objects.

Yeah I know… only the emitter shape which is what I was looking for… thats why its strange…

I know what you’re trying to accomplish. I had the same thing going on. Just check the box Color over Lifetime. Then go and edit the color. At the end of the color line, add a marker, and set the Alpha value to 0. This will make it fade out. I made my script so the particles fade out, then when they’re done emitting and fading, delete the obsolete particle system. I hope that helped :slight_smile:

I had a similar problem to the one described here, but there was no modification to the parent transform. My problem is pretty simple:

  1. Turn on emission
    1.5 Wait, say, 2 seconds to get a good number of particles
  2. Turn off emission
  3. Wait about 4 seconds
  4. All particles disappear at once, early.

If you turn emission back on within 4 seconds, the particles will go away after their normal lifetime

As far as I can tell, this is a bug. My workaround was to put code in my Update routine which toggled emission on for 0.1 seconds if it hadn’t been turned on recently. My code is here:

        //if we have a smoke keepalive
        if (SmokeKeepaliveEverySec > 0.0f)
        {
            //...and the smoke is off
            if (!_is_smoke_on)
            {
                //and we're overdue for a keepalive...
                if (Time.fixedTime > _dt_next_keepalive)
                {
                    float sec_next_keepalive = SmokeKeepaliveEverySec;
                    //then we need to do a keepalive...
                    //if we're currently emitting...
                    if (smokeParticleSystem.enableEmission)
                    {
                        //then turn off emission (remember, we wouldn't be here if smoke were supposed to be on)
                        smokeParticleSystem.enableEmission = false;
                    //otherwise, if we are not currently emitting
                    } else
                    {
                        //set the smoke color to the keepalive color (which is transparent)
                        smokeParticleSystem.startColor = _keepaliveColor;
                        //turn on emission
                        smokeParticleSystem.enableEmission = true;
                        //make a note to turn it off in 0.1 seconds.
                        sec_next_keepalive = 0.1f;
                    }
                    //set our dt_next_keepalive to now plus our keepalive time
                    //make a note to process the keepalive in sec_next_keepalive
                    _dt_next_keepalive = Time.fixedTime + sec_next_keepalive;
                    Debug.Log("Smoke keepalive processed.  smoke on: " + smokeParticleSystem.enableEmission + ", next keepalive in: " + sec_next_keepalive);
                }
            }
        }

Hope this helps anyone else who has had this kind of issue.

Shaun

might want to check the date on things before posting. this is a 7 year old post

1 Like

Just a heads up (as I was googling results and this old post came up)

I was using

public void StopEmiting()
{
ps.Stop( true, ParticleSystemStopBehavior.StopEmitting );
ParticleSystem.EmissionModule em = ps.emission;
em.rateOverTime = 0;
em.enabled = false;
}

but the 2nd time I call the function nothing happens, i.e. they didnt stop emitting

The Solution was in the particle system
change the StopAction from None → Destroy