如何在程序生成的平面上添加额外的顶点?

本文关键字:顶点 添加 平面 程序生成 | 更新日期: 2023-09-27 18:07:05

我找到了一个很久没有更新的旧教程,并按照它创建了一些1D平面地形。它使用贝塞尔曲线来生成表面,然后作为陆地。

然而,这只创建了两组顶点——一个在底部,一个在顶部。我想填充它,让它产生更多的立方体形状,但我不确定在哪里添加额外的顶点。另一个目标是在顶部和底部之间添加更多的顶点,以创建一个更坚固的形状。我应该在哪里添加额外的顶点循环,以创建立方体形状,给网格更高的分辨率和深度?

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;
    }
}

如何在程序生成的平面上添加额外的顶点?

我很确定我已经遵循了那个教程,代码看起来很熟悉。

你是对的,它已经过时了。你应该在Unity Wiki上看看这个资源,它是更新的,包含了比平面更多的原语,包括立方体,锥体,环面,球体和icosphere。我在这里复制了立方体代码,因为这是你问的。

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();