• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by zharramadar · Dec 05, 2010 at 12:42 AM · gameobjectterrainduplicate

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?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

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.)

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image zharramadar · Dec 05, 2010 at 02:12 AM 0
Share

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

avatar image zharramadar · Dec 06, 2010 at 02:44 AM 0
Share

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.

avatar image
1

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);
         }
     }
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image unity_MHNQscX8iwjV3Q · Aug 12 at 04:16 AM 1
Share

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

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

2 People are following this question.

avatar image avatar image

Related Questions

Dealing with placing large amounts of objects via script? 1 Answer

Can't get Object size to Reset to Original 1 Answer

terrain work 2 Answers

Gameobject collision with Terrain C# 4 Answers

GameObjects vs. Submeshes 2 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges