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”.