Currently, A* Pathfinding will only look for a single collider on the root game object of terrain trees. Here is a modification to CollectTreeMeshes() in RecastMeshGatherer.cs that will allow for multiple colliders with offset positions/rotations.
Note: If you are using “random rotation” on your trees, Unity will never rotate the colliders (only the mesh). This is a limitation of Unity terrain. So in general, never use “random rotation” on terrain trees that have more than a single, straight capsule collider.
This modification will ignore trees without any colliders. For my purposes I like to have small shrubs that need to be “trees” but I do not want colliders or path blocked. You can add the code back for that if you prefer from the original CollectTreeMeshes().
void CollectTreeMeshes(Terrain terrain, List<RasterizationMesh> result)
{
// modified jb
TerrainData data = terrain.terrainData;
Vector3 treeColliderPos;
Quaternion treeColliderRot;
for (int i = 0; i < data.treeInstances.Length; i++)
{
TreeInstance instance = data.treeInstances[i];
TreePrototype prot = data.treePrototypes[instance.prototypeIndex];
// Make sure that the tree prefab exists
if (prot.prefab == null)
{
continue;
}
Collider[] treeColliders = prot.prefab.transform.GetComponentsInChildren<Collider>();
var treePosition = terrain.transform.position + Vector3.Scale(instance.position, data.size);
var scale = new Vector3(instance.widthScale, instance.heightScale, instance.widthScale);
for (int x = 0; x < treeColliders.Length; x++)
{
treeColliderPos = treePosition + Vector3.Scale(treeColliders[x].gameObject.transform.position - prot.prefab.transform.position, scale);
treeColliderRot = treeColliders[x].gameObject.transform.rotation;
// Generate a mesh from the collider
RasterizationMesh mesh = RasterizeCollider(treeColliders[x], Matrix4x4.TRS(treeColliderPos, treeColliderRot, scale));
// Make sure a valid mesh was generated
if (mesh != null)
{
// The bounds are incorrectly based on collider.bounds.
// It is incorrect because the collider is on the prefab, not on the tree instance
// so we need to recalculate the bounds based on the actual vertex positions
mesh.RecalculateBounds();
result.Add(mesh);
}
}
}
}