Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Endless Terrain

Discussion in 'Editor & General Support' started by Calixto, May 25, 2013.

  1. Calixto

    Calixto

    Joined:
    Aug 31, 2012
    Posts:
    66
    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
     
    Last edited: May 25, 2013
  2. pas0003

    pas0003

    Joined:
    Mar 24, 2013
    Posts:
    18
    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..
     
  3. Calixto

    Calixto

    Joined:
    Aug 31, 2012
    Posts:
    66
    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<Terrain>();

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

    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();
    }
    }
    }
    ======================================================
     
    Last edited: May 29, 2013
  4. pas0003

    pas0003

    Joined:
    Mar 24, 2013
    Posts:
    18
    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
     
  5. Calixto

    Calixto

    Joined:
    Aug 31, 2012
    Posts:
    66
    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
     
  6. abi-kr01

    abi-kr01

    Joined:
    Aug 6, 2013
    Posts:
    4
    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
     
  7. eric56379

    eric56379

    Joined:
    Mar 11, 2014
    Posts:
    89
    Script isn't working... I tried using this script with mountains and hills and stuff, but it messed up the terrain. See image...
     

    Attached Files: