Combines grass objects into one or several meshes.
Returned dictionary key is the grass index inside array and value holds the combined meshes associated to that index.
grassCombineType - Grass meshes combine type:
GrassCombineType.ByTexture - Grass meshes are combined based on the used grass texture.
GrassCombineType.ByTextureWithAtlas - Grass meshes are combined based on the used grass texture and mesh UV is generated based on the provided GrassAtlasTexture.
GrassCombineType.Everything - Combines all grass meshes into one file and for each mesh UV is generated based on the provided GrassAtlasTexture.
GrassMeshTexcoord2.PivotPoint - Bakes current grass quad mesh's pivot point's local position.
GrassMeshTexcoord2.BaseUV - Bakes current grass quad mesh's initial UV coordinates that will be overwritten in the case of using GrassAtlasTexture.
Dictionary<Texture2D, Rect> atlasRect - In the case of using GrassAtlasTexture, this property should provide collection of GrassTextures and UV coordinates associated with this texture inside GrassAtlasTexture.
exportPercentage - Percentage of the combined grass objects in the range of [0.01, 100]
maxVertexCountPerCombinedMesh - Defines how much vertices combined mesh(es) will contain.
int grassMeshSidesCount, float grassMeshDistortion - Specifies how much sides each grass quad mesh will contain and how much offset distortion they will have.
//Example of exporting grass from TerrainData
//and generating combined meshes by used texture
//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 grass from TerrainData
TerrainToMeshPrototype[] grassPrototypes = terrainData.TerrainToMesh().ExportPrototypes(TerrainToMeshEnum.Prototype.Grass);
//Combining 100% of grassPrototypes into meshes with each one with 65K vertices
Dictionary<int, Mesh[]> grassMeshes = TerrainToMeshUtilities.ConvertPrototypesToGrassMeshes(grassPrototypes,
TerrainToMeshEnum.GrassCombineType.ByTexture,
TerrainToMeshEnum.GrassMeshTexcoord2.None,
true,
null,
100,
65000);
//Creating materials for each layer
Dictionary<int, Material> grassMaterials = new Dictionary<int, Material>();
foreach (var item in grassMeshes)
{
Texture2D grassTexture = terrainData.detailPrototypes[item.Key].prototypeTexture;
Material material = new Material(TerrainToMeshUtilities.GetDefaultShader());
//Setting up material to use grass texture for '_MainTex' and enabling Alpha Cutout
TerrainToMeshUtilities.SetupDefaultMaterial(material, grassTexture, true, null, null, null);
material.name = grassTexture.name;
grassMaterials.Add(item.Key, material);
}
//Instantiating gameObject with grass meshes
foreach (var item in grassMeshes)
{
Mesh[] meshes = item.Value;
for (int i = 0; i < meshes.Length; i++)
{
GameObject grassGO = new GameObject($"Grass (Layer : {item.Key}) {grassMaterials[item.Key].name}");
grassGO.AddComponent<MeshFilter>().sharedMesh = meshes[i];
grassGO.AddComponent<MeshRenderer>().sharedMaterial = grassMaterials[item.Key];
grassGO.transform.SetParent(terrainGO.transform);
}
}
//Example of exporting grass from TerrainData,
//and generating combined meshes by used texture
//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 grass from TerrainData
TerrainToMeshPrototype[] grassPrototypes = terrainData.TerrainToMesh().ExportPrototypes(TerrainToMeshEnum.Prototype.Grass);
//Exporting grass atlas texture from TerrainData
Dictionary<Texture2D, Rect> atlasUVRect;
Texture2D grassAtlasTexture = terrainData.TerrainToMesh().ExportGrassAtlasTexture(1024, out atlasUVRect);
//Combining 100% of grassPrototypes into meshes with each one with 65K vertices
Dictionary<int, Mesh[]> grassMeshes = TerrainToMeshUtilities.ConvertPrototypesToGrassMeshes(grassPrototypes,
TerrainToMeshEnum.GrassCombineType.ByTextureWithAtlas,
TerrainToMeshEnum.GrassMeshTexcoord2.None,
true,
atlasUVRect,
100,
65000);
//Creating material using GrassAtlasTexture
Material grassAtlasMaterial = new Material(TerrainToMeshUtilities.GetDefaultShader());
grassAtlasMaterial.name = terrainData.name + " Grass Atlas";
//Setting up material to use GrassAtlasTexture for '_MainTex' and enabling Alpha Cutout
TerrainToMeshUtilities.SetupDefaultMaterial(grassAtlasMaterial, grassAtlasTexture, true, null, null, null);
//Instantiating gameObject with grass meshes
foreach (var item in grassMeshes)
{
Mesh[] meshes = item.Value;
for (int i = 0; i < meshes.Length; i++)
{
GameObject grassGO = new GameObject($"Grass (Layer: {item.Key})");
grassGO.AddComponent<MeshFilter>().sharedMesh = meshes[i];
grassGO.AddComponent<MeshRenderer>().sharedMaterial = grassAtlasMaterial;
grassGO.transform.SetParent(terrainGO.transform);
}
}
//Example of exporting grass 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 grass from TerrainData
TerrainToMeshPrototype[] grassPrototypes = terrainData.TerrainToMesh().ExportPrototypes(TerrainToMeshEnum.Prototype.Grass);
//Exporting grass atlas texture from TerrainData
Dictionary<Texture2D, Rect> atlasUVRect;
Texture2D grassAtlasTexture = terrainData.TerrainToMesh().ExportGrassAtlasTexture(1024, out atlasUVRect);
//Combining 100% of grassPrototypes into meshes with each one with 65K vertices
Dictionary<int, Mesh[]> grassMeshes = TerrainToMeshUtilities.ConvertPrototypesToGrassMeshes(grassPrototypes,
TerrainToMeshEnum.GrassCombineType.Everything,
TerrainToMeshEnum.GrassMeshTexcoord2.None,
true,
atlasUVRect,
100,
65000);
//Creating material using GrassAtlasTexture
Material grassAtlasMaterial = new Material(TerrainToMeshUtilities.GetDefaultShader());
grassAtlasMaterial.name = terrainData.name + " Grass Atlas";
//Setting up material to use GrassAtlasTexture for '_MainTex' and enabling Alpha Cutout
TerrainToMeshUtilities.SetupDefaultMaterial(grassAtlasMaterial, grassAtlasTexture, true, null, null, null);
//Instantiating gameObject with grass meshes
foreach (var item in grassMeshes)
{
Mesh[] meshes = item.Value;
for (int i = 0; i < meshes.Length; i++)
{
GameObject grassGO = new GameObject("Grass");
grassGO.AddComponent<MeshFilter>().sharedMesh = meshes[i];
grassGO.AddComponent<MeshRenderer>().sharedMaterial = grassAtlasMaterial;
grassGO.transform.SetParent(terrainGO.transform);
}
}
calculateHealthAndDryColor - Bakes prototype's and colors.
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 .