I have a terrain prefab. If I place more than one instance of this terrain in my scene (either using the editor or using a script) and then paint textures onto one of them (modifying the splat map), the same changes to the splat map appear on the other instance as well. See the picture below – I painted the green ‘S’ on one instance of the landscape, and it appeared on both. How can I make these instances completely separate so that I can modify their splat maps separately?
Note that I already tried giving them different TerrainDatas, by script. That allowed me to change their height maps separately, but not their splat maps.
I just wrote a complete deep-copying helper as I had to duplicate a source terrain into distinct copies:
This way copying a terrain is as easy as:
newTerrain.terrainData = ZS.Tools.TerrainDataCloner.Clone(sourceTerrain.terrainData);
In case anyone else has this problem in the future, here’s the solution I found. First, I instantiated the terrain:
terrainPatches[x,z] = (Terrain) Instantiate(terrainPrefab, new Vector3(0, 0, 0), Quaternion.identity);
Then, I needed to create a new TerrainData instance from scratch. It didn’t work if I instantiated the TerrainData instance from a prefab – they would all share the same splat maps. Instead, I had to create each TerrainData from scratch, fill in its attributes, and create the array of SplatPrototypes for each one. Here’s the code I’m using, that solved the problem:
terrainPatches[x,z].terrainData = new TerrainData();
terrainPatches[x,z].terrainData.heightmapResolution = 129;
terrainPatches[x,z].terrainData.size = new Vector3(200,80,200);
terrainPatches[x,z].terrainData.alphamapResolution = 128;
terrainPatches[x,z].terrainData.baseMapResolution = 256;
terrainPatches[x,z].terrainData.SetDetailResolution(256, 8);
SplatPrototype[] splatPrototypes = new SplatPrototype[10];
for (int i = 0; i < 10; i++) {
splatPrototypes *= new SplatPrototype();*
_ splatPrototypes*.tileOffset = new Vector2(0,0);_
_ splatPrototypes.tileSize = new Vector2(20,20);
switch (i) {
case 0: splatPrototypes.texture = terrainTexture0; splatPrototypes.normalMap = rockNormalMap; break;
case 1: splatPrototypes.texture = terrainTexture1; break;
case 2: splatPrototypes.texture = terrainTexture2; break;
case 3: splatPrototypes.texture = terrainTexture3; splatPrototypes.normalMap = grassNormalMap; break;
case 4: splatPrototypes.texture = terrainTexture4; splatPrototypes.normalMap = rockNormalMap; break;
case 5: splatPrototypes.texture = terrainTexture5; splatPrototypes.normalMap = rockNormalMap; break;
case 6: splatPrototypes.texture = terrainTexture6; break;
case 7: splatPrototypes.texture = terrainTexture7; break;
case 8: splatPrototypes.texture = terrainTexture8; break;
case 9: splatPrototypes.texture = terrainTexture9; break;
}
}
terrainPatches[x,z].terrainData.splatPrototypes = splatPrototypes;*_