Search Unity

How to programmatically set TerrainLayer

Discussion in 'World Building' started by yahwho, Apr 22, 2020.

  1. yahwho

    yahwho

    Joined:
    Apr 22, 2020
    Posts:
    1
    Hi all,

    I'm relatively new to Unity (about 3 weeks!) I've been following a course on procedural terrain generation (for Unity 2018).

    Since updating from 2018 Unity to 2019 Unity I've learned that the old method (which I had just learned!) for applying splat maps to terrain no longer works. After a bit of digging around I found that splat maps are now replaced with TerrainLayer.

    Can anyone point me in the direction to work with the new TerrainLayers programmatically?

    I've managed to bodge my course code to kind of work, but I know I'm not doing it correctly.

    Code (CSharp):
    1.    
    2.  
    3. public void SplatMaps()
    4.     {
    5.         Debug.Log("New Splatmaps function!");
    6.  
    7.         TerrainLayer[] terrainLayer;
    8.         terrainLayer = new TerrainLayer[splatHeights.Count];
    9.         int terrainIndex = 0;
    10.         foreach (SplatHeights sh in splatHeights)
    11.         {
    12.             terrainLayer[terrainIndex] = new TerrainLayer();
    13.             terrainLayer[terrainIndex].diffuseTexture = sh.texture;
    14.             terrainLayer[terrainIndex].tileOffset = sh.tileOffset;
    15.             terrainLayer[terrainIndex].tileSize = sh.tileSize;
    16.             terrainLayer[terrainIndex].diffuseTexture.Apply(true);
    17.             string path = "Assets/" + this.gameObject.name + " TerrainLayer " + terrainIndex + ".terrainlayer";
    18.             AssetDatabase.CreateAsset(terrainLayer[terrainIndex], path);
    19.             terrainIndex++;
    20.             Selection.activeObject = this.gameObject;
    21.         }
    22.         // apply textures back into the terrain data
    23.         terrainData.terrainLayers = terrainLayer;
    24.  
    25.         float[,] heightMap = terrainData.GetHeights(0, 0,
    26.                                                     terrainData.heightmapResolution,
    27.                                                     terrainData.heightmapResolution);
    28.  
    29.         float[,,] splatmapData = new float[terrainData.alphamapWidth,
    30.                                                terrainData.alphamapHeight,
    31.                                                terrainData.alphamapLayers];
    32.  
    33.  
    34.         for (int y = 0; y < terrainData.alphamapHeight; y++)
    35.         {
    36.             for (int x = 0; x < terrainData.alphamapWidth; x++)
    37.             {
    38.                
    39.                 float[] splat = new float[terrainData.alphamapLayers];
    40.  
    41.                 for (int i = 0; i < splatHeights.Count; i++)
    42.                 {
    43.                     float noise = Mathf.PerlinNoise(x * splatHeights[i].splatNoiseXScale,
    44.                                                     y * splatHeights[i].splatNoiseYScale)
    45.                                        * splatHeights[i].splatNoiseScaler;
    46.                     float offset = splatHeights[i].splatOffset + noise;
    47.                     float thisHeightStart = splatHeights[i].minHeight - offset;
    48.                     float thisHeightStop = splatHeights[i].maxHeight + offset;
    49.    
    50.                     float steepness = terrainData.GetSteepness(y / (float)terrainData.alphamapHeight,
    51.                                            x / (float)terrainData.alphamapWidth);
    52.  
    53.                     if ((heightMap[x, y] >= thisHeightStart && heightMap[x, y] <= thisHeightStop) &&
    54.                         (steepness >= splatHeights[i].minSlope && steepness <= splatHeights[i].maxSlope))
    55.                     {
    56.                         splat[i] = 1;
    57.                     }
    58.                 }
    59.                // NormalizeVector(splat);
    60.                 for (int j = 0; j < splatHeights.Count; j++)
    61.                 {
    62.                     splatmapData[x, y, j] = splat[j];
    63.                 }
    64.             }
    65.         }
    66.  
    67.         terrainData.SetAlphamaps(0, 0, splatmapData);
    68.  
    69.     }
    70.  
    71.  
     
  2. TOES

    TOES

    Joined:
    Jun 23, 2017
    Posts:
    134
    Try AssetDatabase.SaveAssets(); after you modify the terrainLayers