Endless Terrain

Hi, I’m trying to design a flight simulator type of game. I would like to have a way to produce an endless terrain, so that my plane can fly over the terrain and it will never reach the edge.

What I want to do is somewhat like a Skybox, where the plane can never reach the edge of the sky.

The problem I’m having is that the two objects (the sky and the terrain) are developed in different ways. The terrain is actually a finite object within the game space.

Is there a way to create (even if its programmatically) a terrain that is “never-ending.”

I thought of having different seamless sections of terrain (which is hard to do) that I would programmatically add to the game view as the plane reaches a predefined distance. - Kind of like a chess board where you move from one square into the next square. I would simply programmatically add the new square and destroy the one that the plane exits.

However, I’m hoping that someone here has a better solution.

Thank you for your help,
Calixto

That is what I’m doing in my game (driving) and it’s working great. For a flight sim it might be more tricky though.

Not sure how important it is to have ‘endless’ terrain and a terrain which would be non random (eg. you can come back to places you’ve been to before). Can always just store a 2d array of data values which would correspond to different terrain tiles and add to that as you fly further out, while loading saved tiles if you fly back in…

Hi Pas0003, I agree that an endless terrain may not be most appropriate in all areas, but I need to do something so my plane doesn’t fly off the edge of my map.

I found a script that works from Unity Answers, but I need to understand it. I don’t yet. – I never copy anyone code unless they specifically code it for me.I want to learn how the script works and then I’ll adapt the concept to my needs.

I’ve posted the script below for your review if you care to see it. I tested it and yes, it works. I’m just not sure how - yet…

===============================================================
Source: http://answers.unity3d.com/storage/attachments/1978-infiniteterrain.zip

using UnityEngine;
using System.Collections;

