- Home /
Procedural terrain
I have been working on an procedural terrain, which eventually is going to be infinite. I have run into a couple of problems. Some of which I can't figure out how to fix. The main issue right now is this: https://www.dropbox.com/s/utctinn94h8onk4/Untitled.png This is the current code:
function GenerateTile(nw : int, nh : int) {
if (GameObject.Find("Chunk "+nw+","+nh)) {
return;
}
var td = new TerrainData();
td.heightmapResolution = 513;
td.size = new Vector3(500,200,500);
var ChunkPosX : float = td.size.x * nw;
var ChunkPosY : float = td.size.z * nh;
var t = Terrain.CreateTerrainGameObject(td);
var hw : float = Terrain.activeTerrain.terrainData.heightmapWidth;
var hh : float = Terrain.activeTerrain.terrainData.heightmapHeight;
var heights = new float[hw, hh];
for (var x = 0; x < hw; x++) {
for (var y = 0; y < hh; y++) {
// World Pos Divided by heightmap height
var xCoord = ((ChunkPosX + x) / (Mathf.PI * scale));
var yCoord = ((ChunkPosY + y) / (Mathf.PI * scale));
heights[x,y] += Mathf.PerlinNoise(xCoord, yCoord);
}
}
Terrain.activeTerrain.terrainData.SetHeights(0,0,heights);
t.transform.position = new Vector3(ChunkPosX, 0,ChunkPosY);
t.name = "Chunk "+nw+","+nh;
}
The terrains fit diagonally but not vertically, so It can't be used for tiling as the tiles doesn't create a smooth terrain.
Answer by Scribe · Aug 09, 2014 at 11:10 PM
your main problem seems to be that you use the terrain size to find the perlin start point however you should be using a multiple of your heightmap resolution, also I'm not quite certain why (I haven't done much work with terrain heightmaps) but for some reason I had to swap the position they were mapped to in the float list:
function GenerateTile(nx : int, nz : int) {
if (GameObject.Find("Chunk "+nx+","+nz)) {
return;
}
var td = new TerrainData();
td.heightmapResolution = 513;
td.size = new Vector3(500,200,500);
var t = Terrain.CreateTerrainGameObject(td);
var hw : float = Terrain.activeTerrain.terrainData.heightmapWidth;
var ChunkPosX : float = td.size.x * nx;
var ChunkPosZ : float = td.size.z * nz;
var startPosX : int = hw*(nx-1);
var startPosZ : int = hw*(nz-1);
var heights = new float[hw, hw];
for (var x = 0; x < hw; x++) {
for (var z = 0; z < hw; z++) {
var xCoord = ((startPosX + x)/scale);
var zCoord = ((startPosZ + z)/scale);
heights[z, x] = Mathf.PerlinNoise(xCoord, zCoord);
}
}
Terrain.activeTerrain.terrainData.SetHeights(0,0,heights);
t.transform.position = new Vector3(ChunkPosX, 0,ChunkPosZ);
t.name = "Chunk "+nx+","+nz;
}
Hope that helps!
Scribe
It did help alot, but there is still something wrong, the terrains seem to have a little offset something like 0.5 ingame offset. Here's a picture: https://www.dropbox.com/s/qxlufpcx707tbph/Untitled.png Note: The picture is taken from something about 2 in game units away, so it isn't something huge its just a little offset.
Ahh I had stupidly thought that from terrain chunk to terrain chunk the perlin noise position would increase such as one ending at a relative position of 512 and the next one starting at a position of 513 but of course the edge height overlaps so you need to $$anonymous$$us 1 from the calculations using the resolution... so basically change line 15 and 16 a la:
var startPosX : int = (hw-1)*(nx-1);
var startPosZ : int = (hw-1)*(nz-1);
Also thanks for marking as answered, it is much appreciated by me and the site!
Scribe