In this step we will create the basic terrain. We will generate a height map which Unity will convert into a terrain map.

A height map is basically a two dimensional array of floats where each position represents the height (between 0 and 1) of the terrain at that position. The final height of the terrain is calculated by multiplying this value with the property “Terrain Height” that you can find under Resolution in the Terrain Settings. Unity will interpolate the heights and create a smooth terrain.

1 First of all we need access to the terrain script that is attached to the terrain by default. Add three member variables to the TerrainGenerator.cs file that you have created in the previous step:

using System.Collections;
using UnityEngine;

public class TerrainGenerator : MonoBehaviour
{
    private float[,] _heights;
    private Terrain _terrain;
    private TerrainData _terrainData;

    // Use this for initialization
    private void Start()
    {
    }

    // Update is called once per frame
    private void Update()
    {
    }
}

The variable _heights will contain our height map, _terrain will store a reference to the terrain script, and _terrainData will contain the actual data used for generating the terrain.
Note: I am using Visual Studio for code editing but you can use any editor you like. And I am still using Unity 4.x but the tutorial should also work with Unity 5.x.

2 In the Start() method acquire the reference to the terrain script, and the reference to the terrain data which is located inside the script:

using System.Collections;
using UnityEngine;

public class TerrainGenerator : MonoBehaviour
{
    // ...

    // Use this for initialization
    private void Start()
    {
        _terrain = GetComponent<Terrain>();
        _terrainData = _terrain.terrainData;
    }

    // ...
}

 

3 Create the height map array with the dimensions that you find in the terrain data object:

using System.Collections;
using UnityEngine;

public class TerrainGenerator : MonoBehaviour
{
    // ...

    // Use this for initialization
    private void Start()
    {
        _terrain = GetComponent<Terrain>();
        _terrainData = _terrain.terrainData;
        _heights = new float[_terrainData.heightmapWidth, _terrainData.heightmapHeight];
    }

    // ...
}
4 Create a method called GeneratePerlinTerrain(). The method will use a method called PerlinNoise() – therefore the name. Call the method in Start() right after the creation of the height map. After the call take the height map and assign it to the terrain data object:

using System.Collections;
using UnityEngine;

public class TerrainGenerator : MonoBehaviour
{
    // ...

    public void GeneratePerlinTerrain()
    {
    }

    // Use this for initialization
    private void Start()
    {
        _terrain = GetComponent<Terrain>();
        _terrainData = _terrain.terrainData;
        _heights = new float[_terrainData.heightmapWidth, _terrainData.heightmapHeight];
        GeneratePerlinTerrain();
        _terrainData.SetHeights(0, 0, _heights);
    }
    // ...
}

 

5 Inside the GeneratePerlinTerrain() method create two nested loops for the x and z direction. Get the value from the Mathf.PerlinNoise() method for the position x, z and assign it to the corresponding position in the height map.
Note: To get values from PerlinNoise() that are usable for a terrain, you should be sampling values in very small steps, otherwise you’ll get a more or less flat terrain. Therefore divide x and z by for example 200. You have to play around with the values to get the terrain you like. The smaller the value is the rougher the terrain will be.

using System.Collections;
using UnityEngine;

public class TerrainGenerator : MonoBehaviour
{
    // ...

    public void GeneratePerlinTerrain()
    {
        for (int z = 0; z < _terrainData.heightmapHeight; ++z)
        {
            for (int x = 0; x < _terrainData.heightmapWidth; ++x)
            {
                float height = 0;

                height = Mathf.PerlinNoise(x / 200f, z / 200f);
                _heights[x, z] = height;
            }
        }
    }

    // ...
}

After you run the scene you should see a terrain somewhat like this: Of course you can also run around in the terrain. If you keep falling through the terrain then increase the vertical position (y) of the First Person Controller. 500 should be good value.