0

i want to change the texture of my terrain with certain texture. i got confuse to set the splatmapdata, anyone can help me out??

private void ChangeTexture(Vector3 WorldPos)
{
    print ("changeTexture");

    int mapX = (int)(((WorldPos.x - terrainPos.x) / terrainData.size.x) * terrainData.alphamapWidth);
    int mapZ = (int)(((WorldPos.z - terrainPos.z) / terrainData.size.z) * terrainData.alphamapHeight);


    float[,,] splatmapData = terrainData.GetAlphamaps(3, 3, 15, 15);
    terrainData.SetAlphamaps (mapX, mapZ, splatmapData);
    terrain.Flush ();
}
derHugo
  • 83,094
  • 9
  • 75
  • 115
irwnsyh
  • 23
  • 7

1 Answers1

2

The data returned by GetAlphamaps

The returned array is three-dimensional - the first two dimensions represent x and y coordinates on the map, while the third denotes the splatmap texture to which the alphamap is applied.

Or in simple words a float[x, y, l] where

  • x = width in pixels
  • y = height in pixels
  • l = Texture-Layer

So lets say you want to set it to a certain texture at this pixel coordinates what you do is

  • set the weight for the texture's layer to 1
  • set all other layers weight to 0

So let's say you have e.g. 3 Layers and you want the second one (= index 1) to be the full weighted texture:

float[,,] splatmapData = terrainData.GetAlphamaps(mapX, mapZ, 15, 15);

// Iterate over x-y coordinates within the array
for(var y = 0; i < 15; y++)
{
    for(var x = 0; x < 15; x++)
    {
        // Set first layers weight to 0
        splatmapData[x, y, 0] = 0;

        // Set second layer's weight to 1
        splatmapData[x, y, 1] = 1;

        // Set third layer's weight to 0
        splatmapData[x, y, 2] = 0;
    }
}

terrainData.SetAlphamaps(mapX, mapZ, splatmapData);

I would then implement an enum for the layers like let's say

public enum TerrainLayer
{
    Default = 0,
 
    Green,
    Red
}

so you can simply pass the according layer index as a parameter - a bit more secure than passing in the int values themselves:

private void ChangeTexture(Vector3 worldPos, TerrainLayer toLayer)
{
    print ("changeTexture");

    int mapX = (int)(((worldPos.x - terrainPos.x) / terrainData.size.x) * terrainData.alphamapWidth);
    int mapZ = (int)(((worldPos.z - terrainPos.z) / terrainData.size.z) * terrainData.alphamapHeight);

    float[,,] splatmapData = terrainData.GetAlphamaps(mapX, mapZ, 15, 15);

    for(var z = 0; z < 15; z++)
    {
        for(var x = 0; x < 15; x++)
        {
            // This ofcourse would be more efficient if you do this only once
            // e.g. in Awake since the enum won't change on runtime
            var values = (TerrainLAyer[])Enum.GetValues(typeof(TerrainLayer));

            // Iterate through the enum and 
            for(var l = 0; l < values.Length; l++)
            {
                // set all layers to 0 except the toLayer
                splatmapData[x, z, l] = values[l] == toLayer ? 1 : 0;
            }
        }
    }

    terrainData.SetAlphamaps (mapX, mapZ, splatmapData);
    terrain.Flush ();
}

Now you would simply call it e.g.

ChangeTexture(somePosition, TerrainLayer.Green);
derHugo
  • 83,094
  • 9
  • 75
  • 115