Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Applying splatmaps - help

Discussion in 'Scripting' started by Garrett-Lynch, Mar 21, 2013.

  1. Garrett-Lynch

    Garrett-Lynch

    Joined:
    Mar 13, 2013
    Posts:
    14
    I have been trying to apply a texture to a terrain from C for over a week now. New to Unity3D however applying a texture to a primitive took me 30 seconds to figure out what am I not doing correctly here?

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using Utility;
    4.  
    5. public class test : MonoBehaviour
    6. {
    7.     //use this for initialization
    8.     void Start ()
    9.     {
    10.         //create a new terrain data
    11.         TerrainData _terrainData = new TerrainData();
    12.  
    13.         //set terrain width, height, length
    14.         _terrainData.size = new Vector3(20, 1, 20);
    15.  
    16. SplatPrototype[] terrainTexture = new SplatPrototype[1];
    17. terrainTexture[0] = new SplatPrototype();
    18. terrainTexture[0].texture = (Texture2D)Resources.Load("Terrain Assets/Terrain Textures/Grass (Hill)");
    19. _terrainData.splatPrototypes = terrainTexture;
    20.  
    21.         //Create a terrain with the set terrain data
    22.         GameObject _terrain = Terrain.CreateTerrainGameObject(_terrainData);
    23.     }
    24.    
    25.     // Update is called once per frame
    26.     void Update () {
    27.  
    28.     }
    29. }
    30.  
    I create the splatmap, load the texture, how is it then applied?

    I understand that I will need to ultimately have more than one texture and itterate through the heightmap (something like below) to apply the textures but a little clue as to just how to see a single texture on my terrain is what I need right now. How is this done?

    Code (csharp):
    1. float[,,] map = new float[_terrainData.alphamapWidth, _terrainData.alphamapHeight, 2];
    2.  
    3.  
    4.         // For each point on the alphamap...
    5.         for (var y = 0; y < _terrainData.alphamapHeight; y++) {
    6.            
    7.            
    8.             //print("Y = " + y.ToString());
    9.            
    10.            
    11.             for (var x = 0; x < _terrainData.alphamapWidth; x++) {
    12.                 // Get the normalized terrain coordinate that
    13.                 // corresponds to the the point.
    14.                 var normX = x * 1.0 / (_terrainData.alphamapWidth - 1);
    15.                 var normY = y * 1.0 / (_terrainData.alphamapHeight - 1);
    16.                
    17.                
    18.                 //print("X = " + normX.ToString());
    19.                
    20.                 // Get the steepness value at the normalized coordinate.
    21.                 var angle = _terrainData.GetSteepness(normX, normY);
    22.                
    23.                 // Steepness is given as an angle, 0..90 degrees. Divide
    24.                 // by 90 to get an alpha blending value in the range 0..1.
    25.                 //var frac = angle / 90.0;
    26.                 //map[x, y, 0] = frac;
    27.                 //map[x, y, 1] = 1 - frac;
    28.             }
    29.         }
    30.  
    31. _terrainData.SetAlphamaps(0, 0, map);
     
  2. scrawk

    scrawk

    Joined:
    Nov 22, 2012
    Posts:
    804
    You are only using 1 splatmap so the third array size of map needs to be 1
    There value used should be 1 as well because you want your grass texture to show every were.

    Try this, havnt tested it so sorry if it doesnt work.

    Code (csharp):
    1.  
    2.  
    3. float[,,] map = new float[_terrainData.alphamapWidth, _terrainData.alphamapHeight, 1]; // needs to be 1
    4.      
    5.      
    6.             // For each point on the alphamap...
    7.             for (var y = 0; y < _terrainData.alphamapHeight; y++) {
    8.  
    9.                 for (var x = 0; x < _terrainData.alphamapWidth; x++) {
    10.    
    11.                     map[x, y, 0] = 1.0; //needs to be 1 as well
    12.                 }
    13.             }
    14.      
    15.     _terrainData.SetAlphamaps(0, 0, map);
    16.  
    17.  
     
  3. Garrett-Lynch

    Garrett-Lynch

    Joined:
    Mar 13, 2013
    Posts:
    14
    I have tried your suggest and still I see nothing.

    Isn't there a way to just apply the loaded texture without iterating through the alphamap width and height?
    Perhaps my texture load is incorrect - how do I test that the texture is indeed loading?
    What should the map alphamap array look like - can somebody just post an array to show me how it's structured?

    Can't believe how poor the documentation is on this.


    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using Utility;
    4.  
    5. public class test : MonoBehaviour
    6. {
    7.     //use this for initialization
    8.     void Start ()
    9.     {
    10.         //create a new terrain data
    11.         TerrainData _terrainData = new TerrainData();
    12.  
    13.         //set terrain width, height, length
    14.         _terrainData.size = new Vector3(20, 1, 20);
    15.  
    16.  
    17.         SplatPrototype[] terrainTexture = new SplatPrototype[1];
    18.         terrainTexture[0] = new SplatPrototype();
    19.         terrainTexture[0].texture = (Texture2D)Resources.Load("Terrain Assets/Terrain Textures/Grass (Hill)");
    20.         _terrainData.splatPrototypes = terrainTexture;
    21.  
    22.  
    23.  
    24. //PLEASE IGNORE THIS - AT THE MOMENT THIS IS JUST ADDING COMPLEXITY I DO NOT NEED
    25. //HOW DO I APPLY THE TEXTURE LOADED ABOVE EVERYWHERE?
    26. float[,,] map = new float[_terrainData.alphamapWidth, _terrainData.alphamapHeight, 1]; // needs to be 1
    27.  
    28. // For each point on the alphamap...
    29. for (var y = 0; y < _terrainData.alphamapHeight; y++)
    30. {
    31.     for (var x = 0; x < _terrainData.alphamapWidth; x++)
    32.     {
    33.  
    34.         map[x, y, 0] = (float)1.0; //needs to be 1 as well
    35.     }
    36. }
    37.  
    38. _terrainData.SetAlphamaps(0, 0, map);
    39. //PLEASE IGNORE THIS - AT THE MOMENT THIS IS JUST ADDING COMPLEXITY I DO NOT NEED
    40. //HOW DO I APPLY THE TEXTURE LOADED ABOVE EVERYWHERE?
    41.  
    42.  
    43.  
    44.         //Create a terrain with the set terrain data
    45.         GameObject _terrain = Terrain.CreateTerrainGameObject(_terrainData);
    46.  
    47.     }
    48.    
    49.     // Update is called once per frame
    50.     void Update () {
    51.  
    52.     }
    53.    
    54. }
    55.  
     
  4. coward

    coward

    Joined:
    Jan 9, 2013
    Posts:
    21
    I know this was some time ago, but Resources.Load requires that your texture be in a 'Resources' directory (it can have any path up until the 'Resources' directory). And it looks like you are trying to load it from a different path.