Search Unity

[SOLVED] How to modify a Terrain at runtime and get back to original Terrain on exit?

Discussion in 'Scripting' started by Eldoir, Aug 10, 2017.

  1. Eldoir

    Eldoir

    Joined:
    Feb 27, 2015
    Posts:
    60
    Hello,

    I'm trying to rotate a terrain in runtime, then I want the terrain to get back to its original rotation when I quit the app.

    I have basically this algorithm:

    - Copy ("clone") the Terrain Data
    - Rotate that copy
    - When quitting, the copy is automatically destroyed, so the terrain should get back to its original data.

    The following code implements this algorithm:

    Code (CSharp):
    1.  using UnityEngine;
    2. public class RotateTerrain : MonoBehaviour
    3. {
    4.      [SerializeField]
    5.      private Terrain terrain;
    6.      void Start()
    7.      {
    8.          WorkOnNewCopy();
    9.          // Now we can safely modify our terrain... Can we?
    10.          TerrainRotate(terrain, degrees: 90);
    11.      }
    12.      void WorkOnNewCopy()
    13.      {
    14.          TerrainData backup_terrainData = terrain.terrainData;
    15.          backup_terrainData.name = terrain.terrainData.name + "_tmp";
    16.          backup_terrainData = Instantiate(backup_terrainData);
    17.          terrain.terrainData = backup_terrainData;
    18.          terrain.GetComponent<TerrainCollider>().terrainData = backup_terrainData;
    19.          terrain.Flush();
    20.      }
    21.      void TerrainRotate(Terrain terrain, float degrees)
    22.      {
    23.          // Super-secret code
    24.      }
    25. }
    It's almost working: when I quit the app (or editor), I find myself with a weird mix between the original terrain, and the modified terrain. Everything seems to be back, except the ground texture (splat map). I feel close to the solution!

    Have you got an idea? Thanks in advance! :)
    (same thread as: http://answers.unity3d.com/questions/1391471/how-to-modify-a-terrain-at-runtime-and-get-back-to.html)
     
  2. Eldoir

    Eldoir

    Joined:
    Feb 27, 2015
    Posts:
    60
    I used this awesome script to safely clone my terrain: https://gist.github.com/Eldoir/d5a438dfedee55552915b55097dda1d4
    Just had to write this:
    Code (CSharp):
    1. terrain.terrainData = TerrainDataCloner.Clone(terrain.terrainData);
    2. terrain.GetComponent<TerrainCollider>().terrainData = terrain.terrainData; // Don't forget to update the TerrainCollider as well
    After this, the rotation works perfectly, and it reverts back automatically when I quit.
    Just what I wanted!
     
  3. pedroamarocosta

    pedroamarocosta

    Joined:
    Feb 27, 2018
    Posts:
    5
    Yes that helper class is key for any true deep-copy of a terrain. Only correct and updated solution i've found.