2

I have a procedural generated Terrain, based on Unity's Terrain System.

Now i want a Map from the Terrain, not a minimap but a full map, that is saved as a 2D Texture.

First i thought of a RenderTexture, but if i take a Camera to catch the whole Terrain, the result depends on the resolution aspect, and i also have problems cause the width of the Terrain is 3.2x the length.

Is there a better way to solve this problem?

AlpakaJoe
  • 533
  • 5
  • 24
  • I would set up an orthographic camera over the terrain whose width and height matches the terrain, and you can set the resolution of the texture however you please – Ruzihm Nov 20 '19 at 22:02
  • @Ruzihm i tried that, but if the screens aspect ratio changes, the width and height don't match the terrain anymore. Is is somehow possible to set up a orthographic camera so that it got fix values that don't change with the resolution? – AlpakaJoe Nov 22 '19 at 01:05
  • yep! Part of "set up an orthographic camera over the terrain whose width and height matches the terrain" includes setting the aspect ratio of that camera. See [my answer](https://stackoverflow.com/a/59001943/1092820) for more info. – Ruzihm Nov 22 '19 at 21:43

1 Answers1

2
  1. Make a new camera and place it over the terrain.

  2. Make sure it is in orthographic mode

  3. Set the camera.aspect field to terrainData.size.x / terrainData.size.z

  4. Set the camera.orthographicSize field to terrainData.size.z/2f

  5. Make sure the camera frame is oriented with the terrain's axes. Something along the lines of cam.transform.LookAt(terrain.GetPosition(), terrain.transform.forward); will do the trick.

Then, you should be able to create a RenderTexture with the pixel resolution you'd like (based on this answer by Rafal Wiliński):

int resHeight = 1000;
int resWidth = Mathf.RoundToInt(resHeight * camera.aspect);

RenderTexture rt = new RenderTexture(resWidth, resHeight, 24);
camera.targetTexture = rt; //Create new renderTexture and assign to camera
Texture2D screenShot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false); //Create new texture

camera.Render();

RenderTexture.active = rt;
screenShot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0); //Apply pixels from camera onto Texture2D

camera.targetTexture = null;
RenderTexture.active = null; //Clean
Destroy(rt); //Free memory

then, your terrain would be captured in screenshot

Ruzihm
  • 19,749
  • 5
  • 36
  • 48
  • 1
    Thanks, that worked! Just two things, you need to set the camera.aspect to "terrainData.size.x / terrainData.size.z" and the camera.orthographicSize to "terrainData.size.z / 2f". – AlpakaJoe Nov 22 '19 at 22:44