- Home /
SOLVED
Particle system not destroying.
I got an problem with particle system. I'm instantiating one everytime ball hits an brick, and after it's done it should be removed automaticly, but these just won't get destroyed.
Script doesnt give out any errors or warnings, but particle system(clone)'s just won't get destroyed.
Here's the whole script:
using UnityEngine;
using System.Collections;
public class BrickScript : MonoBehaviour {
static int numBricks = 0;
public int pointValue = 1;
public int currentLvl = 0;
public int hitPoints = 1;
public int powerUpChance = 3;
public Transform particlesPrefab;
public GameObject[] powerUpPrefabs;
public AudioClip[] hitaudio;
// Use this for initialization
void Start () {
numBricks++;
}
// Update is called once per frame
void Update () {
if ( currentLvl == 4) {
Application.LoadLevel("GameOver");
}
}
void OnCollisionEnter ( Collision col ) {
hitPoints--;
if ( hitPoints <= 0 ) {
Die();
}
if (col.gameObject.tag == "Ball")
Debug.Log ("Particles!");
GameObject go = Instantiate(particlesPrefab, transform.position, Quaternion.identity) as GameObject;
Destroy (go, 2.5f);
}
void Die() {
Destroy ( gameObject );
BallScript ball1Script= GameObject.FindGameObjectWithTag ("Ball").GetComponent<BallScript>();
PaddleScript paddleScript= GameObject.Find ("Paddle").GetComponent<PaddleScript>();
paddleScript.AddPoint(pointValue * (int)ball1Script.curspeed);
numBricks--;
Debug.Log (numBricks);
if ( Random.Range(0, powerUpChance) == 0 ) {
Instantiate( powerUpPrefabs[ Random.Range(0, powerUpPrefabs.Length) ] , transform.position, Quaternion.identity );
}
if ( numBricks <= 0 ) {
//Load Next Level
Application.LoadLevel(currentLvl+1);
if(currentLvl == 1){
GJAPIHelper.Trophies.ShowTrophyUnlockNotification (4086);
}
if(currentLvl == 2){
GJAPIHelper.Trophies.ShowTrophyUnlockNotification (4087);
}
}
}
}
And here's just the part that SHOULD be removing that.
void OnCollisionEnter ( Collision col ) {
hitPoints--;
if ( hitPoints <= 0 ) {
Die();
}
if (col.gameObject.tag == "Ball")
Debug.Log ("Particles!");
GameObject go = Instantiate(particlesPrefab, transform.position, Quaternion.identity) as GameObject;
Destroy (go, 2.5f);
}
Why it isnt getting destroyed?
A simple way to get a particle system to self destroy is to attach a script component to the Particle System object and run this code
void Start() { Destroy(gameObject, GetComponent().duration); }
This sets an Auto Destroy on the Particle System Object based on its set duration
I'm a complete noob and this might be already clear to everyone, but I was running into this same problem and found a very simple solution for me. When I edit the particlesystem, in the inspector there is a setting that controls what happens when the particles have stopped. It's called "Stop Action". Mine was set to "None" and the particlesystem objects would persist. But when I changed that setting to "Destroy", they were removed from the Hierarchy.
Answer by Tomer-Barkan · Oct 12, 2013 at 06:43 AM
I have the following script attached to the particle system prefab, and it works fine:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class HitEmitterScript : MonoBehaviour {
private float timeLeft;
public void Awake() {
ParticleSystem system = GetComponent<ParticleSystem>();
timeLeft = system.startLifetime;
}
public void Update() {
timeLeft -= Time.deltaTime;
if (timeLeft <= 0) {
GameObject.Destroy(gameObject);
}
}
}
Note that the lifetime is set to be the particle's starting life, but you could make it a constant 2.5 seconds.
The more Unity way of doing that is changing the countdown (timeLeft) into a clock time when you should die.
Say the variable is renamed destroyTime. Set in start destroyTime=Time.time+2.5f;
. Then update checks if(Time.time>=destroyTime)
. No need for the decrement.
Answer by Doireth · Oct 11, 2013 at 08:47 PM
Particle systems don't self destroy. It's a problem that a lot of people have. A better option would be to not instantiate the particle system every time but rather instantiate it once at the start, move it to where it needs to be (such as a collision point) and use
[Particle System].Play()
This way it removes needless instantiation and the need for it to be destroyed as you'll be using it over and over. Better performance too.
Ok, but I'd still like to know why my code isnt deleting it?
When Unity changed from their legacy particle system to the current one (known as Shuriken) this problem has emerged quite a bit. $$anonymous$$any people have requested that particle systems self-destruct but it hasn't been implemented yet. I really don't know why it doesn't destroy when you destroy what it's attached to and it's something that has cause me grief before. You could try (when destroying the object) to destroy the particle component itself. For example.
Destroy(go.transform.GetComponent<ParticleSystem>());
This gives only an error:
"NullReferenceException: Object reference not set to an instance of an object"
Your code destroys the entire object. I was suggest destroying the particle system component itself.
Ok, try
ParticleSystem go = Instantiate(particlesPrefab, transform.position, Quaternion.identity) as ParticleSystem;
Destroy(go, 2.5f);
Answer by Owen-Reynolds · Oct 11, 2013 at 09:36 PM
The code (Instantiate then timed 2.5-sec Destroy) looks fine. I'm wondering if the bricks always have 1 hit point, so always die right away. I think the 2.5-sec Destroy is really a hidden coroutine attached to the brick. So a dead brick can't destroy the explosion.
Try giving the bricks 2-HP to test (should destroy the puff on first hit.) If that's the problem, maybe move the OnCollisionEnter into the ball script. Or just move the explosion spawn there.
---- answer #2 -----
From that last test (not printing the name after a spawn,) go
is clearly broken. You're getting a null reference for go
, which means the destroy command is destroying nothing. Specifically, Instantiate is spawning just fine. But the as GameObject
conversion doesn't work, so just gives you a null (just tried it.)
Fix#1: redeclare particlePrefab (up top) as a GameObject (it's a Transform now)
Alternate fix#2:
Leave particlePrefab as a Transform, but change spawn code to:
Transform go = Instantiate(...) as Transform;
Destroy(go.gameObject, 2.5f);
Either way, the GameObject's or Transforms all have to match.
Those have 1 hit point, 2 HP won't do a difference, just tested. It won't destroy that "Particle System(Clone)" objects it instantiates.
I still think the code is fine -- I've used that trick plenty -- and that something else is breaking the Destroy (the parens on the if are missing, but doubt that's the problem.)
Try it in Start (Instantiate, Destroy in 2.5.) To be sure, toss in a Debug.Log("spawned :"+go.name);
. Should see them get destroyed.
This is what happens on console / screen when I did it like this:
// Use this for initialization
void Start () {
numBricks++;
ParticleSystem go = Instantiate(particlesPrefab, transform.position, Quaternion.identity) as ParticleSystem;
Debug.Log ("spawned: "+go.name);
Destroy (go, 2.5f);
}
B/W Bricks are particles. And no, it doesnt print ever on console what it's spawning.