- Home /
Issue copying heightmaps from a LARGE terrain to a new, small, cutout Terrain with GETHEIGHTS and SETHEIGHTS
I have a large terrain and I have successfully cut out a section and copied all information over to a newly created and smaller terrain/terraindata and shown it in game. The only issue I seem to have is GetHeights and SetGeights.
Getheights seems to correctly get the correct height information but when I use setheights on the new terrain, it SCALES the information to the smaller terrain. So, lets say I want to create a new terrain that is 1/2 the size in both width and height, The code I use is:
TerrainData workData = new TerrainData();
Terrain workTerrain = Terrain.CreateTerrainGameObject(workData).GetComponent<Terrain>();
workData.heightmapResolution = sourceTerrain.terrainData.heightmapResolution;
workData.size = new Vector3(Size, sourceTerrain.terrainData.size.y, Size); // Size
float[,] sourceHeights = sourceTerrain.terrainData.GetHeights(X, Y, Size, Size);
workData.SetHeights(0, 0, sourceHeights);
This code will copy over the heights, but everything is CRUSHED and the rest of the terrain is flat. in the inspector, when I change the new terrain to the same size as the old one (While running), the scale is perfect but with 1/4 of the land covered with what I coppied and the rest flat (when I copy 1/2 of the original)
Any reason why? did I miss something? Does the GETHEIGHTS retain the information somehow of the original terrains width/height and scale when using SETHEIGHTS?
This is due to height restrictions of the terrain object. Your best bet is to scale the sampled height before setting. For example.
Terrain A has a max height of 60.
Terrain B has a max height of 30
And your sample height is 45
So our calculation looks like this.
sampleHeight * (original$$anonymous$$axHeight / new$$anonymous$$axHeight)
hi @RobAnthem and thanks for the reply. But I dont think was I was really that clear in my issue.
$$anonymous$$y $$anonymous$$AIN terrain is 1000x1000 in size ($$anonymous$$ountains, textures, etc) and 300 for a height. Now, Via c#, I create a new terrain in any size, this case 500x500 and 300 in height. When I copy the heightmap using the code where Size=500, X=0, Y=0 :
TerrainData workData = new TerrainData();
Terrain workTerrain = Terrain.CreateTerrainGameObject(workData).GetComponent<Terrain>();
workData.heightmapResolution = sourceTerrain.terrainData.heightmapResolution;
workData.size = new Vector3(Size, sourceTerrain.terrainData.size.y, Size); // Size
float[,] sourceHeights = sourceTerrain.terrainData.GetHeights(X, Y, Size, Size);
workData.SetHeights(0, 0, sourceHeights);
The returned new Terrain is sized correctly (500x500 and 300 height) and the actual HEIGHTS are correct. whats incorrect is the width and height of the heightmap when coppied. on the 500x500 new terrain created, the heightmap is CRUSHED down to only occupy the first 250x250 of the 500x500 terrain using the code above... Yet the returned sourceHeights float[,] array from the original is 500x500 in size. So why does the array, thats 500x500 in size and the new terrain, thats also 500x500 not match up when SetHeights is called? When SetHeights is called, only 1/4 of the 500x500 new terrain is changed. Now to go one step further, If I was to take this NEW terrain I created durring runtime and change its size to that of the original terrain, the 1/4 part of the new terrain would match up with the original and not be scaled/shrunk.
Confusing, no?
Answer by Bunny83 · Feb 22, 2018 at 03:09 AM
The "size" of the terrain only affects the world space size of the terrain object. You currently set the heightmap resolution to the same value as your original terrain. You only "scale down" the terrain. If you want a "smaller" terrain in terms of samples you have to use a lower resolution.
Answer by JForrestna · Feb 23, 2018 at 08:59 PM
Thank you @Bunny83 , this is the answer I was looking for. I didn't quite understand how HeightmapResolution effected the new terrain, but after some digging into it this was the culprit. I just set the Resolution to 1/2 the originals 1025 (^2 + 1 of course = 513) and it worked fine. Now, I wonder if Its possible for Unity to keep the resolution the same on the new terrain and re-sample the heightmap in a fast and efficient way to fill the terrain...