Jump to content

GeNa terrain decorator deformations persist after runtime operation


FoxTheDog

Recommended Posts

I am using GeNa spawners and terrain decorators in a procedural environment. I have a few Gaia terrains that I modify with prefabs / biomes every time the player visits them. Over the course of 1) playtesting, and 2) actually playing the build, I've noticed that the flattened region where structures had been spawned in previous visits to the planet remain in subsequent visits. 

Is there a way to 'undo' the terrain deformation caused by a runtime executed decorator spawn on exiting play mode? 

Thanks for any advice you can provide.

Link to comment
Share on other sites

On 1/26/2022 at 9:19 AM, FoxTheDog said:

I am using GeNa spawners and terrain decorators in a procedural environment. I have a few Gaia terrains that I modify with prefabs / biomes every time the player visits them. Over the course of 1) playtesting, and 2) actually playing the build, I've noticed that the flattened region where structures had been spawned in previous visits to the planet remain in subsequent visits. 

Is there a way to 'undo' the terrain deformation caused by a runtime executed decorator spawn on exiting play mode? 

Thanks for any advice you can provide.

We are looking into this. 

Link to comment
Share on other sites

Unity terrain stores its data in what essentially acts like a scriptable object. What this means is that changes at design time and runtime are persisted.

You would need to backup and restore the terraindata to revert this behaviour. GeNa has an in memory undo, you would need to call that when you exit play mode.

 

 

 

Link to comment
Share on other sites

Thanks for the reply. I've been digging into the API docs and found GeNaSpawner.UndoAll(). Although the function is public, I'm having a hard time calling it. My idea was to use the onApplicationQuit event to undo all the spawns that a single spawner made (those with terrain decorators). Something like this:

[SerializeField] GeNa.Core.GeNaSpawner spawner
void OnApplicationQuit()
    {
        spawner.UndoAll();
    }

I'm clearly not understanding the docs though, UndoAll doesn't appear to be a public method of the GenaSpawner class (but I am admittedly very new to all this!)

5 hours ago, Adam said:

You would need to backup and restore the terraindata to revert this behaviour. GeNa has an in memory undo, you would need to call that when you exit play mode.

I've looked into this, its nothing I've done before and a bit complex. Are you suggesting that GeNa's in memory undo would handle the backup and restore of the terrain data, or are those separate tasks? Im guessing saving and loading the terrain data isnt going to be very performant in a build.. but I did find this post (2013, recent comment 2019) about the subject, in case anyone else is interested.

 https://answers.unity.com/questions/390209/how-to-prevent-terrain-changes-from-being-permanen.html

 

 

Link to comment
Share on other sites

@Manny This is indeed a huge help. I either need to rethink how I'm using the procedural spawners or implement some sort of deep copy / reload of the terraindata. I'll look into the latter and if its reasonable and works, I'll update this thread to share the solution with the community. Thanks again, you guys are really helping me out!

Link to comment
Share on other sites

Well this was incredibly simple after all, the solution suggested by @Manny and @Adam works like a charm. I fixed up some deprecated code but used the script linked above mostly as is. 

For the sake of completeness, I wrote a tiny script that takes the Terrain component from Gaia and assigns the terrain data and collider components to the deep copy. I only have one tile per scene here, but you easily could iterate over the hierarchy and get the terrain component at runtime rather than assign it in the editor like I do here. ,Literally copy pasted from the thread above.

using UnityEngine;

// Uses TerrainDataCloner to create a deep copy of the terrain.
// Subsequent edits to the terrain and its collider at runtime will be
// made to the deep copy rather than the original.
// Useful if you re-use a handful of terrains with procedurally spawned
// prefabs that modify the mesh and/or details.
//
// TerrainDataCloner: https://gist.github.com/Eldoir/d5a438dfedee55552915b55097dda1d4
// Unity thread: https://tinyurl.com/ykbd2fze
public class TerrainCloneRestore : MonoBehaviour
{

    [SerializeField] Terrain terrain;
    private void Awake()
    {
        terrain.terrainData = TerrainDataCloner.Clone(terrain.terrainData);
        terrain.GetComponent<TerrainCollider>().terrainData = terrain.terrainData; 
    }

}

 

Thanks again!

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Tell a friend

    Love Canopy - Procedural Worlds? Tell a friend!
  • Need help?

    We work with some of the biggest brands in global gaming, automotive, technology, and government to create environments, games, simulations, and product launches for desktop, mobile, and VR.

    Our unique expertise and technology enable us to deliver solutions that look and run better at a fraction of the time and cost of a typical project.

    Check out some of our non-NDA work in the Gallery, and then Contact Us to accelerate your next project!

×
×
  • Create New...