如何在程序生成的平面上添加额外的顶点?
本文关键字:顶点 添加 平面 程序生成 | 更新日期: 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();