Texture Rectangle Out of Bounds (Splatmap)

Hey guys,

I’m trying to alter the texture of the terrain during runtime and having trouble figuring out the terrain system and api.

I have this code currently which is supposed to convert a world position (Vector3) point to the corresponding size/position of the “alphamap/splatmap”. I’m getting this error from the script:
Texture rectangle is out of bounds (115 + 512 > 512)
UnityEngine.TerrainData:GetAlphamaps(Int32, Int32, Int32, Int32).

The error is generated by the “myTerrain.GetAlphamaps(mapX, mapZ, myTerrain.alphamapWidth, myTerrain.alphamapHeight)” function on line 28 in the script.

And here is the script:

using UnityEngine;
using System.Collections;

public class TerrainTextureModifier : MonoBehaviour {

    private TerrainData myTerrain;

    // Use this for initialization
    void Start () {
        myTerrain = Terrain.activeTerrain.terrainData;
    }
  
    // Update is called once per frame
    void Update () {

        if (Input.GetKeyUp(KeyCode.P))
        {
            //The splatmap positions converted FROM the terrain world position(s)
            //var mapX = ((player.x - terrainPos.x) / terrainData.size.x) * terrainData.alphamapWidth;
            //var mapZ = ((player.z - terrainPos.z) / terrainData.size.z) * terrainData.alphamapHeight;

            int mapX = Mathf.RoundToInt(((1540 - 0) / (myTerrain.size.x)) * (myTerrain.alphamapWidth));
            int mapZ = Mathf.RoundToInt(((673 - 0) / (myTerrain.size.z)) * (myTerrain.alphamapHeight));

            Debug.Log("mapX is : " + mapX);
            Debug.Log("mapY is : " + mapZ);

            float[, ,] maps = myTerrain.GetAlphamaps(mapX, mapZ, myTerrain.alphamapWidth, myTerrain.alphamapHeight);

            Debug.Log("AlphaMap Height is: " + myTerrain.alphamapHeight);
            Debug.Log("AlphaMap Width is: " + myTerrain.alphamapWidth);


            /*for (int i = 0; i < myTerrain.splatPrototypes.Length; i++)
            {
                maps[0, 0, i] > .5f)
            }*/

            maps[0, 0, 0] = 0;
            maps[0, 0, 1] = 1;
            maps[0, 0, 2] = 0;
            maps[0, 0, 3] = 0;

            myTerrain.SetAlphamaps(mapX, mapZ, maps);
        }

    }
}

Any idea why “115” would be out of bounds on a 512 size map? Also, is my math wrong in converting the terrain world position to the alphamap position?

Nevermind I got it to work. Don’t you love it when you post something on the forums and then solve it quickly afterwards :slight_smile:

I changed

float[, ,] maps = myTerrain.GetAlphamaps(mapX, mapZ, myTerrain.alphamapWidth, myTerrain.alphamapHeight);

to

float[, ,] maps = myTerrain.GetAlphamaps(mapX, mapZ,  1,  1);

And it now works.

Now my problem is that the alphamap changes persist through game sessions (i.e. its permanently saved in the terrain data) even though it was altered during runtime only. Is there a way to save the alphamap before it’s altered, then reapply it at the end or beginning of the next game session?

You could try saving changes to a scriptable object, or running “repair code” OnApplicationQuit()