Search Unity

Procedural Terrain Height map can't be applied to Terrain data

Discussion in 'World Building' started by Tigger_Fan_, Nov 15, 2019.

  1. Tigger_Fan_

    Tigger_Fan_

    Joined:
    Jun 25, 2019
    Posts:
    3
    I've been trying to create procedural terrain for a game. I keep getting the error: "ArgumentException: X or Y base out of bounds. Setting up to 4096x4096 while map size is 33x33" when setting my generated height map to the terraindata. Anyone know a fix for this?

    Code (CSharp):
    1.     void GenerateTerrainData()
    2.     {
    3.         terrain.terrainData.heightmapResolution = resolution;
    4.         terrain.terrainData.baseMapResolution = resolution;
    5.  
    6.         terrain.terrainData.size = new Vector3(length, height, width);
    7.         terrain.terrainData.SetHeights(0, 0, GenerateHeights());
    8.     }
    9.  
    10.     float[,] GenerateHeights()
    11.     {
    12.         float[,] heights = new float[length * resolution, width * resolution];
    13.         Debug.Log("heights[" + heights.GetLength(0) + "," + heights.GetLength(1) + "]");
    14.  
    15.         for (int x = 0; x < length; x++)
    16.         {
    17.             for (int y = 0; y < width; y++)
    18.             {
    19.                 switch (heightType)
    20.                 {
    21.                     default:
    22.                     case HeightType.perlin:
    23.                         heights[x, y] = GeneratePerlinHeight(x);
    24.                         break;
    25.  
    26.                     case HeightType.multiFreqPerlin:
    27.                         heights[x, y] = GenerateMultiFreqPerlinHeight(x, y);
    28.                         break;
    29.  
    30.                     case HeightType.multiFreqNoise:
    31.                         heights[x, y] = GenerateMulitFreqNoiseHeight(x);
    32.                         break;
    33.                 }
    34.              
    35.             }
    36.         }
    37.  
    38.         return heights;
    39.     }
     
  2. crysicle

    crysicle

    Joined:
    Oct 24, 2018
    Posts:
    95
    You're trying to apply a bigger heightmap than the current heightmap resolution of the terrain. The fault is in the 12th line.

    float[,] heights = new float[length * resolution, width * resolution];

    Lets say length = 10 and width = 10 and the terrain resolution is 33x33. In that case you'd be applying a 330x330 resolution heightmap onto a 33x33 terrain's heightmap via SetHeights(0, 0, GenerateHeights()), hence the error being out of bounds.

    Also Unity only supports 2^n + 1 heightmap resolutions going from 33x33 to 4097x4097. In the line 3rd line:

    terrain.terrainData.heightmapResolution = resolution;

    make sure that the resolution follows the previous formula
     
  3. Tigger_Fan_

    Tigger_Fan_

    Joined:
    Jun 25, 2019
    Posts:
    3
    So if I understand you, the heightmap resolution has to be the same as the length and the width? Is there any way to make terrain in the shape of a rectangle, not a square?
     
  4. crysicle

    crysicle

    Joined:
    Oct 24, 2018
    Posts:
    95
    You can make the terrain into a rectangle via changing the terrain size, however, the resolution of the heightmap will always be the same for Z and X axis. If you're looking to stretch the heightmap data and not just the size of the terrain, you could probably do so by changing your GenerateMultiFreqPerlinHeight(x, y) inputs into something like GenerateMultiFreqPerlinHeight(x * multiplier, y) which should stretch the X axis heightmap data more if multiplier > 1 and shrink if multiplier < 1.
     
  5. Tigger_Fan_

    Tigger_Fan_

    Joined:
    Jun 25, 2019
    Posts:
    3
    I was only looking to change the terrain base shape, so editing the terrain data size worked. Thanks for the help!
     
    Last edited: Nov 17, 2019