- Home /
Unity 2017 does not update tree collider in terrain
I wrote a c# script that remove a raycasted tree inside a terrain and I add a new tree outside the terrain gameobject. I refresh the terrain with the following code:
float[,] heights = g_terrain.terrainData.GetHeights(0, 0, 0, 0);
g_terrain.terrainData.SetHeightsDelayLOD(0, 0, heights);
g_terrain.ApplyDelayedHeightmapModification();
When I remove the iskinematic boolean variable present in the rigidbody associated to the tree, this is shot up in the sky... it seems that the tree collider inside the terrain is already present as if the code used to update the heightmap does not work. Any idea?
Answer by underhand · Oct 05, 2017 at 08:01 PM
To avoid the problem mentioned before, I create a method that create automatically CapsuleColliders on terrain trees, when some trees are near than a specified radius. The code is reported here after:
private void CreateCollider()
{
Vector3 playerposition = Player.transform.position;
int _treecount = g_terrain.terrainData.treeInstanceCount;
List<string> _namesCollider = new List<string>();
for (int _i = 0; _i < _treecount; _i++)
{
TreeInstance treeInstance = g_terrain.terrainData.GetTreeInstance(_i);
Vector3 treeposition = Vector3.Scale(treeInstance.position, g_terrain.terrainData.size);
int distance = (int)Vector3.Distance(playerposition, treeposition);
if (distance <= ColliderDistance)
{
Transform trs = Terrain.transform.Find(_i.ToString());
if (trs == null)
{
GameObject gameObject = new GameObject(_i.ToString());
gameObject.transform.position = treeposition;
gameObject.transform.SetParent(Terrain.transform);
CapsuleCollider capsuleCollider = gameObject.AddComponent<CapsuleCollider>();
capsuleCollider.center = g_capsulecolliders[treeInstance.prototypeIndex].center * treeInstance.heightScale;
capsuleCollider.height = g_capsulecolliders[treeInstance.prototypeIndex].height * treeInstance.heightScale;
capsuleCollider.radius = g_capsulecolliders[treeInstance.prototypeIndex].radius * treeInstance.widthScale;
_namesCollider.Add(_i.ToString());
}
else
{
_namesCollider.Add(_i.ToString());
}
}
}
int _numcollider = Terrain.transform.childCount;
bool _found = false;
for (int _i = 0; _i < _numcollider; _i++)
{
for (int _j = 0; _j < _namesCollider.Count; _j++)
{
if (Terrain.transform.GetChild(_i).name == _namesCollider[_j])
{
_found = true;
break;
}
}
if (!_found)
Destroy(Terrain.transform.GetChild(_i).gameObject);
else
_found = false;
}
}
The flag "Enable Tree Colliders" in the Terrain Collider must be set to false.