public class InfiniteTerrain : MonoBehaviour
{
public GameObject PlayerObject;

private Terrain[,] _terrainGrid = new Terrain[3,3];

void Start ()
{
Terrain linkedTerrain = gameObject.GetComponent();

_terrainGrid[0,0] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent();
_terrainGrid[0,1] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent();
_terrainGrid[0,2] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent();
_terrainGrid[1,0] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent();
_terrainGrid[1,1] = linkedTerrain;
_terrainGrid[1,2] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent();
_terrainGrid[2,0] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent();
_terrainGrid[2,1] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent();
_terrainGrid[2,2] = Terrain.CreateTerrainGameObject(linkedTerrain.terrainData).GetComponent();

UpdateTerrainPositionsAndNeighbors();
}

private void UpdateTerrainPositionsAndNeighbors()
{
_terrainGrid[0,0].transform.position = new Vector3(
_terrainGrid[1,1].transform.position.x - _terrainGrid[1,1].terrainData.size.x,
_terrainGrid[1,1].transform.position.y,
_terrainGrid[1,1].transform.position.z + _terrainGrid[1,1].terrainData.size.z);
_terrainGrid[0,1].transform.position = new Vector3(
_terrainGrid[1,1].transform.position.x - _terrainGrid[1,1].terrainData.size.x,
_terrainGrid[1,1].transform.position.y,
_terrainGrid[1,1].transform.position.z);
_terrainGrid[0,2].transform.position = new Vector3(
_terrainGrid[1,1].transform.position.x - _terrainGrid[1,1].terrainData.size.x,
_terrainGrid[1,1].transform.position.y,
_terrainGrid[1,1].transform.position.z - _terrainGrid[1,1].terrainData.size.z);

_terrainGrid[1,0].transform.position = new Vector3(
_terrainGrid[1,1].transform.position.x,
_terrainGrid[1,1].transform.position.y,
_terrainGrid[1,1].transform.position.z + _terrainGrid[1,1].terrainData.size.z);
_terrainGrid[1,2].transform.position = new Vector3(
_terrainGrid[1,1].transform.position.x,
_terrainGrid[1,1].transform.position.y,
_terrainGrid[1,1].transform.position.z - _terrainGrid[1,1].terrainData.size.z);

_terrainGrid[2,0].transform.position = new Vector3(
_terrainGrid[1,1].transform.position.x + _terrainGrid[1,1].terrainData.size.x,
_terrainGrid[1,1].transform.position.y,
_terrainGrid[1,1].transform.position.z + _terrainGrid[1,1].terrainData.size.z);
_terrainGrid[2,1].transform.position = new Vector3(
_terrainGrid[1,1].transform.position.x + _terrainGrid[1,1].terrainData.size.x,
_terrainGrid[1,1].transform.position.y,
_terrainGrid[1,1].transform.position.z);
_terrainGrid[2,2].transform.position = new Vector3(
_terrainGrid[1,1].transform.position.x + _terrainGrid[1,1].terrainData.size.x,
_terrainGrid[1,1].transform.position.y,
_terrainGrid[1,1].transform.position.z - _terrainGrid[1,1].terrainData.size.z);

_terrainGrid[0,0].SetNeighbors( null, null, _terrainGrid[1,0], _terrainGrid[0,1]);
_terrainGrid[0,1].SetNeighbors( null, _terrainGrid[0,0], _terrainGrid[1,1], _terrainGrid[0,2]);
_terrainGrid[0,2].SetNeighbors( null, _terrainGrid[0,1], _terrainGrid[1,2], null);
_terrainGrid[1,0].SetNeighbors(_terrainGrid[0,0], null, _terrainGrid[2,0], _terrainGrid[1,1]);
_terrainGrid[1,1].SetNeighbors(_terrainGrid[0,1], _terrainGrid[1,0], _terrainGrid[2,1], _terrainGrid[1,2]);
_terrainGrid[1,2].SetNeighbors(_terrainGrid[0,2], _terrainGrid[1,1], _terrainGrid[2,2], null);
_terrainGrid[2,0].SetNeighbors(_terrainGrid[1,0], null, null, _terrainGrid[2,1]);
_terrainGrid[2,1].SetNeighbors(_terrainGrid[1,1], _terrainGrid[2,0], null, _terrainGrid[2,2]);
_terrainGrid[2,2].SetNeighbors(_terrainGrid[1,2], _terrainGrid[2,1], null, null);
}

void Update ()
{
Vector3 playerPosition = new Vector3(PlayerObject.transform.position.x, PlayerObject.transform.position.y, PlayerObject.transform.position.z);
Terrain playerTerrain = null;
int xOffset = 0;
int yOffset = 0;
for (int x = 0; x < 3; x++)
{
for (int y = 0; y < 3; y++)
{
if ((playerPosition.x >= _terrainGrid[x,y].transform.position.x)
(playerPosition.x <= (_terrainGrid[x,y].transform.position.x + _terrainGrid[x,y].terrainData.size.x))
(playerPosition.z >= _terrainGrid[x,y].transform.position.z)
(playerPosition.z <= (_terrainGrid[x,y].transform.position.z + _terrainGrid[x,y].terrainData.size.z)))
{
playerTerrain = _terrainGrid[x,y];
xOffset = 1 - x;
yOffset = 1 - y;
break;
}
}
if (playerTerrain != null)
break;
}

if (playerTerrain != _terrainGrid[1,1])
{
Terrain[,] newTerrainGrid = new Terrain[3,3];
for (int x = 0; x < 3; x++)
for (int y = 0; y < 3; y++)
{
int newX = x + xOffset;
if (newX < 0)
newX = 2;
else if (newX > 2)
newX = 0;
int newY = y + yOffset;
if (newY < 0)
newY = 2;
else if (newY > 2)
newY = 0;
newTerrainGrid[newX, newY] = _terrainGrid[x,y];
}
_terrainGrid = newTerrainGrid;
UpdateTerrainPositionsAndNeighbors();
}
}
}

After skimming through the code it looks pretty much exactly what I was doing previously (I’m using a slightly different system now). There’s a 3x3 array of terrain tiles and they reposition/regenerate when the player moves off the middle tile, making it current tile the middle tile again, but moving/recreating the tiles. Pretty much what you need I guess

Thanks, I’ll do more homework. I’ve seen where 9 tiles are used. Here, he’s using 3. I simply have to play around with the concept and find what will work for me.

Thanks again,
Calixto

hey pas0003 m trying to do the same crating endless drive way can u plz give me the idea or ur project so that i can do the same

Script isn’t working… I tried using this script with mountains and hills and stuff, but it messed up the terrain. See image…

1902912--122738--Capture.PNG