- Home /
Cannot change detaillayer after cloning terraindata
Hi,
I am stuck with the following problem: I cannot change the detaillayer of my terrain after cloning it. I've tested a lot of different approaches, but grass or any other detail I add on runtime does not show up, even though I don't get any error messages. Here is what I do:
Duplicate the terrain data on runtime:
Terrain terrain = terrainTemp.GetComponent<Terrain>();
TerrainData newTerrainData = (TerrainData) Object.Instantiate(terrain.terrainData);
terrain.terrainData = newTerrainData;
TerrainCollider tc = terrain.gameObject.GetComponent<TerrainCollider>();
tc.terrainData = newTerrainData;
Add prototypes:
for (int i = 1; i < max; i++) {
DetailPrototype detailProto = new DetailPrototype ();
detailProto.prototype = (GameObject)Resources.Load (path + i);
detailProto.dryColor = Color.yellow;
detailProto.healthyColor = Color.green;
detailProto.maxHeight = 2f;
detailProto.maxWidth = 2f;
detailProto.minHeight = 1f;
detailProto.minWidth = 1f;
detailProto.noiseSpread = 0.1f;
detailProto.usePrototypeMesh = true;
detailProto.renderMode = DetailRenderMode.Grass;
detailPrototypes.Add (detailProto);
}
Add prototypes to terraindata:
terrain.terrainData.detailPrototypes = detailPrototypes.ToArray ();
terrain.terrainData.RefreshPrototypes ();
And for testing purposes add some grass to every spot in the terrain:
int[,] newMap = new int[DETAIL_RESOLUTION, DETAIL_RESOLUTION];
for (int i = 0; i <DETAIL_RESOLUTION; i++) {
for (int j = 0; j <DETAIL_RESOLUTION; j++) {
newMap [i, j] = 1;
}
}
terrain.terrainData.SetDetailLayer (0, 0, 0, newMap);
I also add trees on runtime via code, but for some reason adding trees work without fail. Do you know why the grass is not painted?
Thank your for your help.
I'm getting the same problem. You ever figure out what's going on? Is this a bug? If so, did you ever figure out how to prevent your detail layer changes from persisting?
Afaik it was just another conversion issue. The code to change the detail of layer 0 at one location looks like this:
TerrainData terrainDataTemp = terrainTemp.terrainData;
Vector3 terrainPosTemp = terrainTemp.transform.position;
int detailWidth = terrainDataTemp.detailWidth;
int detailHeight = terrainDataTemp.detailHeight;
float mapX = ((selectedLocation.x - terrainPosTemp.x) / terrainDataTemp.size.x) * detailWidth;
float mapZ = ((selectedLocation.z - terrainPosTemp.z) / terrainDataTemp.size.z) * detailHeight;
if (terrainDataTemp.detailPrototypes.Length > 0)
{
int[,] detailLayer = terrainDataTemp.GetDetailLayer((int)mapX, (int)mapZ, detailWidth, detailHeight, 0);
detailLayer[0, 0] = 8;
terrainDataTemp.SetDetailLayer((int)mapX,(int)mapZ, 0, detailLayer);
}
Note: detailLayer[0,0] = 8 changes the density to 8. I haven't tested other values, since there are more pressing issues for me to take care of.
Give it a try and report back if it solved it for you.
Edit: Duplicating terraindata works on my end like this:
TerrainData newTerrainData = (TerrainData)Object.Instantiate (terrain.terrainData);
#if UNITY_EDITOR
AssetDatabase.CreateAsset (newTerrainData, "Assets/Resources/_Scenes/$$anonymous$$issions/" + terrain.name + ".asset");
AssetDatabase.Refresh();
#else
#endif
terrain.terrainData = newTerrainData;
TerrainCollider tc = terrain.gameObject.GetComponent<TerrainCollider> ();
tc.terrainData = newTerrainData;
Yeah, I only need to change the density between two grass types, so I'm just saving the detail layer at start and re-applying at the end. I dup'ed my terrain as well as a backup. Nice solution for the editor there as well.
Your answer
![](https://koobas.hobune.stream/wayback/20220613103628im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Making Duplicate Terrain Unique? 1 Answer
Paint Terrain Texture From Vector3 List 0 Answers
Duplicated objects go crazy at runtime 0 Answers
How to export heightmap of a terrain during runtime. 0 Answers