Skip to content

Instantly share code, notes, and snippets.

@xulub
Created November 19, 2022 08:33
Show Gist options
  • Save xulub/af5a84b25162522e8bde0c216b965720 to your computer and use it in GitHub Desktop.
Save xulub/af5a84b25162522e8bde0c216b965720 to your computer and use it in GitHub Desktop.
How to convert Unity terrain detail meshes to GameObjects (based on https://answers.unity.com/questions/1327033/trying-to-get-detailed-mesh-instances-from-terrain.html)
public class TerrainDetailConverter
{
Terrain _terrain;
...
void Convert()
{
var terrainData = _terrain.terrainData;
var scaleX = terrainData.size.x / terrainData.detailWidth;
var scaleZ = terrainData.size.z / terrainData.detailHeight;
var targetDensity = Mathf.RoundToInt((1f - _terrain.detailObjectDensity) * 4);
for (int d = 0; d < terrainData.detailPrototypes.Length; d++)
{
var detailPrototype = terrainData.detailPrototypes[d];
var detailLayer = terrainData.GetDetailLayer(0, 0, terrainData.detailWidth, terrainData.detailHeight, d);
var accumulatingDensity = 0f;
for (int x = 0; x < terrainData.detailWidth; x++)
{
for (int y = 0; y < terrainData.detailHeight; y++)
{
var layerDensity = detailLayer[y, x];
if (layerDensity > 0)
accumulatingDensity += layerDensity;
if (accumulatingDensity > targetDensity)
{
var pos = new Vector3(x * scaleX + _terrain.transform.position.x, 0, y * scaleZ + _terrain.transform.position.z);
pos.y = _terrain.SampleHeight(pos);
var detail = Instantiate(terrainData.detailPrototypes[d].prototype, pos, Quaternion.Euler(0, Random.Range(0, 359), 0), transform);
var scale = Random.Range(detailPrototype.minWidth, detailPrototype.maxWidth);
detail.transform.localScale = Vector3.one * scale;
accumulatingDensity = 0;
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment