The question is answered, right answer was accepted. problem was fixed.
Rocket explosion goes off 'randomly' and not when i want to.
So i have made a rocket with an explosion particle attached to it. When i shoot the rocket and hits a collider, the meshrenderer is being turned off and the explosion particle is played.
When i shoot ONE rocket(when only one is in the scene), it works perfectly. However when i shoot multiple rocket in a short time, the explosions don't happen when i want to. and sometimes the explosion goes off when the rocket is mid-air and didn't hit anything.
I'm not very good in coding since i'm focussing more on art, but i think this has to do with using private vars or something(not sure)?
If anyone could help me out, that'll be great. The script that is attached to my rocket is down below.
var time : float;
var mesh : MeshRenderer;
function Start (){
gameObject.Find("SmokeTrail").GetComponent(ParticleSystem).enableEmission = true;
}
function OnCollisionEnter(theCollision : Collision){
Destroy(gameObject,time);
mesh.enabled = false;
Emit = true;
gameObject.Find("SmokeTrail").GetComponent(ParticleSystem).enableEmission = false;
gameObject.Find("Explosion").GetComponent(ParticleSystem).Play();
Destroy(gameObject,time);
}
Answer by Fredex8 · Apr 07, 2016 at 01:47 PM
Firstly it's a really bad idea to be using gameObject.Find
within OnCollisionEnter. The one you are using on Start is far from ideal but the time it takes to find objects would be enough to delay the particle effects visibly on collision when you have multiple rockets on screen. No guarantee with this that they will actually find the explosion object on themselves and not on another rocket instead.
Also not clear why you have Destroy(gameObject,time);
in there twice. Seems like that is either going to be redundant or potentially call a null reference when the second destroy cannot find the item since it has already been destroyed (if it wasn't destroying itself it would anyway). If you want the rocket to destroy whatever it hit use Destroy(theCollision.gameObject)
. I also cannot see where you have actually set the value of time. If unset it will be 0 by default and therefore be destroying things instantly.
There are a few other ways to do this. First is for each rocket item to have SmokeTrail and Explosion on them as a particle system and assigned to variables in the inspector so you don't need to mess around with Find or GetComponent and can just enable/disable them directly. Or they could be child objects within the rocket prefab which would work much the same. That would work fine for the SmokeTrail.
For the explosion however I would probably look at instantiating a prefab with the explosion particle system on it at the point the rocket collided. Use Destroy(explosionInstance, 1);
(or however long the particle animation is) to destroy the instantiated explosion on a timer or a script on the explosion prefab to do it. After instantiating the explosion destroy the rocket itself instantly rather than turning off the renderer and smoke trail.
EDIT:
//Assign particles in the inspector instead of with Find
//In the particle editor set them to Play on Awake
//Child object of rocket with the trail particles on
var rocketTrail : GameObject;
//Not a child object but a prefab from your scene
var explosion : GameObject;
function OnCollisionEnter(theCollision : Collision){
//Spawn explosion
var explosionInstance : GameObject = Instantiate(explosion, transform.position, transform.rotation);
Destroy(explosionInstance, 2f);
//Destroy rocket
Destroy(gameObject);
}
My JS is a bit rusty so you may need to check that but this should remove the need to use Find which is slowing things down for you. Remove the explosion from the rocket itself and just have it assigned as a prefab from your project. The reference to rocketTrail above isn't doing anything currently but you may want it to stop emitting particles if the rocket has a limited range and is going to run out of fuel or something. Either way avoid using Find at all costs and assign things in the inspector where you can.
thanks for the reply!
i have no idea why i have Destroy(gameobject,time); twice in this.
The rocket itself is ofcourse a prefab and in the inspector i set the tim to 2 secs. The rocket prefab also has got children yes and those are the smoketrail and explosion particles.
So if I get this right, you're telling me to let the rocket be destroyed on impact. And to spawn in the explosion on the rocket's location when it impacts?
Any idea how I can make the Explosion spawn and be destroyed within the this script with Destroy(explosionInstance);?
Provided destroying the rocket is the last line of code after everything you want to rocket to do on collision: spawn the explosion, apply damage or force to enemies, destroy objects etc then yes it is better than turning off the renderer on it.
I added some code to the answer above which should work for you.
I fixed it by adding a collider to the explosion particle. And I made it so that it explodes when it comes in contact with another collider.
it's a newbie mistake i made, by trying to merge multiple scripts with eachother. $$anonymous$$y script got kind of messed up by doing that. It's fixed now.
thanks for replying to my question atleast!!