- Home /
chain of explosions - Destroying gameObjects in range
Hi there, I am having a little trouble with my code, I think its just due to the way I implemented my bomb system but when I try to create a chain of explosions.
The way I implemented it originally, was to get the destroyObjects method to call itself so that it would set of a chain reaction, I know know that this is definitely not a good way as unity just crashes out. I am guessing its causing an infinite loop or just feed-backing.
I deduced that if I am able to have "live" list management so that the list is populated and de-populated as objects go in and out of the range then I could use that but personally i am a little lost as how i would do that. Any and all suggestions are welcome.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//---------------------------------------------------------------------------------------
// NOTES & TO-DOs
//---------------------------------------------------------------------------------------
//
// Bombs do explode other bombs but currently only in the scope of the origional bomb
// i need to feed the bomb scope method to the currently exploding one so it searches for
// all of the bombs is scope
//---------------------------------------------------------------------------------------
public class Bomb : GameItem
{
//static protected int bombBag = 100;
// Bomblists ~ Stores all the Bombs
public static List<GameObject> bombList = new List<GameObject>();
// Movement & Force Vars
const int noForce = 0;
public int maxForce = 100;
private int throwForce = 15;
// Timer Vars
private float bornTime;
private int bombTime = 5;
//-------------------------------------------------------------------------------------------------------------------------
// Blast Radius and Collider Methods
//-------------------------------------------------------------------------------------------------------------------------
protected Collider [] radiusCollider;
public static float radius = 3.0f;
private SphereCollider radiusPreview;
// Initialises the Radius Collider and links the collider to the
void INITRadius () {
radiusCollider = Physics.OverlapSphere(transform.position, radius);
radiusPreview = GetComponent("SphereCollider") as SphereCollider;
radiusPreview.radius = radius;
}
public List<GameObject> inRadius () {
List<GameObject> inRadiusList = new List<GameObject>();
foreach (var collider in radiusCollider) {
inRadiusList.Add((GameObject)collider.gameObject);
}
return inRadiusList;
}
//-------------------------------------------------------------------------------------------------------------------------
// Bomb Detonation and Destruction Methods
//-------------------------------------------------------------------------------------------------------------------------
void bombTimer(){
if((Time.time - bornTime) >= bombTime){
INITRadius();
DestroyObjects();
}
}
void DestroyObjects () {
foreach (var listItem in inRadius()) {
if (listItem.tag != "NonDestructable" && listItem.tag != "Bomb") {
Cube.destroyBlockWChk(listItem);
Destroy(this.gameObject);
}
else if (listItem.tag != "NonDestructable" && listItem.tag == "Bomb"){
expolde(listItem);
Destroy(this.gameObject);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// PUT EXPLODE OTHER BOMB METHOD HERE!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
}
}
void expolde(GameObject target){
Destroy(target.gameObject);
}
void detonateOtherExplosives(){
GameObject[] Bombs = GameObject.FindGameObjectsWithTag("Bomb");
if(this.transform.position == Bombs[1].transform.position){
Debug.Log("Booom!");
}
}
//-------------------------------------------------------------------------------------------------------------------------
// INIT
//-------------------------------------------------------------------------------------------------------------------------
void Start ()
{
// Iniialises the basclass GameItem() ****************************** <- [ IMPORTANT FOR ALL CHILDREN OF GameItem ]
base.INIT();
//Add Bomb to the bombsArray
bombList.Add(this.gameObject);
// Grabs the time at instantiation of bombs
bornTime = Time.time;
//---------------------------------------------------------------------------------------
// Controls Force [ ADD THIS TO ITS OWN METHOD WITH PARAMETERS ] ***********************
//---------------------------------------------------------------------------------------
// Adds an impulse on the first frame of creation which throws it in the direction of the Players aiming ray
this.rigidbody.AddForce(GameObject.FindGameObjectWithTag("AimDirection").transform.forward * throwForce, ForceMode.Impulse);
// This was the old aiming system using [ up / down / left / right ]
//this.rigidbody.AddForce(PlayerInteraction.rayDirection * throwForce, ForceMode.Impulse);
// Puts new Bombs into the InstanceBin
transform.transform.parent = GameObject.FindGameObjectWithTag("InstanceBin").transform;
}
//-------------------------------------------------------------------------------------------------------------------------
// UPDATE
//-------------------------------------------------------------------------------------------------------------------------
void Update ()
{
bombTimer();
}
//-------------------------------------------------------------------------------------------------------------------------
}
Answer by SilverTabby · Aug 28, 2011 at 08:30 PM
This seems too complex for what you are trying to do. You are trying to do everything in one script that controls everything. This creates an overly complex, bloated script that is too easy to make a mistake and have it run on each object.
I would:
DO NOT try to get into data structures if you don't need to. It's too complex to deal with dynamic allocation for something like this.
DO NOT use GameObject.Destroy() on any object except this.gameObject, and only do that at the END of your explode function
When exploding, do the OverlapSphere like you already have, but instead of destroying each GameObject, use SendMessage to call a function on that object that causes it's explosion. This is the safest, most versatile way to do this. It is easier to add onto a SendMessage setup that it is to add onto a Destroy setup. (make sure to use SendMessageOptions.DontRequireReciever)
Make sure that function returns without doing anything if it has already been called (prevents recursive loop)
I would personally wait a few frames during the explode function - this gives the engine a chance to actually handle the Destroy calls (they do not resolve until after the update cycle) and so that the player can get a bit of feedback on what is about to happen. It should also increase frame rate because you aren't trying to do too many things in one frame and also the Destroy calls will make it so that there are fewer collides in the next frame, decreasing the overhead of the next OverlapSphere.
That really makes a lot of sense, why do you think this is too complicated though, this is a relatively simple script compared to a lot of my others the reason i have a lot in here is because its going to be inherited from and all of the children need these same behaviours.
Thank you for the solution though I will implement that right now, I cant believe how simple that is and how i couldn't think about it in that way. $$anonymous$$uch to learn indeed.:)
"Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction. "
-Albert Einstein
Remember: less is more.
Answer by Arshia001 · Aug 28, 2011 at 04:12 PM
Well, I DID type two full paragraphs on how to do it, but by some miracle the text never made it! Believe me, this is NOT my idea of a joke! In a nutshell, you should mark the objects for destruction rather than actually destroy them, and only attempt to find the neighbouring $$anonymous$$es IF this one is not marked for destruction. Look at this link, it'll give you a better idea on how to do this:
Your answer
Follow this Question
Related Questions
How to Chain of Explosion? 1 Answer
blow up bomb when it collides with fire 1 Answer
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers