How to destroy Terrain-Tree-Collider?

Hey guys!

I am using a chop-wood-from-terrain-trees-script. All working fine but there is on thing i dont get. After a tree is destroyed, the collider still exist (invisible). Any ideas? :frowning:

public class TreesManager : MonoBehaviour
{
    public int TreeHP = 200;
    public int DropNum = 10;
    public float DropArea = 3;
    public Terrain terrain;
    public float BlastArea = 0.5f;
    public GameObject WoodDrop;
    public float ResetTime = 600;

    private List<int> RemovedIndexList = new List<int>();
    private SceneManager sceneManage;
    private List<Logger> Loggers = new List<Logger>();
    private TreeInstance[] treesBackup;
    private int ChopIndex;
    private bool hited = false;
    private float timeTemp;


    void Start()
    {
        sceneManage = (SceneManager)GameObject.FindObjectOfType(typeof(SceneManager));
        if (sceneManage)
        {
            if (Network.isClient)
            {
                sceneManage.GetInitializeeScene();
            }
        }

        if (terrain == null)
            terrain = this.GetComponent<Terrain>();

        timeTemp = Time.time;
        BackupTree();
    }

    void Update()
    {
        hited = false;
        if (Time.time >= ResetTime + timeTemp)
        {
            if (Network.isServer || Network.isClient)
            {
                if (Network.isServer)
                {
                    if (sceneManage)
                        sceneManage.ResetAllTrees();
                }
            }
            else
            {
                ResetTrees();
            }
            timeTemp = Time.time;
        }
    }

    public void ResetTrees()
    {
        RemovedIndexList.Clear();
        Loggers.Clear();
        terrain.terrainData.treeInstances = treesBackup;
    }

    bool LoggerChecker(int index)
    {
        // we cannot put HP variable to every trees in the scene
        // so we have to use something to define it by Index of a tree
        // a Logger using for define a HP to each trees

        foreach (Logger logger in Loggers)
        {
            if (logger.index == index)
                return false;
        }
        Logger newLogger = new Logger();
        newLogger.index = index;
        newLogger.HP = TreeHP;
        Loggers.Add(newLogger);
        return true;
    }

    bool LoggerApplyDamage(int damage, int index)
    {
        // apply damage to a tree
        if (!LoggerChecker(index))
        {
            foreach (Logger logger in Loggers)
            {
                if (logger.index == index)
                {
                    logger.HP -= damage;
                    if (logger.HP <= 0)
                    {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public void Cuttree(Vector3 position, int damage)
    {
        if (terrain == null)
            return;

        // we cannot specific a tree, we just find possibility around the position 
        int index = 0;
        foreach (TreeInstance tree in terrain.terrainData.treeInstances)
        {
            Vector3 treepos = Vector3.Scale(tree.position, terrain.terrainData.size) + Terrain.activeTerrain.transform.position;
            var distance = Vector3.Distance(new Vector3(treepos.x, position.y, treepos.z), position);
            // hit a tree if in ranged
            if (distance < BlastArea)
            {
                if (LoggerApplyDamage(damage, index))
                {
                    Drop(position);
                    RemovedIndexList.Add(index);
                    SendARemovedTree(index);
                    return;
                }
            }
            index++;
        }

    }

    public void SendARemovedTree(int index)
    {
        if (!Network.isServer && !Network.isClient)
        {
            // in single player
            RemoveATrees(index);
        }
        else
        {
            if (Network.isServer)
            {

                RemoveATrees(index);

                // only server can send a removed tree index;
                if (sceneManage)
                    sceneManage.SendRemovedTreeIndex(index);
            }
        }
    }

    public string GetRemovedTrees()
    {
        // convert array to string using for send via RPC network
        string arraylist = "";
        foreach (int index in RemovedIndexList)
        {
            arraylist += index + ",";
        }
        return arraylist;
    }

    public void UpdateRemovedTrees(string indexremoved)
    {
        // get all indexes of removed trees as a string
        if (terrain == null)
            return;

        RemovedIndexList.Clear();

        // convert them to array
        string[] indexes = indexremoved.Split(","[0]);
        for (int i = 0; i < indexes.Length; i++)
        {
            int res = -1;
            if (int.TryParse(indexes*, out res))*

RemovedIndexList.Add(res);
}
// save them to a removed index list

List instancesTmp = new List(terrain.terrainData.treeInstances);
foreach (int removed in RemovedIndexList)
{
// loop a removed index list find and remove a tree
instancesTmp.RemoveAt(removed);
}
// replace a tree instances in terrain data with new array
terrain.terrainData.treeInstances = instancesTmp.ToArray();
}

public void RemoveATrees(int index)
{
// remove a specific tree by index
List instancesTmp = new List();
int i = 0;
foreach (TreeInstance tree in terrain.terrainData.treeInstances)
{
// loop a all of a tree on terrain
if (i != index)
{
// basically add every tree to a Tmp array, Except a tree with a specfic index
instancesTmp.Add(tree);
}
i++;
}
// replace a tree instances in terrain data with a Tmp array
terrain.terrainData.treeInstances = instancesTmp.ToArray();
}

public void OnHit(DamagePackage dm)
{
if (!hited)
{
if (Network.isServer || (!Network.isClient && !Network.isServer))
{
Cuttree(dm.Position, dm.Damage);
hited = true;
}
}
}

public void Drop(Vector3 position)
{
// drap a wood
if (WoodDrop == null)
return;

for (int i = 0; i < DropNum; i++)
{
if (Network.isClient || Network.isServer)
{
if (Network.isServer)
Network.Instantiate(WoodDrop, DetectGround(position + new Vector3(Random.Range(-DropArea, DropArea), 0, Random.Range(-DropArea, DropArea))), WoodDrop.transform.rotation, 2);
}
else
{
GameObject.Instantiate(WoodDrop, DetectGround(position + new Vector3(Random.Range(-DropArea, DropArea), 0, Random.Range(-DropArea, DropArea))), WoodDrop.transform.rotation);
}
}
}

Vector3 DetectGround(Vector3 position)
{
RaycastHit hit;
if (Physics.Raycast(position, -Vector3.up, out hit, 1000.0f))
{
return hit.point;
}
return position;
}

void BackupTree()
{
if (terrain == null)
return;
// create backup trees data/
treesBackup = terrain.terrainData.treeInstances;
}

void OnApplicationQuit()
{
// Importance!! Need to restore all tree before close
// if not, all the removed trees will be lose forever
if (terrain == null)
return;
terrain.terrainData.treeInstances = treesBackup;
}

}

public class Logger
{
public int index;
public int HP;
}

Doesnt work because the โ€œtreeโ€ / index isnt a GameObject.

Destroy(GetComponent());
Destroy(GetComponent());
hope this is what you need

public void RemoveATrees (int index)
{
// remove a specific tree by index
List instancesTmp = new List ();
int i = 0;
foreach (TreeInstance tree in terrain.terrainData.treeInstances) {
// loop a all of a tree on terrain
if (i != index) {
// basically add every tree to a Tmp array, Except a tree with a specfic index
instancesTmp.Add (tree);
}
i++;
}
// replace a tree instances in terrain data with a Tmp array
terrain.terrainData.treeInstances = instancesTmp.ToArray ();
// refresh the terrain, get rid of collider of that tree.
float[,] heights = terrain.terrainData.GetHeights(0, 0, 0, 0);
terrain.terrainData.SetHeights(0, 0, heights);

    }

I donโ€™t know if you need that anymore but change your RemoveATrees to that and it works.