Search Unity

Help in making terrain gen better

Discussion in 'Scripting' started by lanceslances, Oct 18, 2021.

  1. lanceslances

    lanceslances

    Joined:
    Aug 9, 2021
    Posts:
    10
    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:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [RequireComponent(typeof(MeshFilter))]
    6. public class MeshGenerator : MonoBehaviour
    7. {
    8.     private Mesh mesh;
    9.  
    10.     private Vector3[] vertices;
    11.     private int[] triangles;
    12.  
    13.     [SerializeField] private int xSize = 20;
    14.     [SerializeField] private int zSize = 20;
    15.  
    16.     void Start()
    17.     {
    18.         mesh = new Mesh();
    19.         GetComponent<MeshFilter>().mesh = mesh;
    20.  
    21.         CreateShape();
    22.         UpdateMesh();
    23.     }
    24.  
    25.     void CreateShape()
    26.     {
    27.         vertices = new Vector3[(xSize + 1) * (zSize + 1)];
    28.  
    29.         for (int i = 0, z = 0; z <= zSize; z++)
    30.         {
    31.             for (int x = 0; x <= xSize; x++)
    32.             {
    33.                 float y = Mathf.PerlinNoise(x * .025f, z * .025f) * 12;
    34.                 vertices[i] = new Vector3(x, y, z);
    35.                 i++;
    36.             }
    37.         }
    38.  
    39.         int tris = 0;
    40.         int vert = 0;
    41.         triangles = new int[xSize * zSize * 6];
    42.         for (int z = 0; z < zSize; z++)
    43.         {
    44.             for (int x = 0; x < xSize; x++)
    45.             {
    46.                 triangles[tris + 0] = vert + 0;
    47.                 triangles[tris + 1] = vert + xSize + 1;
    48.                 triangles[tris + 2] = vert + 1;
    49.                 triangles[tris + 3] = vert + 1;
    50.                 triangles[tris + 4] = vert + xSize + 1;
    51.                 triangles[tris + 5] = vert + xSize + 2;
    52.  
    53.                 vert++;
    54.                 tris += 6;
    55.             }
    56.  
    57.             vert++;
    58.         }
    59.     }
    60.  
    61.     void UpdateMesh()
    62.     {
    63.         mesh.Clear();
    64.  
    65.         mesh.vertices = vertices;
    66.         mesh.triangles = triangles;
    67.  
    68.         mesh.RecalculateNormals();
    69.         mesh.RecalculateBounds();
    70.         MeshCollider meshCollider = gameObject.GetComponent<MeshCollider>();
    71.         meshCollider.sharedMesh = mesh;
    72.     }
    73. }
    74.  
    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.
     

    Attached Files:

  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    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.

    Code (csharp):
    1. Vector2 Outer= new Vector2( 0.02f, 0.02f);
    2. 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

    Screen Shot 2021-10-17 at 6.57.44 PM.png

    And from in the spaceship itself:

    Screen Shot 2021-10-17 at 7.01.21 PM.png


    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
     
    lanceslances likes this.
  3. lanceslances

    lanceslances

    Joined:
    Aug 9, 2021
    Posts:
    10
    Cool! I tried it out and it looks better now. Thanks.
     
    Kurt-Dekker likes this.