- Home /
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 http://answers.unity3d.com/questions/58342/problem-with-terrain-duplicates-simple.html 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;
}
}
}
Answer by Rabbit-Stew-dio · Feb 03, 2012 at 08:23 PM
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;
}
}
Thanks for the answer. This definitely works, but as a warning there are strange happenin's in scene view after editing the copy's splat map. If you add the original terrain data to the scene, viewing it at different distances will alternate between the old splat map and the new splat map, so there is some data that is still being shared between the two somehow.
The problem seems to be resolved the next time the scene is saved... but it's still strange, and merits a bit of caution.
Your answer
![](https://koobas.hobune.stream/wayback/20220613063531im_/https://answers.unity.com/themes/thub/images/avi.jpg)