0

I found an old tutorial that has not been updated in awhile, and followed it to create some 1D plane terrain. It uses bezier curves to generate the surface, which then acts as the land.

However, this only creates two sets of vertices - one at the bottom and one at the top. I would like to pad it so it generates more of a cube shape, but I am not sure where to add the additional vertices. Another goal is to add more vertices between the top and bottom to create a shape that is more solid. Where should I add the additional vertices loops in order to create the cube-like shape, giving the mesh a higher resolution and depth?

using UnityEngine;
using System.Collections.Generic;

public class TerrainGenerator : MonoBehaviour
{
    public Vector3[] meshPoints = null;

    private Mesh _mesh = null;
    public List<Vector3> vertices = new List<Vector3>();
    private List<int> triangles = new List<int>();

    private MeshCollider _collider;
    private MeshFilter _filter;

    private float terrainSize = 0.4f;

    public LandTypes type;

    public float lastHeight = 3;

    void Awake()
    {
        _collider = GetComponent<MeshCollider>();
        _filter = GetComponent<MeshFilter>();
    }

    public void GenerateMesh(float lh, LandTypes Type)
    {
        type = Type;
        _mesh = _filter.mesh;
        _mesh.Clear();

        meshPoints = new Vector3[4];

        switch(Type)
        {
            case LandTypes.Flat:
                meshPoints[0] = new Vector3(terrainSize * (float)0, lh, 0f);
                meshPoints[1] = new Vector3(terrainSize * (float)1, lh, 0f);
                meshPoints[2] = new Vector3(terrainSize * (float)2, lh, 0f);
                meshPoints[3] = new Vector3(terrainSize * (float)3, lh, 0f);
                break;
            case LandTypes.Up:
                int typeOfUpChance = Random.Range(1, 20);

                if (typeOfUpChance > 10)
                {
                    meshPoints[0] = new Vector3(terrainSize * (float)0, lh, 0f);
                    meshPoints[1] = new Vector3(terrainSize * (float)1, lh + 1, 0f);
                    meshPoints[2] = new Vector3(terrainSize * (float)2, lh + 2, 0f);
                    meshPoints[3] = new Vector3(terrainSize * (float)3, lh + 3, 0f);
                } else
                {
                    meshPoints[0] = new Vector3(terrainSize * (float)0, lh, 0f);
                    meshPoints[1] = new Vector3(terrainSize * (float)1, lh + Random.Range(2, 3), 0f);
                    meshPoints[2] = new Vector3(terrainSize * (float)2, lh + Random.Range(2, 4), 0f);
                    meshPoints[3] = new Vector3(terrainSize * (float)3, lh + 5, 0f);
                }


                break;
            case LandTypes.Down:
                if (lh > 6f)
                {
                    meshPoints[0] = new Vector3(terrainSize * (float)0, lh, 0f);
                    meshPoints[1] = new Vector3(terrainSize * (float)1, lh - 2, 0f);
                    meshPoints[2] = new Vector3(terrainSize * (float)2, lh - 3, 0f);
                    meshPoints[3] = new Vector3(terrainSize * (float)3, lh - 4, 0f);
                }
                else
                {
                    meshPoints[0] = new Vector3(terrainSize * (float)0, lh, 0f);
                    meshPoints[1] = new Vector3(terrainSize * (float)1, lh, 0f);
                    meshPoints[2] = new Vector3(terrainSize * (float)2, lh, 0f);
                    meshPoints[3] = new Vector3(terrainSize * (float)3, lh, 0f);
                }
            break;
            case LandTypes.Hill:
                meshPoints[0] = new Vector3(terrainSize * (float)0, lh, 0f);
                meshPoints[1] = new Vector3(terrainSize * (float)1, lh + 1.5f, 0f);
                meshPoints[2] = new Vector3(terrainSize * (float)2, lh + 1.5f, 0f);
                meshPoints[3] = new Vector3(terrainSize * (float)3, lh, 0f);
            break;
        }

        LandController.Instance.HeightCounts.Add(meshPoints[3].y);
        LandController.Instance.lastHeight = meshPoints[3].y;

        int resolution = 8;
        for (int i = 0; i < resolution; i++)
        {
            float t = (float)i / (float)(resolution - 1);
            Vector3 p = CalculateBezierPoint(t, meshPoints[0], meshPoints[1], meshPoints[2], meshPoints[3]);

            AddTerrainPoint(p);
        }

        _mesh.vertices = vertices.ToArray();
        _mesh.triangles = triangles.ToArray();
        _mesh.RecalculateBounds();
        _mesh.RecalculateNormals();
        _collider.sharedMesh = _mesh;
    }

