The GetHeights and GetAlphamaps methods each time allocate memory to create a float array and then return it. Even in the Unity Manual, the Understanding Automatic Memory Management page that this is bad memory practice:
Why not make a version of the method that takes a float array and fills it with values, without initializing a new array? By analogy with the existing methods:
Physics.RaycastNonAlloc instead of Physics.RaycastAll
Physics.OverlapSphereNonAlloc instead of Physics.OverlapSphere
It might look like this:
public void TerrainData.GetHeightsNonAlloc (int xBase, int yBase, int width, int height, float [,] heights);
public void TerrainData.GetAlphamapsNonAlloc (int x, int y, int width, int height, float [,] alphamaps);
instead:
public float [,] TerrainData.GetHeights (int xBase, int yBase, int width, int height);
public float [,] TerrainData.GetAlphamaps (int x, int y, int width, int height);
Usage might look like:
float [,] heights = new float [sizeHeightmap, sizeHeightmap];
terrain.terrainData.GetHeightsNonAlloc (0, 0, sizeHeightmap, sizeHeightmap, heights)
float [,,] alphamaps = new float [sizeAlphamap, sizeAlphamap, 32];
terrain.terrainData.GetAlphamapsNonAlloc (0, 0, sizeAlphamap, sizeAlphamap, alphamaps)
Problem context:
In my game, the player can edit the terrain in real time and then save it. The large world of the game consists of 64 terrain tiles with a resolution of each 1025x1025. To serialize the heights of all terrains to bytes and save them to files, I make a call to the terrainData.GetHeights method, which results in huge GC Alloc allocations of about 250 mb for heightmaps. But I also have to save alphamaps, which theoretically requires about 8000 mb (250 mb * 32 material slots). But I didn’t even dare to check GetAlphamaps
It is clear that I will save only those tiles that were changed by the player in the current game session, but some players may have such a long game session in which they have time to change all or almost all of the 64 terrains. This is absolutely not useful, especially with GetAlphamaps.
I tried to read heights one at a time using GetHeight, but saving 64 million heights from 2.5 seconds increased several times, which I would like to avoid. Alphamaps cannot read values without GC Alloc in any way.
