- Home /
Destroy(gameObject) not working
I have two scripts that randomly spawn models in an area and then respawn ones the overlap. I can't find any errors in the code, but when Destroy(gameObject); is called in the second script, it seems to do nothing. Here is the base spawning script:
using UnityEngine;
using System.Collections;
public class CreateBuildings : MonoBehaviour {
public GameObject ThreeSBWR;
public GameObject ThreeSB;
public GameObject TwoSBWR;
public GameObject TwoSB;
public GameObject OneSBWR;
public GameObject OneSB;
public int ThreeSBTS;
public int TwoSBTS;
public int OneSBTS;
Quaternion SpawnRotation;
void Start ()
{
int a;
int b;
int c;
a = ThreeSBTS;
while (a > 0)
{
Vector3 SpawnLocation;
SpawnLocation = new Vector3(Random.Range(-90, 90), 2.5f, Random.Range(-90, 90));
while (SpawnLocation.x < 15 && SpawnLocation.x > -15 && SpawnLocation.z < 15 && SpawnLocation.z > -15)
{
SpawnLocation = new Vector3(Random.Range(-90, 90), 2.5f, Random.Range(-90, 90));
}
SpawnRotation.eulerAngles = new Vector3(0, Random.Range(0, 360), 0);
float rand;
rand = Random.Range(0, 1);
if (rand >= 0.5f)
{
Instantiate(ThreeSB, SpawnLocation, SpawnRotation);
}
else
{
Instantiate(ThreeSBWR, SpawnLocation, SpawnRotation);
}
a -= 1;
}
b = TwoSBTS;
while (b > 0)
{
Vector3 SpawnLocation;
SpawnLocation = new Vector3(Random.Range(-90, 90), 2.5f, Random.Range(-90, 90));
while (SpawnLocation.x < 15 && SpawnLocation.x > -15 && SpawnLocation.z < 15 && SpawnLocation.z > -15)
{
SpawnLocation = new Vector3(Random.Range(-90, 90), 2.5f, Random.Range(-90, 90));
}
SpawnRotation.eulerAngles = new Vector3(0, Random.Range(0, 360), 0);
float rand;
rand = Random.Range(0, 1);
if (rand >= 0.5f)
{
Instantiate(TwoSB, SpawnLocation, SpawnRotation);
}
else
{
Instantiate(TwoSBWR, SpawnLocation, SpawnRotation);
}
b -= 1;
}
c = OneSBTS;
while (c > 0)
{
Vector3 SpawnLocation;
SpawnLocation = new Vector3(Random.Range(-90, 90), 2.5f, Random.Range(-90, 90));
while (SpawnLocation.x < 15 && SpawnLocation.x > -15 && SpawnLocation.z < 15 && SpawnLocation.z > -15)
{
SpawnLocation = new Vector3(Random.Range(-90, 90), 2.5f, Random.Range(-90, 90));
}
SpawnRotation.eulerAngles = new Vector3(0, Random.Range(0, 360), 0);
float rand;
rand = Random.Range(0, 1);
if (rand >= 0.5f)
{
Instantiate(OneSB, SpawnLocation, SpawnRotation);
}
else
{
Instantiate(OneSBWR, SpawnLocation, SpawnRotation);
}
c -= 1;
}
}
public void Spawn(GameObject ToSpawn)
{
print("Call Successfull");
Vector3 SpawnLocation;
SpawnLocation = new Vector3(Random.Range(-90, 90), 2.5f, Random.Range(-90, 90));
while (SpawnLocation.x < 15 && SpawnLocation.x > -15 && SpawnLocation.z < 15 && SpawnLocation.z > -15)
{
SpawnLocation = new Vector3(Random.Range(-90, 90), 2.5f, Random.Range(-90, 90));
}
Quaternion SpawnRot;
SpawnRot = new Quaternion(0, 0, 0, 0);
SpawnRot.eulerAngles = new Vector3(0, Random.Range(0, 360), 0);
Instantiate(ToSpawn, SpawnLocation, SpawnRot);
print("(Call) Spawn Complete");
}
}
Here is the script that checks for overlaps:
using UnityEngine;
using System.Collections;
public class CollisionCheck : MonoBehaviour {
void OnTriggerEnter(Collider col)
{
if (col.gameObject.name != "Player" && col.gameObject.name != "Ground" && col.gameObject.name != "Bullet(Clone)")
{
GameObject.Find("GameController").GetComponent<CreateBuildings>().Spawn(gameObject);
print("Called");
Destroy(gameObject);
}
}
void OnTriggerStay(Collider col)
{
if (col.gameObject.name != "Player" && col.gameObject.name != "Ground" && col.gameObject.name != "Bullet(Clone)")
{
GameObject.Find("GameController").GetComponent<CreateBuildings>().Spawn(gameObject);
print("Called");
Destroy(gameObject);
}
}
}
Here is a video showing what happens with different values for ThreeSBTS, TwoSBTS, and OneSBTS:
https://drive.google.com/open?id=0B_HzgsC9lP3nRURlaDUxQlJIOEk
As you can see in the video, the Destroy(gameObject); seems to do nothing, and the more buildings there are to spawn, the more likely that this causes problems. I would like to have 2, 4, and 6 as the values, but it rarely spawns correctly. Does anyone know how to fix this?
Answer by LucianoMacaDonati · Oct 26, 2016 at 10:30 PM
Hello @matthrewp,
You're calling Instantiate on an object marked for Destroy. I would make a function to Move the colliding building instead of re-spawning it.
My solution (keeping your original approach) would be as follows:
Create a function to only move the buildings to a new random location. On collision enter, call this function. Just in case, I would add a maximum amount of times you can call this and check for it every call before ultimately destroying the conflicting gameObject (to avoid callstack overflows).
Some other general tips for you:
I would start by removing the OnTriggerStay function so that it doesn't interfere with your debugging. Having two Debug.Log's that print "Called" makes it harder to know which function was called (and we only need to destroy once: when the overlap begins).
Second, I see you want to re-spawn the buildings that overlap others but you're actually calling Destroy on both buildings (both buildings collide with each other).
And lastly, the video shows only the first frame since you pause it and then press play. Wouldn't you want to see what happens the next frame? (Destroy waits until the end of the current loop to safely destroy the gameobject, more info here).
Thanks, I hadn't thought of moving the model ins$$anonymous$$d of destroying it!
The garbage collector will thank you for that :)
Answer by nathanthesnooper · Oct 26, 2016 at 09:58 PM
I have had a similar problem as well.
Some solutions I thought of: Destroy(this) instead of Destroy(gameObject)
The only solution that always worked for me was having a separate script delete things. Camera.main.gameObject.GetComponent<CustDelete>().Destroy(this);
CustDelete.cs:
using UnityEngine; using System.Collections public class CustDelete : MonoBehaviour { public void Destroy(GameObject des) { Destroy(des); } }
It is a Unity Bug I believe because it deletes the object before the script knows it ended (idk what actually happens)
I'm afraid trying this produced no result. Thanks for trying!
Sorry :(, Hopefully you can find out... you know you shouldn't use the cube... it is collisions for your buildings and people might be able to see it for a split second.
That actually makes no sense. Destroy is a static method so it doesn't matter in which scope you call it.
Also passing "this" to Destroy will only destroy the script instance but not the GameObject that containst the script.
Your answer
Follow this Question
Related Questions
Destroy function not documented? 2 Answers
Destroy On Contact 1 Answer
unet 5.2 client authority destroy 1 Answer
How to detect a single collision when 2 identical gameobjects collide. 1 Answer
My ship destroyed when i press fire 1 Answer