    void AddTerrainPoint(Vector3 point)
    {

        vertices.Add(new Vector3(point.x, 0f, 0f));
        vertices.Add(point);


        if (vertices.Count >= 4)
        {
            int start = vertices.Count - 4;
            triangles.Add(start + 0);
            triangles.Add(start + 1);
            triangles.Add(start + 2);
            triangles.Add(start + 1);
            triangles.Add(start + 3);
            triangles.Add(start + 2);
        }
    }



    private Vector3 CalculateBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
    {

        float u = 1 - t;
        float tt = t * t;
        float uu = u * u;
        float uuu = uu * u;
        float ttt = tt * t;

        Vector3 p = uuu * p0;
        p += 3 * uu * t * p1;
        p += 3 * u * tt * p2;
        p += ttt * p3;

        return p;
    }
}
Merlin
  • 929
  • 12
  • 33

1 Answers1

1

I'm pretty sure I've followed that tutorial, that code looks familiar.

You are right that it is out of date though. You should look out this resource on the Unity Wiki, it is newer and contains many more primitives than just planes, including cubes, cones, torus, sphere, and icosphere. I've reproduced the cube code here since that is what you asked about.

MeshFilter filter = gameObject.AddComponent< MeshFilter >();
Mesh mesh = filter.mesh;
mesh.Clear();

float length = 1f;
float width = 1f;
float height = 1f;

#region Vertices
Vector3 p0 = new Vector3( -length * .5f,    -width * .5f, height * .5f );
Vector3 p1 = new Vector3( length * .5f,     -width * .5f, height * .5f );
Vector3 p2 = new Vector3( length * .5f,     -width * .5f, -height * .5f );
Vector3 p3 = new Vector3( -length * .5f,    -width * .5f, -height * .5f );  

Vector3 p4 = new Vector3( -length * .5f,    width * .5f,  height * .5f );
Vector3 p5 = new Vector3( length * .5f,     width * .5f,  height * .5f );
Vector3 p6 = new Vector3( length * .5f,     width * .5f,  -height * .5f );
Vector3 p7 = new Vector3( -length * .5f,    width * .5f,  -height * .5f );

Vector3[] vertices = new Vector3[]
{
    // Bottom
    p0, p1, p2, p3,

    // Left
    p7, p4, p0, p3,

    // Front
    p4, p5, p1, p0,

    // Back
    p6, p7, p3, p2,

    // Right
    p5, p6, p2, p1,

    // Top
    p7, p6, p5, p4
};
#endregion

#region Normales
Vector3 up  = Vector3.up;
Vector3 down    = Vector3.down;
Vector3 front   = Vector3.forward;
Vector3 back    = Vector3.back;
Vector3 left    = Vector3.left;
Vector3 right   = Vector3.right;

Vector3[] normales = new Vector3[]
{
    // Bottom
    down, down, down, down,

    // Left
    left, left, left, left,

    // Front
    front, front, front, front,

    // Back
    back, back, back, back,

    // Right
    right, right, right, right,

    // Top
    up, up, up, up
};
#endregion  

#region UVs
Vector2 _00 = new Vector2( 0f, 0f );
Vector2 _10 = new Vector2( 1f, 0f );
Vector2 _01 = new Vector2( 0f, 1f );
Vector2 _11 = new Vector2( 1f, 1f );

Vector2[] uvs = new Vector2[]
{
    // Bottom
    _11, _01, _00, _10,

    // Left
    _11, _01, _00, _10,

    // Front
    _11, _01, _00, _10,

    // Back
    _11, _01, _00, _10,

    // Right
    _11, _01, _00, _10,

    // Top
    _11, _01, _00, _10,
};
#endregion

#region Triangles
int[] triangles = new int[]
{
    // Bottom
    3, 1, 0,
    3, 2, 1,            

    // Left
    3 + 4 * 1, 1 + 4 * 1, 0 + 4 * 1,
    3 + 4 * 1, 2 + 4 * 1, 1 + 4 * 1,

    // Front
    3 + 4 * 2, 1 + 4 * 2, 0 + 4 * 2,
    3 + 4 * 2, 2 + 4 * 2, 1 + 4 * 2,

    // Back
    3 + 4 * 3, 1 + 4 * 3, 0 + 4 * 3,
    3 + 4 * 3, 2 + 4 * 3, 1 + 4 * 3,

    // Right
    3 + 4 * 4, 1 + 4 * 4, 0 + 4 * 4,
    3 + 4 * 4, 2 + 4 * 4, 1 + 4 * 4,

    // Top
    3 + 4 * 5, 1 + 4 * 5, 0 + 4 * 5,
    3 + 4 * 5, 2 + 4 * 5, 1 + 4 * 5,

};
#endregion

mesh.vertices = vertices;
mesh.normals = normales;
mesh.uv = uvs;
mesh.triangles = triangles;

mesh.RecalculateBounds();
mesh.Optimize();
Cody
  • 2,643
  • 2
  • 10
  • 24