Making Duplicate Terrain Unique?

I need the ability to make a duplicate terrain unique, so that I may edit it’s terrainData without affecting the original terrain. I found this question Problem With Terrain Duplicates - Simple? - Questions & Answers - Unity Discussions that seems to indicate the only way is to reimport the heightmap, but that does not account for the trees and texture data. I’ve tried manually copying the terrainData info and reapplying it to a new terrain, but that still connects the data to the original.

Here is my code thus far, which just connects the terrain with the old terrainData. Is there a way to make the copied terrainData unique from the old?

using UnityEditor;
using UnityEngine;

public class TerrainTools : EditorWindow
{
	[MenuItem("Tools/Terrain Tools")]
	static void Iinit(MenuCommand command)
	{
		TerrainTools i = (TerrainTools)ScriptableObject.CreateInstance(typeof(TerrainTools));
		i.ShowUtility();
	}
	
	void OnGUI()
	{

		Terrain ter = Terrain.activeTerrain;
		GUILayout.Label("Terriain Name: " + ter.name, EditorStyles.boldLabel);
		
		if(GUILayout.Button("Store Terrain Data"))
			StoreTerrainData();
		
		if(GUILayout.Button("Set Terrain Data"))
			SetTerrainData();
		
		if(GUILayout.Button("Reset Terrain Data"))
			ResetTerrain();
		
		GUILayout.Space(10);
		
		GUILayout.BeginHorizontal();
			GUILayout.Label("Currently Stored Data ", EditorStyles.boldLabel);
			GUILayout.Label(stored);
		GUILayout.EndHorizontal();
		
		GUILayout.BeginHorizontal();
			GUILayout.Label("Currently Selected ", EditorStyles.boldLabel);
			GUILayout.Label(Terrain.activeTerrain.terrainData.name);
		GUILayout.EndHorizontal();
	}
	
	void ResetTerrain()
	{
		Terrain.activeTerrain.terrainData = new TerrainData();
	}
	
	TerrainData terData = new TerrainData();
	string stored = "";
	void StoreTerrainData()
	{
		stored = Terrain.activeTerrain.terrainData.name;
		terData = Terrain.activeTerrain.terrainData;
	}
	
	void SetTerrainData()
	{
		if(terData != null)
		{
			Terrain.activeTerrain.terrainData = terData;	
		}
	}
}

You will need to clone your original TerrainData to separate the copy from the original.

TerrainData newTerrainData = (TerrainData) Object.Instantiate(terData);

will do the trick. So your “Store” method should read:

void StoreTerrainData()
{
   stored = Terrain.activeTerrain.terrainData.name;
   terData = (TerrainData) Object.Instantiate(Terrain.activeTerrain.terrainData);
}

One more trap to be aware of: Your game object that contains the terrain (Terrain.activeTerrain.gameObject) usually also has a TerrainCollider on it. When you update the terrain data, you should also update the terrain collider.

void SetTerrainData()
{
   if(terData != null)
   {
     TerrainData newTerrainData = (TerrainData) Object.Instantiate(terData);
     Terrain.activeTerrain.terrainData = newTerrainData; 
     TerrainCollider tc = Terrain.activeTerrain.gameObject.GetComponent<TerrainCollider>();
     tc.terrainData = newTerrainData;
   }
}