Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

[SOLVED] Particle Instance finished playing so can I destroy it?

Discussion in 'Scripting' started by castingflame, Jun 20, 2016.

  1. castingflame

    castingflame

    Joined:
    Jan 29, 2016
    Posts:
    35
    Hello everyone.

    I am a beginner to all this so please treat me with kid gloves.

    I am following an online course and have come to the end of a section where my small breakout game is about done. One of the last things we did was to create a new prefab for a small smoke explosion using the particle system component. It all works okay but there is something that is troubling me when I am watching the game auto-play.

    When a brick is destroyed a particle effect is played at the same location called Smoke. When I watch the Hierarchy it comes up as Smoke(clone). So far so good. What is surprising to me is that in our code we have created an instance of our prefab using the following ..

    Code (CSharp):
    1. ...
    2. public GameObject smoke;       //this smoke object gets dropped on this in the inspector
    3. ...
    4.  
    5.  
    6. GameObject smokePuff = Instantiate(smoke, transform.position, transform.rotation) as GameObject;
    7.  
    8.  
    9.  

    but after the 'smoke has cleared' so to speak the instance is still loaded in the Hierarchy and I would imagine game memory. Each time a brick is destroyed and a new instance is created the list of Smoke(clone) gets longer.

    How could I ;

    1. Look at the particle system instance, i.e. the smoke, and see if it has finished playing.
    2. When I know the smoke has cleared, destroy that particular (no pun intended) smoke instance so I do not get a list of idle object sitting in memory.


    Obviously this isn't an issue for this little game but it is a big issue going forward knowing how to deal with such situations.

    Thank you for any help you can give.
     
  2. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,194
    If your particle system doesn't loop, you could set it to destroy after it's done. That's pretty easy:

    First, get the ParticleSystem component:

    Code (csharp):
    1. ParticleSystem parts = smokePuff.GetComponent<ParticleSystem>();
    Find the total duration of the particle system. The particle system emits particles for it's duration, and each particle has a lifetime of startLifetime seconds. These are named the same in the inspector and the scripts. So:

    Code (csharp):
    1. float totalDuration = parts.duration + parts.startLifetime;
    Then you simply destroy the object when that's done. The second argument to Destroy is a delay before the destruction happens:

    Code (csharp):
    1. Destroy(smokePuff, totalDuration);
    So the total code is.

    Code (csharp):
    1. GameObject smokePuff = Instantiate(smoke, transform.position, transform.rotation) as GameObject;
    2. ParticleSystem parts = smokePuff.GetComponent<ParticleSystem>();
    3. float totalDuration = parts.duration + parts.startLifetime;
    4. Destroy(smokePuff, totalDuration);
     
  3. castingflame

    castingflame

    Joined:
    Jan 29, 2016
    Posts:
    35


    I am , as we say in my neck of the woods, 'Gob Smacked'!

    A massive thank you Baste. You answered so quickly, explained things in bite size chunks and gave me code that just pasted in and worked. I will take a break and then come back and make sure I get it 100%

    ... and I was scared about posting in the unity forum ;)
     
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,194
    We're pretty nice. If you get an answer fast is completely random - depends on if someone who's a regular is on their lunch break before it's pushed to page 2 :p
     
    castingflame likes this.
  5. axeldaguerre

    axeldaguerre

    Joined:
    Mar 1, 2020
    Posts:
    3
    Hi i am a beginner either but i can give an update of this issue for someone who will come here to find answer. I am using Unity 2019.3.3F1 right now and you don't need to do what Baste is saying here.
    On the" particle effect editor" you have an option in the main section of the particle effect editor, it is name "Stop Action" and you can choice what to do after the particle system is done (when not looping). Select "Destroy" and it will destroy the particle system nicely without all this code, not really neede dmost of the time.
     
  6. wrashidd

    wrashidd

    Joined:
    Sep 19, 2019
    Posts:
    1
     
  7. Valhalaru

    Valhalaru

    Joined:
    Feb 3, 2016
    Posts:
    9
    You are the man for finding this option! Works like a charm. Thank you.
     
  8. ziadata

    ziadata

    Joined:
    Nov 10, 2017
    Posts:
    2
    Thanks so much you saved me tons of time :)
     
  9. hotlabs

    hotlabs

    Joined:
    Apr 11, 2021
    Posts:
    10
    Best Solution!
     
  10. shinichikudo997

    shinichikudo997

    Joined:
    Jul 1, 2018
    Posts:
    32
    Thank you for this
     
  11. Nimeode

    Nimeode

    Joined:
    May 21, 2018
    Posts:
    10
    A different solution that I came up with (and a way that you can re-use it on any particle effects) is create a script that will destroy the effect based on a time frame. I did this by

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class DestroyParticleEffect : MonoBehaviour
    6. {
    7.     public float lifeTime;
    8.  
    9.     public void Start()
    10.     {
    11.         Invoke("DestroyEffect", lifeTime);
    12.     }
    13.     void DestroyEffect()
    14.     {
    15.         Destroy(gameObject);
    16.     }
    17. }
    18.  
    You would just then attach this to any object that needs to be destroyed after x timeframe.
     
  12. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,194
    This thread is very old! I can't remember if it wasn't around when I wrote my reply 6 years ago, or if I just didn't know then, but these days you can just set the "end action" on the ParticleSystem to Destroy, and be done with it.