Returned dictionary key is the grass index inside TerrainData.detailPrototypes array and value holds the combined meshes associated to that index.
calculateHealthAndDryColor - Bakes health and dry colors from TerrainData inside combined mesh vertex color.
exportPercentage - Percentage of the combined detail objects in the range of [0.01, 100]
maxVertexCountPerCombinedMesh - Defines how much vertices combined mesh(es) will contain.
Theoretically Unity can create mesh with 4 billion vertices, but for run-time use it is better to use more logical values. Based on the used vertex count, generated meshes will be in 16 or 32 bits index format.
//Example of exporting detail meshes from TerrainData
//and combining them all into one mesh
//Exporting terrain mesh
Mesh terrainMesh = terrainData.TerrainToMesh().ExportMesh(100, 100);
//Creaing GameObject using terrain mesh
GameObject terrainGO = new GameObject("Terrain");
terrainGO.AddComponent<MeshFilter>().sharedMesh = terrainMesh;
terrainGO.AddComponent<MeshRenderer>().sharedMaterial = new Material(TerrainToMeshUtilities.GetDefaultShader());
//Exporting detail meshes from TerrainData
TerrainToMeshPrototype[] detailMeshPrototypes = terrainData.TerrainToMesh().ExportPrototypes(TerrainToMeshEnum.Prototype.DetailMesh);
//Combining 100% of detailMeshPrototypes into meshes with each one with 65K vertices
Dictionary<int, Mesh[]> detailMeshes = TerrainToMeshUtilities.ConvertPrototypesToDetailMeshes(detailMeshPrototypes, true, 100, 65000);
//Instantiating gameObject with detail meshes
foreach (var item in detailMeshes)
{
Mesh[] meshes = item.Value;
for (int i = 0; i < meshes.Length; i++)
{
GameObject detailGO = new GameObject($"Detail Mesh (Layer: {item.Key})");
detailGO.AddComponent<MeshFilter>().sharedMesh = meshes[i];
//Reading material from the original detail mesh prototype
GameObject originalPrefab = terrainData.detailPrototypes[item.Key].prototype;
Material material = originalPrefab.GetComponentInChildren<MeshRenderer>().sharedMaterial;
detailGO.AddComponent<MeshRenderer>().sharedMaterial = material;
detailGO.transform.SetParent(terrainGO.transform);
}
}