Help in making terrain gen better

Hi. I’ve been trying to make a survival game since I feel like it would be a good way to learn about inventory, adding models, procedural generation and etc. I made my Mesh Generator script but then it looks very scripted and has a pattern because there is no such thing as a flat area and a mountainous area. Any tips on adding “biomes” to not make my terrain look more natural because the entire thing seems to be so hilly but what I want is a hilly area and a not hilly area.

Code I have so far:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshFilter))]
public class MeshGenerator : MonoBehaviour
{
    private Mesh mesh;

    private Vector3[] vertices;
    private int[] triangles;

    [SerializeField] private int xSize = 20;
    [SerializeField] private int zSize = 20;

    void Start()
    {
        mesh = new Mesh();
        GetComponent<MeshFilter>().mesh = mesh;

        CreateShape();
        UpdateMesh();
    }

    void CreateShape()
    {
        vertices = new Vector3[(xSize + 1) * (zSize + 1)];

        for (int i = 0, z = 0; z <= zSize; z++)
        {
            for (int x = 0; x <= xSize; x++)
            {
                float y = Mathf.PerlinNoise(x * .025f, z * .025f) * 12;
                vertices[i] = new Vector3(x, y, z);
                i++;
            }
        }

        int tris = 0;
        int vert = 0;
        triangles = new int[xSize * zSize * 6];
        for (int z = 0; z < zSize; z++)
        {
            for (int x = 0; x < xSize; x++)
            {
                triangles[tris + 0] = vert + 0;
                triangles[tris + 1] = vert + xSize + 1;
                triangles[tris + 2] = vert + 1;
                triangles[tris + 3] = vert + 1;
                triangles[tris + 4] = vert + xSize + 1;
                triangles[tris + 5] = vert + xSize + 2;

                vert++;
                tris += 6;
            }

            vert++;
        }
    }

    void UpdateMesh()
    {
        mesh.Clear();

        mesh.vertices = vertices;
        mesh.triangles = triangles;

        mesh.RecalculateNormals();
        mesh.RecalculateBounds();
        MeshCollider meshCollider = gameObject.GetComponent<MeshCollider>();
        meshCollider.sharedMesh = mesh;
    }
}

My question is do you have any tips to help me make my terrain gen look more natural and have mountainous parts and flat parts. I’m thinking of using another noise map but I don’t really have an idea about how to do this.

This is an INCREDIBLY powerful way to go.

Try these steps instead of the simple call to Mathf.PerlinNoise().

I’m going to call your .025f multiplier a “frequency.” This is the frequency with which your linear step-step-step sweep of your domain goes through the PerlinNoise domain, as you know.

First, make two sets of frequency params, I like to use Vector2 since they are two floats.

Vector2 Outer= new Vector2( 0.02f, 0.02f);
Vector2 Inner = new Vector2( 0.25f, 0.25f);

You would use those with your PerlinNoise call to scale x/y.

Note how Outer is much lower frequency.

Each sample (x,y):

  • get the Outer noise value (it will change slowly over larger areas)

  • decide based on its value if you will make bumpy ground here (with the Inner noise value), or whether you will make nice flat ground.

That will make very unrealistic ground, like hard flat and all lumps.

But you can do other things like simply using the Outer value to scale the Inner bumps up and down, so you have very sharp areas and very un-sharp areas.

Here’s what that looks like in my Jetpack Kurt game

7580440--939577--Screen Shot 2021-10-17 at 6.57.44 PM.jpg

And from in the spaceship itself:

7580440--939580--Screen Shot 2021-10-17 at 7.01.21 PM.jpg

Another way to use it is to take the first one and force it to only be 0, 0.25f, 0.5f, 0.75 or 1.0

Then multiply it by a bunch and add a higher frequency one to it to get noise within each plateau

1 Like

Cool! I tried it out and it looks better now. Thanks.

1 Like