How to make terrain tree fall when a gameobject collides or touches it

Hi everyone, I have trying to make the terrain trees fall when an enemy gameobject collides or touches it. I have searched and tried a lot of code with no luck and would really need some help.

Pretty sure terrain trees can’t (easily) be chopped down / knocked over like that.

To do such a thing you would likely need your own tree objects that fall over in some fashion, perhaps:

  • using physics?
  • using a pre-canned animation?
  • using your own tweener code?
  • something else?

You’ll need to remove the chosen tree from the terrain and instantiate your own tree in its place and then make it fall over.
I asked Google’s Gemini on how to remove a tree from the terrain:

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

public class TreeRemover : MonoBehaviour
{
    // Assign your terrain in the inspector
    public Terrain terrain;

    void Start()
    {
        // If terrain is not assigned, try to find the active terrain
        if (terrain == null)
        {
            terrain = Terrain.activeTerrain;
        }
    }

    /// <summary>
    /// Finds and removes the closest tree to a given world position.
    /// </summary>
    /// <param name="worldPosition">The position in the world to find the closest tree to.</param>
    public void RemoveClosestTree(Vector3 worldPosition)
    {
        TerrainData terrainData = terrain.terrainData;
        
        // Get all trees from the terrain
        List<TreeInstance> allTrees = new List<TreeInstance>(terrainData.treeInstances);
        
        if (allTrees.Count == 0)
            return;

        int treeIndexToRemove = -1;
        float minDistance = float.MaxValue;

        // Find the closest tree to the given position
        for (int i = 0; i < allTrees.Count; i++)
        {
            // Get the tree's position in world space
            TreeInstance currentTree = allTrees[i];
            Vector3 treeWorldPosition = Vector3.Scale(currentTree.position, terrainData.size) + terrain.transform.position;
            
            float distance = Vector3.Distance(treeWorldPosition, worldPosition);

            if (distance < minDistance)
            {
                minDistance = distance;
                treeIndexToRemove = i;
            }
        }

        // If a tree was found
        if (treeIndexToRemove != -1)
        {
            // Remove the tree from our list
            allTrees.RemoveAt(treeIndexToRemove);

            // IMPORTANT: Apply the new tree list back to the terrain data
            terrainData.treeInstances = allTrees.ToArray();
            
            // Optional: Refresh the terrain to reflect the change immediately
            terrain.Flush();
        }
    }

    // --- Example Usage ---
    // Example of how you might call this script from another script (e.g., a player controller)
    void Update()
    {
        // When the player presses the 'F' key, try to remove a tree in front of them
        if (Input.GetKeyDown(KeyCode.F))
        {
            // Raycast forward from the camera
            Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2));
            if (Physics.Raycast(ray, out RaycastHit hit, 100.0f))
            {
                // We hit something, now remove the closest tree to that hit point
                Debug.Log("Ray hit at: " + hit.point);
                RemoveClosestTree(hit.point);
            }
        }
    }
}

You could try asking it how to add a copy of the removed tree in its place. Or take a look here. Basically you can get the tree’s prefab from the terrain’s “prototypes”.