Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Destroy makes subsequent gameobjects box collider components faulty

Discussion in 'Scripting' started by Roryyyyyyyyyy, Sep 13, 2016.

  1. Roryyyyyyyyyy

    Roryyyyyyyyyy

    Joined:
    Jun 8, 2015
    Posts:
    22
    I have a script that manages the swapping of game objects depending on what upgrade tier it is on. I hold references to all the tier game objects in the script and have one reference of current gameobject. When I want to upgrade to the next tier I destroy the current GO reference then set it as the correct tier and instantiate it. The problem is that the box colliders do not work correctly. They are all shown as active in the editor and raycasts still detect it, just my player model doesn't stop when colliding with it. I have tried taking out the destroy current gameobject step and it solves the problem but then I am stuck with the previous tier still there.

    Here are the sections of code for the parts I described.

    Code (CSharp):
    1. public int id;
    2.     public int currentTier;
    3.     public GameObject currentGO;
    4.     public GameObject tierZero;
    5.     public GameObject tierOne;
    6.     public GameObject tierTwo;
    7.     public GameObject tierThree;

    The code below enables a preview of the first tier when placing. When placed it replaces that with a model of materials to show where the building will be built. This has no problems with collisions when placed.

    Code (CSharp):
    1. public void Placing()
    2.     {
    3.         sizeGuide.GetComponent<MeshRenderer>().enabled = true;
    4.         currentGO = (GameObject)Instantiate(tierOne);
    5.         currentGO.transform.SetParent(transform, true);
    6.         for(int i = 0; i < currentGO.transform.childCount; i++)
    7.         {
    8.             currentGO.transform.GetChild(i).GetComponent<BoxCollider>().enabled = false;
    9.         }
    10.     }
    11.  
    12.     public void Placed()
    13.     {
    14.         sizeGuide.GetComponent<MeshRenderer>().enabled = false;
    15.         Destroy(currentGO);
    16.         currentGO = (GameObject)Instantiate(tierZero);
    17.         currentGO.transform.SetParent(transform, false);
    18.         currentGO.GetComponent<BuildingScript>().id = id;
    19.         for (int i = 0; i < currentGO.transform.childCount; i++)
    20.         {
    21.             currentGO.transform.GetChild(i).GetComponent<BoxCollider>().enabled = true;
    22.         }
    23.     }
    This is the part that causes problems. The object instantiated in ChangeCurrentGO() is the one that has collision problems.

    Code (CSharp):
    1. public void CheckCurrentGO()
    2.     {
    3.         if (currentTier == 1 && currentGO != tierOne)
    4.         {
    5.             ChangeCurrentGO(tierOne);
    6.         }
    7.         else if(currentTier == 2 && currentGO != tierTwo)
    8.         {
    9.             ChangeCurrentGO(tierTwo);
    10.         }
    11.         else if(currentTier == 3 && currentGO != tierThree)
    12.         {
    13.             ChangeCurrentGO(tierThree);
    14.         }
    15.     }
    16.  
    17.     public void ChangeCurrentGO(GameObject changeTo)
    18.     {
    19.        
    20.         currentGO = (GameObject)Instantiate(changeTo);
    21.         currentGO.transform.SetParent(transform, false);
    22.         for (int i = 0; i < plotContents.Count; i++)
    23.         {
    24.             Debug.Log(currentGO.transform.GetChild(0).gameObject);
    25.             invManager.AddItem(currentGO.transform.GetChild(0).gameObject, plotContents[i], 1);
    26.             Destroy(plotContentsGO[i]);
    27.         }
    28.         plotContents.Clear();
    29.         plotContentsGO.Clear();
    30.         Destroy(transform.GetChild(1).gameObject);
    31.     }


    I'm unsure if this is a bug or I am missing something important. Any help would be greatly appreciated.
     
  2. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    Not quite sure what's wrong, but I'm noticing one thing. You're doing this:

    Code (csharp):
    1. if (currentTier == 1 && currentGO != tierOne)
    2. ...
    3. else if(currentTier == 2 && currentGO != tierTwo)
    4. ...
    5. else if(currentTier == 3 && currentGO != tierThree)
    6. ...
    But != and == for objects are reference equality (with a bit of null-magic in Unity). currentGO should never be the same object as tierOne, two or three, it should be a copy of that object. Unless I'm mistaken, this should print false:

    Code (csharp):
    1. public void ChangeCurrentGO(GameObject changeTo)
    2.     {
    3.        currentGO = (GameObject)Instantiate(changeTo);
    4.        Debug.Log(currentGO == changeTo);
    5.        ...
    In that case, assuming you're calling CheckCurrentGO very often (like every frame), you might be creating and destroying the created object very often.

    That's all that stands out to me as potentially wrong. Your ChangeCurrentGO code can't be undestood unless the reader knows exactly what the transform hierarchy of all involved objects are, though, so there might be other things. That's probably not a good idea, by the way, if you look at this piece of code in two weeks, you won't remember why this makes sense:

    Code (csharp):
    1. Destroy(transform.GetChild(1).gameObject);
    And you'll have to look at the prefab a bunch to get what's going on.
     
  3. Roryyyyyyyyyy

    Roryyyyyyyyyy

    Joined:
    Jun 8, 2015
    Posts:
    22
    Thanks for the reply. The function is only called when the player hits it with a hammer, had the problem of creating and destroying repeatedly a while back and made sure not to let that happen again! That's strange as that part seems to do the job correctly, I will probably try and rewrite it anyway just to avoid any possible future complications. I have managed to fix the problem as the base had a rigidbody encasing the building to deal with overlapping and getting rid of that fixed it. I did think that the getchild stuff would cause some problems. Will definitely look into that. Thank you for the feedback!