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

Any ideas of how to make field for strategy game?

Discussion in 'General Graphics' started by TripleDouble, Apr 19, 2015.

  1. TripleDouble

    TripleDouble

    Joined:
    Mar 18, 2014
    Posts:
    11
    Hello,
    I'm trying to figure out, what is the best way, to create things like paths and fields on a terrain ingame. Something like creating fields in Age of empires 3, wheres the texture was right on the ground. I think creating a plane right above the ground isn't best solution (Because of humps etc.). I googled all day but all I found is that SetAlphamaps, but found only tuts for texturing all terrain, not only one specific section only for field or road.

    Here is what i want.
     

    Attached Files:

  2. ensiferum888

    ensiferum888

    Joined:
    May 11, 2013
    Posts:
    317
    It's the same thing really, SetAlphamaps takes a position X and Z and a float[,,] that containts the weights of the textures.

    So you'll need to convert your worldPosition to terrain position and then set the weights, then call SetAlphamaps with those position index. For example this is how I do fields for my game, it already has a BoxCollider with the proper size for the field:

    Code (CSharp):
    1. public static void PaintDirtTexture(GameObject go)
    2.     {
    3.         Terrain mainTerrain = Terrain.activeTerrain;
    4.         TerrainData terrainData = mainTerrain.terrainData;
    5.        
    6.         BoxCollider boxCol = go.GetComponent<BoxCollider>();
    7.        
    8.         Vector3 worldPos1 = new Vector3(boxCol.bounds.min.x, go.transform.position.y, boxCol.bounds.min.z);
    9.         Vector3 worldPos2 = new Vector3(boxCol.bounds.max.x, go.transform.position.y, boxCol.bounds.max.z);
    10.        
    11.         Vector3 pos1 = getTerrainRelativeAlphaPosition(worldPos1);
    12.         Vector3 pos2 = getTerrainRelativeAlphaPosition(worldPos2);
    13.        
    14.         int x1 = (int)pos1.x;
    15.         int y1 = (int)pos1.y;
    16.         int x2 = (int)pos2.x;
    17.         int y2 = (int)pos2.y;
    18.        
    19.         int originX = Mathf.Min(x1, x2);
    20.         int originY = Mathf.Min (y1, y2);
    21.        
    22.         int width = Mathf.Abs(x2 - x1);
    23.         int height = Mathf.Abs(y2 - y1);
    24.                
    25.         float[, ,] alphas = terrainData.GetAlphamaps(originX, originY, width, height);
    26.        
    27.         for(int i = 0 ; i < height ; i++)
    28.         {
    29.             for(int j = 0 ; j < width ; j++)
    30.             {
    31.                 alphas[i, j, 1] = 0.8f;
    32.                 alphas[i, j, 0] = 0.2f;
    33.                 alphas[i, j, 2] = 0.0f;
    34.                 alphas[i, j, 3] = 0.0f;
    35.             }
    36.         }
    37.         terrainData.SetAlphamaps(originX, originY, alphas);
    38.     }
    39.  
    40.     //Get terrain position from world position (returns X: int Y: int)
    41.     public static Vector3 getTerrainRelativeAlphaPosition(Vector3 position)
    42.     {
    43.         Terrain terrain = Terrain.activeTerrain;
    44.         Vector3 tempCoord = position - terrain.gameObject.transform.position;
    45.         Vector3 coord;
    46.        
    47.         coord.x = tempCoord.x / terrain.terrainData.size.x;
    48.         coord.y = tempCoord.y / terrain.terrainData.size.y;
    49.         coord.z = tempCoord.z / terrain.terrainData.size.z;
    50.        
    51.         int hmWidth = terrain.terrainData.alphamapWidth;
    52.         int hmHeight = terrain.terrainData.alphamapHeight;
    53.        
    54.         float posXinTerrain = coord.x * hmWidth;
    55.         float posZinTerrain = coord.z * hmHeight;
    56.                
    57.         return new Vector3(posXinTerrain, posZinTerrain);
    58.     }
    59.  
    This will only paint the area contained within the box. You need to make sure your collider is exacly the same ratio as your alphamaps resolution on your terrain or else you could end up with bleeding.
     
    TripleDouble and theANMATOR2b like this.
  3. TripleDouble

    TripleDouble

    Joined:
    Mar 18, 2014
    Posts:
    11
    It works perfectly just like I wanted. Thank you!