What is wrong with my Destroy BoxCollider and Rigidbody code?

I have a script that builds a Skyscraper from multiple meshes. The player can essentially bite off a number of the lower floors from the ground up the building. After which I’d like the rest of the building to collapse down onto itself in stages (like a controlled demolition).

The initial build and bite work fine. But I’m having trouble managing the BoxCollision and Rigidbody components when I try to destroy floors again.

I would expect the BoxCollider assigned to the variable Col to be destroyed after first calling the Kill() function. Yet is isn’t until I call the function again. I’m confused as to how that comes to be.

Secondly, when I call the Kill() function a second time I get an error saying I can’t add a Rigidbody component because the game object already has one. But this also confuses me as the second time Kill() is called the bool Collapsing should be true and so the Rigidbody should be destroyed?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BuildingObject : MonoBehaviour
{
    public GameObject topSection;
    public GameObject midSection;
    public GameObject container;
    public int floors;
    public int floorWidth;

    List<GameObject> sections;
    private int surviveSections;
    private GameObject section;

    private BoxCollider col;
    private bool collapsing = false;

    private void Start()
    {
        Build(floors);
    }

    private void Update()
    {

        if (Input.GetKeyDown(KeyCode.D))
        {
            Kill(2.76f);
        }

        if (Input.GetKeyDown(KeyCode.N))
        {
            print("Col? "+col);
        }

    }


    private void Build(int levels)
    {
        sections = new List<GameObject>();

        for (int i = 0; i < levels; i++)
        {
            if (i < levels - 1)
            {
                section = (GameObject)Instantiate(midSection);
            }
            else
            {
                section = (GameObject)Instantiate(topSection);
            }

            section.transform.parent = container.transform;
            section.transform.localPosition = new Vector3(0f, transform.position.y + (i * 2f), 0f);
            section.name = ("Section" + 1 * i);
            sections.Add(section);

        }

        if (!collapsing)
        {
            col = gameObject.AddComponent<BoxCollider>();
            gameObject.GetComponent<BoxCollider>().size = new Vector3(floorWidth, 2 * levels, floorWidth);
            gameObject.GetComponent<BoxCollider>().center = new Vector3(0f, floors, 0f);
        }

    }


    public void Kill(float KillHeight)
    {
        if (col != null)
        {
            //Destroy(gameObject.GetComponent<BoxCollider>());
            //Destroy(col);
            Destroy(GetComponent<BoxCollider>());
            print("Col was not null!");
        }

        if (collapsing)
        {
            Destroy(container.GetComponent<BoxCollider>());
            Destroy(container.GetComponent<Rigidbody>());
        }

        //Count how many floors are above attack, destroy pieces lower than attack height
        foreach (GameObject sec in sections)
        {
            if (sec.transform.position.y > Mathf.RoundToInt(KillHeight))
            {
                surviveSections++;
            }

            Destroy(sec, 0f);
        }

        container.transform.localPosition = new Vector3(0f, (floors - surviveSections) * 2, 0f);
        container.layer = LayerMask.NameToLayer("Destroyed");

        Build(surviveSections);

        //Add some physics stuff for the container object
        container.AddComponent<BoxCollider>();
        container.GetComponent<BoxCollider>().size = new Vector3(floorWidth, 2 * surviveSections, floorWidth);
        container.GetComponent<BoxCollider>().center = new Vector3(0f, 2 * transform.localPosition.y + (surviveSections), 0f);
        container.AddComponent<Rigidbody>();
        container.GetComponent<Rigidbody>().mass = 10 * surviveSections;

        if (!collapsing)
        {
            collapsing = true;
            //StartCoroutine(Collapse());
        }



    }


}

Check out the documentation for Destroy: Unity - Scripting API: Object.Destroy

Of note:

In other words, the components won’t be destroyed until the end of the current frame. Try delaying creation of the new components until the next frame.

1 Like

Wow. Ok, yeah that’s a clanger of a puzzle piece. Thanks for the quick response!

hmmm its weird, im still having problems in some customer proyect where i need to remove some collider, or disable or what ever, but its doesn’t seems to do it and , its should do on code I set it but I can still see the box collider there attached and my player its colliding with the object that should be disappeared … but I’m try to destroy the root of the obj too coz its has to be destroy the root later , I cant understand why is not removing the collider I’m really frustrated at this point.

My bad guys…
nice i fixed all the boxes problem after destroy them now they become walkable… it was due some of the boxes, most of them , add a box collider duplicated :S so i remove those and it worked now after add some other code but i think the problem was duplicated box colliders on the prefabs…