- Home /
[Help Needed] Trying to flatten terrain in terrain centre via script.
I am trying to modify my terrain height values in order to create a nice flat area in the middle of terrain , with the other hill/mountain like values still intact around the area. So far all is well , apart from I have reached a point where I get an error:
ArgumentException: Trying to access out of bounds height information.
I have checked this , and based my solution around its structure but with no full avail so far!
My first code file (ScriptCreateBuildZone) is where the error occurs (On line 60) and then stops , I just cannot understand where it is trying to access as the I believe that the terrain values(See in DebugLog screenshot at the bottom) are okay. Then again I might be horribly wrong. Here is the script:
using UnityEngine;
using System.Collections;
public class ScriptCreateBuildZone : MonoBehaviour {
Terrain terrMain;
int hmWidth;
int hmHeight;
int terrPosX;
int terrPosY;
int buildZoneSize = 50;
int finalHeight;
// Use this for initialization
void Start () {
//terrMain = GameObject.Find("Terrain(Clone)") as Terrain;
Destroy(GameObject.Find("Terrain(Clone)"));
terrMain = Terrain.activeTerrain;
hmWidth = terrMain.terrainData.heightmapWidth;
hmHeight = terrMain.terrainData.heightmapHeight;
Debug.Log ("HeightMap Width and Height:" + hmWidth + "," + hmHeight);
}
// Update is called once per frame
void Update ()
{
Func();
}
void Func()
{
Vector3 tempCoord = (transform.position - terrMain.gameObject.transform.position);
Debug.Log ("Temp coords are:" + tempCoord.x + "," + tempCoord.y + "," + tempCoord.z);
Vector3 coord;
coord.x = tempCoord.x / terrMain.terrainData.size.x;
coord.y = tempCoord.y / terrMain.terrainData.size.y;
coord.z = tempCoord.z / terrMain.terrainData.size.z;
Debug.Log ("Terrain data XYZ Positions are:" + terrMain.terrainData.size.x + "," + terrMain.terrainData.size.y + "," + terrMain.terrainData.size.z);
Debug.Log ("coords are:" + coord.x + "," + coord.y + "," + coord.z);
terrPosX = (int) (coord.x * hmWidth);
terrPosY = (int) (coord.z * hmHeight);
//terrPosX = (int)tempCoord.x ;
//terrPosY = (int)tempCoord.z ;
Debug.Log ("TerrainPos's are:" + terrPosX + "," + terrPosY);
int offset = buildZoneSize / 2;
print ("Getting hieghts for hieghtmap...");
float[,] heights = terrMain.terrainData.GetHeights(terrPosX-offset,terrPosY-offset,buildZoneSize,buildZoneSize); //<- ERROR OCCURS HERE!
print ("getHeights Successful.");
Debug.Log (heights);
for (int i = 0; i < buildZoneSize; i++)
{
for (int j = 0; j < buildZoneSize; j++)
{
heights [i, j] = finalHeight;
Debug.Log (finalHeight);
}
}
// go raising the terrain slowly
finalHeight += finalHeight; //Time.deltaTime;
terrMain.terrainData.SetHeights(terrPosX-offset,terrPosX-offset,heights);
Destroy (this.gameObject);
}
}
The second script that may also be of importance is the one where my terrain is instantiated with its values(ClassTerrain). NOTE: I am using the TerrainToolkit asset pack which is why i have those values in the if statements , works great! Second script:
public class ClassTerrain : MonoBehaviour {
//Objects of the terrain
GameObject terrObj ;
public GameObject terrBuildZone; //= GameObject.CreatePrimitive(PrimitiveType.Cylinder);
//Variables for future manipulation
TerrainData terrData;
Terrain terrMain;
int hmWidth;
int hmHeight;
int terrPosX;
int terrPosY;
int buildZoneSize = 50;
int finalHeight;
//public Terrain terrain;
//Data for the terrain
//Numeric Variables
public int terrainX = 10000;
public int terrainZ = 10000;
int heightMapWidth;
int heightMapHeight;
//SET UP CLIMATE DETAILS HERE
enum ClimateType
{
tropicaldry,
mediteranean,
subtropical,
marinewestcoast,
arid,
highland
};
ClimateType ct;
void Start ()
{
Init();
ConstructMap ();
}
void Update ()
{
}
void Init()
{
short climateChoice = 1;
//terrObj.layer = 8;
TerrainData temp_terrData = new TerrainData();
temp_terrData.size = new Vector3 (terrainX, 1000, terrainZ);
terrObj = Terrain.CreateTerrainGameObject(temp_terrData);
Vector3 position = new Vector3 (0, 0, 0); //the ingame position you want your terrain at
terrObj = Instantiate(terrObj, position, Quaternion.identity) as GameObject;
//DO CASE STATEMENT
switch (climateChoice)
{
case 1:
ct = ClimateType.tropicaldry;
break;
case 2:
ct = ClimateType.mediteranean;
break;
case 3:
ct = ClimateType.subtropical;
break;
case 4:
ct = ClimateType.marinewestcoast;
break;
case 5:
ct = ClimateType.arid;
break;
case 6:
ct = ClimateType.highland;
break;
}
terrMain = Terrain.activeTerrain;
hmWidth = terrMain.terrainData.heightmapWidth;
hmHeight = terrMain.terrainData.heightmapHeight;
}
void ConstructMap()
{
TerrainToolkit tt = terrObj.AddComponent <TerrainToolkit>() as TerrainToolkit;
terrObj = GameObject.Find("Terrain(Clone)");
terrObj.gameObject.GetComponent<TerrainToolkit> ().PerlinGenerator (3, 0.5f, 9, 1.0f);
if (ct == ClimateType.tropicaldry)
{
tt.PerlinGenerator(3, 0.5f, 9, 1.0f);
Instantiate (terrBuildZone);
}
else if (ct == ClimateType.mediteranean)
{
tt.PerlinGenerator(2, 1.0f, 8, 1.0f);
//pos 5285,310,4755
//scale 7500,10,7500
}
else if (ct == ClimateType.subtropical)
{
tt.PerlinGenerator(2, 1.0f, 5, 1.0f);
//pos 4865,180,5030
//scale 7500,100,7500
}
else if (ct == ClimateType.marinewestcoast)
{
tt.PerlinGenerator(3, 0.5f, 3, 1.0f);
//pos 5025 , 100 , 5500
//scale 7500 , 1 , 7500
}
else if (ct == ClimateType.arid)
{
tt.PerlinGenerator(8, 0.07f, 9, 1.0f);
//pos 4750, 50 , 5210
//scale 7500, 10 , 7500
}
else if (ct == ClimateType.highland)
{
tt.PerlinGenerator(5, 1.0f, 7, 1.0f);
//pos 4800 , 400 ,4800
//scale 7500 , 100 , 7500
}
}
}
My terrain values may be the issue , but again Im not sure. Here is the debug log for assistance: 
If any other info is needed , please ask! Thanks
Your answer