Hey All,
I simply trying to get instance of added Detailed Meshes from Terrain Data,
There is already ‘TreeInstance’ in TerrainData but there is no ‘DetailInstance’, so I can’t access grass objects that instantiated in Terrain Tool, my purpose is taking out of all instances to world from terrain data.
Hello all, I have found the answer today, I wrote something like this, Hope it helps!
Copy all and paste somewhere
public class DetailedObjectInstance
{
public GameObject Prefab;
public Vector3 Position;
public Vector3 Rotation;
public Vector3 Scale;
public static DetailedObjectInstance[] ExportObjects(Terrain terrain)
{
List<DetailedObjectInstance> output = new List<DetailedObjectInstance>();
TerrainData data = terrain.terrainData;
if (terrain.detailObjectDensity != 0)
{
int detailWidth = data.detailWidth;
int detailHeight = data.detailHeight;
float delatilWToTerrainW = data.size.x / detailWidth;
float delatilHToTerrainW = data.size.z / detailHeight;
Vector3 mapPosition = terrain.transform.position;
bool doDentisy = false;
float targetDentisty = 0;
if (terrain.detailObjectDensity != 1)
{
targetDentisty = (1 / (1f - terrain.detailObjectDensity));
doDentisy = true;
}
float currentDentity = 0;
DetailPrototype[] details = data.detailPrototypes;
for (int i = 0; i < details.Length; i++)
{
GameObject Prefab = details*.prototype;*
float minWidth = details*.minWidth;*
float maxWidth = details*.maxWidth;*
float minHeight = details*.minHeight;*
float maxHeight = details*.maxHeight;*
int[,] map = data.GetDetailLayer(0, 0, data.detailWidth, data.detailHeight, 0);
List grasses = new List();
for (var y = 0; y < data.detailHeight; y++)
{
for (var x = 0; x < data.detailWidth; x++)
{
if (map[x, y] > 0)
{
currentDentity += 1f;
bool pass = false;
if (!doDentisy)
pass = true;
else
pass = currentDentity < targetDentisty;
if (pass)
{
float z = (x * delatilWToTerrainW) + mapPosition.z;
float x = (y * delatilHToTerrainW) + mapPosition.x;
float _y = terrain.SampleHeight(new Vector3(_x, 0, _z));
grasses.Add(new Vector3(
_x,
_y,
_z
));
}
else
{
currentDentity -= targetDentisty;
}
}
}
}
foreach (var item in grasses)
{
DetailedObjectInstance e = new DetailedObjectInstance();
e.Prefab = Prefab;
e.Position = item;
e.Rotation = new Vector3(0, UnityEngine.Random.Range(0, 360), 0);
e.Scale = new Vector3(UnityEngine.Random.Range(minWidth, maxWidth), UnityEngine.Random.Range(minHeight, maxHeight), UnityEngine.Random.Range(minWidth, maxWidth));
output.Add(e);
}
}
}
return output.ToArray();
}
}
**After that its ready to use **
An Example of usage =>
private void Awake()
{
Terrain terrian = GetComponent();
DetailedObjectInstance[] objects = DetailedObjectInstance.ExportObjects(terrian);
foreach (var item in objects)
{
GameObject obj = Instantiate(item.Prefab, item.Position, Quaternion.Euler(item.Rotation));
obj.transform.localScale = item.Scale;
}
}
thank you so much. you saved my a big time. you are awesome!