- Home /
Duplicating Terrain at run-time
Hello everyone,
I'm trying here, unsuccessfully, to duplicate terrains in real-time.
I have 2 GameObjects, named "Terrain00" and "Terrain01". Each of them have a Terrain object, created dynamically from resources I get from a socket stream. I want now to, at certain event in my application, to remove Terrain00 terrain (but keeping the GameObject) and duplicate, or move, the terrain inside Terrain01.
I managed to get a instance of each terrain, managed to make a copy of the terrain with Instantiate, and even managed to delete the terrain in Terrain00, but I didn't found a way so far to insert the copied terrain in Terrain00.... All I could do so far is to create a new blank terrain with GameObject.AddComponent.... I'm trying to avoid to create a new terrain in Terrain00 and then export everything to my new terrain, as terrainData, terrainCollider, and so on.
Is there any way to do this?
Answer by Eric5h5 · Dec 05, 2010 at 02:05 AM
There's no point trying to avoid copying everything over, because that's what you have to do. There isn't a Terrain.Copy function, but you can make one yourself fairly easily. (Terrain.CreateTerrainGameObject just links to an existing TerrainData, so it's not helpful here.)
Exactly what I wanted to avoid.... oh well, let's do it then. So nice if there was any method to simply duplicate terrains without having to build one =D I love to be lazy hehe
Just updating for future reference... I just duplicated my GameObject containing the Terrain, and everything inside it went along (Terrain, terraincollider, trees, parameters, splats, etc). Then I deleted my old gameobject and renamed it as my old object. This caused my terrain scripts to reset its attributes, so I had to save them in a global variable... maybe not the most elegant solution, but it worked perfectly.
Answer by hasCode · Jun 08, 2014 at 11:02 PM
Eric is correct, but I too enjoy being lazy.
I am setting up my height map and my splat map via code. Therefore, all I really need is a shallow copy of all the TerrainData properties that I setup in the designer.
I threw together this prototype and tested that it works.
To my fellow lazy coders, enjoy:
// this is garbage test code, but you get the idea
public class TerrainSpawner : MonoBehaviour {
public GameObject terrainPrefab;
// Use this for initialization
IEnumerator Start () {
GameObject terrainGameObject = (GameObject) Instantiate (terrainPrefab, new Vector3 (-1000.0F, 0.0F, -1000.0F), terrainPrefab.transform.rotation);
yield return new WaitForSeconds (5.0F); // waiting for 5 seconds so I can watch it spawn the 2nd terrain in the scene view while it's running
Terrain terrain = terrainPrefab.GetComponent<Terrain> ();
TerrainData terrainData = new TerrainData ();
CopyFrom (terrainData, terrain.terrainData); // copy the basic getable/setable properties
GameObject newTerrainGameObject = (GameObject) Instantiate (terrainPrefab, new Vector3 (-3000.0F, 0.0F, -1000.0F), terrainPrefab.transform.rotation);
Terrain newTerrain = newTerrainGameObject.GetComponent<Terrain> ();
newTerrain.terrainData = terrainData;
}
// previously an extension method
public static void CopyFrom<T1, T2>(T1 obj, T2 otherObject)
where T1: class
where T2: class
{
PropertyInfo[] srcFields = otherObject.GetType().GetProperties(
BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);
PropertyInfo[] destFields = obj.GetType().GetProperties(
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty);
foreach (var property in srcFields) {
var dest = destFields.FirstOrDefault(x => x.Name == property.Name);
if (dest != null && dest.CanWrite)
dest.SetValue(obj, property.GetValue(otherObject, null), null);
}
}
}
This is the ONLY solution found for cases where there's no explicitly saved terrainData asset. Super relevant for recovering complex terrains when the only thing remaining is a backup scene.
Your answer
Follow this Question
Related Questions
Vegetation problem 1 Answer
Why do I get duplicate gameobject assets when updating geometry? 1 Answer
Airplane - Collision With Terrain Problem 1 Answer
Duplicated Terrain Object and Data STILL affects other terrains 4 Answers
terrain work 2 Answers