Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Terrain Terrain Layers API. Can you tell me the starting point?

Discussion in 'World Building' started by alussam, Jan 1, 2019.

  1. alussam

    alussam

    Joined:
    May 13, 2018
    Posts:
    13
    Hello! Recently I began work on terrain script wich fills the terrain with textures. I used splatPrototypes class. But now terrain API is fully reworked. I want to be up to date and work with new features. Can you tell me from where to start? Can I find some example of using TerrainLayer instead of SplatPrototypes. Thanks for any help!
     
  2. wyatttt

    wyatttt

    Unity Technologies

    Joined:
    May 9, 2018
    Posts:
    173
    Use of SplatPrototypes is deprecated. You will want to use the TerrainLayers portion of the Terrain/TerrainData APIs. So something like:


    Code (CSharp):
    1. public void AddTerrainLayer( Terrain terrain, TerrainLayer terrainLayer )
    2. {
    3.     // get the current array of TerrainLayers
    4.     TerrainLayer[] oldLayers = terrain.terrainData.terrainLayers;
    5.  
    6.     // check to see that you are not adding a duplicate TerrainLayer
    7.     for( int i = 0; i < oldLayers.Length; ++i )
    8.     {
    9.         if( oldLayers[ i ] == terrainLayer ) return;
    10.     }
    11.  
    12.     // NOTE: probably want to track Undo step here before modifying the TerrainData
    13.  
    14.     TerrainLayer[] newLayers = new TerrainLayer[ oldLayers.Length + 1 ];
    15.  
    16.     // copy old array into new array
    17.     Array.Copy( oldLayers, 0, newLayers, 0, oldLayers.Length );
    18.  
    19.     // add new TerrainLayer to the new array
    20.     newLayers[ oldLayers.Length ] = terrainLayer;
    21.     terrain.terrainData.terrainLayers = newLayers;
    22. }
    or you can use the PaintContext API in the UnityEngine.Experimental.TerrainAPI namespace.

    Here are some examples: https://github.com/Unity-Technologies/TerrainToolSamples
     
    Rowlan and Claytonious like this.
  3. alussam

    alussam

    Joined:
    May 13, 2018
    Posts:
    13
    Thanks, but can you tell me, how can I apply layers to terrain. I used terrainData.applyAlphaMaps fragment before, but now I can't use this and dont method for layers. Thanks again
     
  4. wyatttt

    wyatttt

    Unity Technologies

    Joined:
    May 9, 2018
    Posts:
    173
    Ah you mean to actually fill the alphamap with a terrain layer. I guess I only answered part of the question. Sorry about that.

    You'd definitely want to use the PaintContext API (BeginPaintAlphamap and EndPaintAlphamap, specifically) or manually set the splat/alphamap weights using something like this:

    Code (CSharp):
    1.  
    2. public void AddTerrainLayer( Terrain terrain, TerrainLayer terrainLayer )
    3. {
    4.     // get the current array of TerrainLayers
    5.     TerrainLayer[] oldLayers = terrain.terrainData.terrainLayers;
    6.  
    7.     // check to see that you are not adding a duplicate TerrainLayer
    8.     for( int i = 0; i < oldLayers.Length; ++i )
    9.     {
    10.         if( oldLayers[ i ] == terrainLayer ) return;
    11.     }
    12.  
    13.     // NOTE: probably want to track Undo step here before modifying the TerrainData
    14.  
    15.     TerrainLayer[] newLayers = new TerrainLayer[ oldLayers.Length + 1 ];
    16.  
    17.     // copy old array into new array
    18.     Array.Copy( oldLayers, 0, newLayers, 0, oldLayers.Length );
    19.  
    20.     // add new TerrainLayer to the new array
    21.     newLayers[ oldLayers.Length ] = terrainLayer;
    22.     terrain.terrainData.terrainLayers = newLayers;
    23. }
    24.  
    25. public void FillTerrainLayer( Terrain terrain, TerrainLayer terrainLayer )
    26. {
    27.     // add the terrain layer to the terrain before filling
    28.     AddTerrainLayer( terrain, terrainLayer );
    29.  
    30.     // get the weight data for the alphamaps
    31.     int width = terrain.terrainData.alphamapWidth;
    32.     int height = terrain.terrainData.alphamapHeight;
    33.     float[ , , ] alphamaps = terrain.terrainData.GetAlphaMaps( 0, 0, width, height );
    34.  
    35.     int numAlphamaps = alphamaps.GetCount( 2 );
    36.     for( int i = 0; i < numAlphamaps; ++i )
    37.     {
    38.         // TODO: loop through the alphamaps and set weights for your filled
    39.         //       terrain layer to 1 and all other terrain layers to 0
    40.     }
    41.  
    42.     // NOTE: normally you'd have to renormalize the weights but since you
    43.     //       are filling the weights of one layer and clearing the rest, you can
    44.     //       skip that step since they will technically be normalized
    45.  
    46.     // NOTE: probably want to track Undo step here before modifying the TerrainData
    47.  
    48.     // set the new alphamap weights in the terrain data
    49.     terrainData.SetAlphamaps( 0, 0, alphamaps );
    50. }
    Does this better answer your question?
     
    Last edited: Jan 4, 2019
    Rowlan likes this.
  5. wyatttt

    wyatttt

    Unity Technologies

    Joined:
    May 9, 2018
    Posts:
    173
    Using a PaintContext can be faster as that is done on the GPU
     
    Last edited: Jan 4, 2019
    alussam likes this.
  6. alussam

    alussam

    Joined:
    May 13, 2018
    Posts:
    13
    Oh, yes, thats right. I tried this before and in most cases got black terrain. Now i tried to fill with one layer and it works. Seems,that I'm doing something wrong. Thanks a lot for help!
     
  7. ghtx1138

    ghtx1138

    Joined:
    Dec 11, 2017
    Posts:
    113
    Hi @wyatttt

    I used your script to create a new layer but it does not appear correct (probably my script). You can see that it is blue and that is does not appear under the Terrain Layers box when selected -like the other one I made manually.

    Can you please tell me how to add a new layer with a texture? Also where is the layer in the Assets folder? I cannot see it yet (probably because I do not have the New Layer working correctly?)

    Thanks


    CreateTerrainLayerTexture.png

    CreateTerrainLayerTexture.png
     
    jdoxbotica, LMckee and zwcloud like this.
  8. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,062
    So first pass on converting out splat tools. Setting the alpha maps it looks like the third dimension is in opposite order as the old api? So dimension 0 actually references the 4th layer? Or maybe some other difference in the api is turning it around somehow.
     
  9. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,062
    Ok nevermind on that, it was CTS out of sync with the terrain.
     
  10. jdoxbotica

    jdoxbotica

    Joined:
    Aug 6, 2018
    Posts:
    7
    I have the same problem as @ghtx1138.

    If I set the texture layer in the inspector I have no problem but trying to set in code gives the blue box. Does anyone know how to fix this?
     
  11. jdoxbotica

    jdoxbotica

    Joined:
    Aug 6, 2018
    Posts:
    7
    ah it was simply because I was setting the terrainLayers per an array entry rather than setting the entire array in one go.