saving terrain to xml

Hi,

I’m writing and editor script to save my terrains to xml.
I can’t get the grass to save.

static void Save ()
{
		GameObject tr = Selection.activeGameObject;
		TerrainData data = tr.GetComponent<TerrainCollider> ().terrainData;

		heightmapResolution = data.heightmapResolution;
		size = data.size;
		detailResolution = data.detailResolution;
		detailPrototypes = data.detailPrototypes;
		wavingGrassStrength = data.wavingGrassStrength;
		wavingGrassAmount = data.wavingGrassAmount;
		wavingGrassSpeed = data.wavingGrassSpeed;
		wavingGrassTint = data.wavingGrassTint;
		treeInstances = data.treeInstances;
		treePrototypes = data.treePrototypes;
		alphamapResolution = data.alphamapResolution;
		baseMapResolution = data.baseMapResolution;
		splatPrototypes = data.splatPrototypes;

		MapHeight = data.GetHeights (0, 0, data.heightmapWidth, data.heightmapHeight);
		terrainAlphamaps = data.GetAlphamaps (0, 0, data.alphamapResolution, data.alphamapResolution);
		
		pixelError = tr.GetComponent<Terrain>().heightmapPixelError;
		baseMapDistance = tr.GetComponent<Terrain>().basemapDistance;
		castShadows = tr.GetComponent<Terrain>().castShadows;
		detailObjectDistance = tr.GetComponent<Terrain>().detailObjectDistance;
		detailObjectDensity = tr.GetComponent<Terrain>().detailObjectDensity;
		treeDistance = tr.GetComponent<Terrain>().treeDistance;
		billBoardStart = tr.GetComponent<Terrain>().treeBillboardDistance;
		fadeLength = tr.GetComponent<Terrain>().treeCrossFadeLength;
		maxMeshTrees = tr.GetComponent<Terrain>().treeMaximumFullLODCount;
		DestroyImmediate (tr);
}

What i’m i missing ?
Thanks.

GetDetailLayer/SetDetailLayer

What you’ll want to do is turn those into a single int[,] instead of a lot of int[,]'s

To iterate through the layers, use

Something like:

void Save() {
	int[,,] details = new int[terrainData.detailPrototypes.Length,terrainData.detailResolution,terrainData.detailResolution];
	
	for (int i = 0; i < terrainData.detailPrototypes.Length; i++){
		int[,] theseDetails = terrainData.GetDetailLayer(0,0,terrainData.detailResolution,terrainData.detailResolution,i);
		// Combine theseDetails into details[i,,] for later access
	}
}

You may need to use detailWidth/Height instead of resolution - I forget if it’s always square or not. Anyhow, hope that helps!

Hi,

Thanks for that but i ran into another problem :

		details = new int[data.detailPrototypes.Length,data.detailResolution,data.detailResolution];
		for (int i = 0; i < data.detailPrototypes.Length; i++){
			theseDetails = data.GetDetailLayer(0,0,data.detailResolution,data.detailResolution,i);
		}

		for (int n = 0; n < details.Length; n++)
		{
			data.SetDetailLayer(0, 0, n, theseDetails[n]);
		}

and i’m getting this error when i set the details back:

Well you need to actually merge theseDetails into details - and then access them from details, not theseDetails. But lets simplifying things and just use a generic list…

TerrainData terrainData = new TerrainData();
		List<int[,]> details = new List<int[,]>();
		
		// GET
		for (int i = 0; i < terrainData.detailPrototypes.Length; i++){
			details.Add(terrainData.GetDetailLayer(0,0,terrainData.detailWidth, terrainData.detailHeight, i));
		}
		
		// SET
		for (int i = 0; i < terrainData.detailPrototypes.Length; i++){
			terrainData.SetDetailLayer(0,0,i, details[i]);
		}

yes, that worked. not grasping it yet but i will study it more.
thank you very much :slight_smile: