[Unity 学习] - 进阶篇 - Mesh基础系列2:圆角立方体

[Unity 学习] - 进阶篇 - Mesh基础系列2:圆角立方体

本文并非原创,只是本人的学习记录,原文是由放牛的星星老师翻译Catlike系列教程
链接: https://mp.weixin.qq.com/s/fZmw-AIGpXz5AToChjA8Lw

1复合一个立方体

在Mesh基础系列1中,我们最后做出一个面向-Z的一个main,我们可以创建六个网格来实例化完成一个立方体,但是它并不实用,因为他是六个Mesh,这样就增加我们整体使用它的难度,具体怎么增加难度,我会在后面进行说明。在这之前,我们先做一个整体立方体用以做对比。

2 创建立方体顶点集合

首先我们需要一个component脚本,2Dmesh和3Dmesh没有太多区别,只需要增加一个维度就好,在上个章节的代码中加入zSize即可。

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class RoundedCube : MonoBehaviour {

	public int xSize, ySize, zSize;

	private Mesh mesh;
	private Vector3[] vertices;

	private void Awake () {
		Generate();
	}
	private void Generate () {
		GetComponent<MeshFilter>().mesh = mesh = new Mesh();
		mesh.name = "Procedural Cube";
	}

	private void OnDrawGizmos () {
     	if (vertices == null) {
     		return;
     	}
     	for (int i = 0; i < vertices.Length; i++) {
     		Gizmos.color = Color.black;
     		Gizmos.DrawSphere(vertices[i], 0.1f);
     		Gizmos.color = Color.yellow;
     		Gizmos.DrawRay(vertices[i], normals[i]);
     	}
    }

设置xyz的大小
[设置立方体的大小]
计算一共需要多少个点,我们最好创建一个没有重复顶点的立方体
首先,有八个角点,12条边,所以我们获取点的个数

	int cornerVertices = 8;
	int edgeVertices = (xSize + ySize + zSize - 3) * 4;
	int faceVertices = (
		(xSize - 1) * (ySize - 1) +
		(xSize - 1) * (zSize - 1) +
		(ySize - 1) * (zSize - 1)) * 2;
	vertices = new Vector3[cornerVertices + edgeVertices + faceVertices];

定位第一面的顶点定位网格的第一行一样

 int v = 0;
 for (int x = 0;x < = xSize; x++)
 {
 	vertices[v++] = new Vector3(x, 0, 0);
 	yield return wait;
 }

v用来计算顶点数,这样我们不会担心咋其他位置增加v,导致顶点的数据多余,继续第二面的第一行

for (int z = 1; z <= zSize; z++) {
	vertices[v++] = new Vector3(v++, xSize, y, z);
}
for (int x = xSize - 1; x >= 0; x--) {
	vertices[v++] = new Vector3(x, y, zSize);
}
for (int z = zSize - 1; z > 0; z--) {
	vertices[v++] = new Vector3( 0, y, z);
}

这样我们就得到第一个欢,接下来我在y这里向量中,叠加过个环

for (int y = 0; y <= ySize; y++) {
	for (int x = 0; x <= xSize; x++) {
		vertices[v++] = new Vector3(x, y, 0);
	}

这样我们看似的到一个立方体,但没有盖子,所以在上下两个面叠加盖子

for (int z = 1; z < zSize; z++) {
	for (int x = 1; x < xSize; x++) {
		vertices[v++] = new Vector3(x, ySize, z);
	}
}
for (int z = 1; z < zSize; z++) {
	for (int x = 1; x < xSize; x++) {
		vertices[v++] = new Vector3(x, 0, z);
	}
}`

3 添加三角形

我们删除协程,然后创建顶点和三角形的单独方法,将顶点赋值到mesh中

private void CreateVertices () {
	....
	mesh.vertices = vertices;
}

创建单个正方形

	private static int SetQuad (int[] triangles, int i, int v00, int v10, int v01, int v11) {
		triangles[i] = v00;
		triangles[i + 1] = triangles[i + 4] = v01;
		triangles[i + 2] = triangles[i + 3] = v10;
		triangles[i + 5] = v11;
		return i + 6;
	}

创建三角形的方法

private void CreateTriangles () {
	int queds = (xSize * ySize  + xSize * zSize + ySize * zSize) * 2;
	int [] triangles = new int[queade * 6]
	mesh.triangles = triagnles;
}

到这里就是可以创建面片和顶点了,接下来,我们根据顶点的位置,将面片依次创建出来

for (int q = 0; q<ring - 1; q++, v++)
{
	 t = SetQuad(triangles, t, v, v + 1, v + ring, v + ring + 1);
}
t = SetQuad(triangles, t, v, v - ring + 1, v + ring, v + 1);

这里需要注意一下,我们创建顶点的时候,是依次往上加载的,所以说,最后一个面片的顶点需要回到当前这一环的起始位置;
完整代码

for (int y = 0; y < ySize; ++y, v++)
{
	for (int q = 0; q<ring - 1; q++, v++)
	{
		 t = SetQuad(triangles, t, v, v + 1, v + ring, v + ring + 1);
	}
	t = SetQuad(triangles, t, v, v - ring + 1, v + ring, v + 1);
}

然后创建顶部和底部,需要注意的是,顶部和底部顶点的排列方式

private int CreateTopFace (int[] triangles, int t, int ring) {
		int v = ring * ySize;
		for (int x = 0; x < xSize - 1; x++, v++) {
			t = SetQuad(triangles, t, v, v + 1, v + ring - 1, v + ring);
		}
		t = SetQuad(triangles, t, v, v + 1, v + ring - 1, v + 2);

		int vMin = ring * (ySize + 1) - 1;
		int vMid = vMin + 1;
		int vMax = v + 2;

		for (int z = 1; z < zSize - 1; z++, vMin--, vMid++, vMax++) {
			t = SetQuad(triangles, t, vMin, vMid, vMin - 1, vMid + xSize - 1);
			for (int x = 1; x < xSize - 1; x++, vMid++) {
				t = SetQuad(
					triangles, t,
					vMid, vMid + 1, vMid + xSize - 1, vMid + xSize);
			}
			t = SetQuad(triangles, t, vMid, vMax, vMid + xSize - 1, vMax + 1);
		}

		int vTop = vMin - 2;
		t = SetQuad(triangles, t, vMin, vMid, vTop + 1, vTop);
		for (int x = 1; x < xSize - 1; x++, vTop--, vMid++) {
			t = SetQuad(triangles, t, vMid, vMid + 1, vTop, vTop - 1);
		}
		t = SetQuad(triangles, t, vMid, vTop - 2, vTop, vTop - 1);

		return t;
	}

底部也是一样的

private int CreateBottomFace (int[] triangles, int t, int ring) {
		int v = 1;
		int vMid = vertices.Length - (xSize - 1) * (zSize - 1);
		t = SetQuad(triangles, t, ring - 1, vMid, 0, 1);
		for (int x = 1; x < xSize - 1; x++, v++, vMid++) {
			t = SetQuad(triangles, t, vMid, vMid + 1, v, v + 1);
		}
		t = SetQuad(triangles, t, vMid, v + 2, v, v + 1);

		int vMin = ring - 2;
		vMid -= xSize - 2;
		int vMax = v + 2;

		for (int z = 1; z < zSize - 1; z++, vMin--, vMid++, vMax++) {
			t = SetQuad(triangles, t, vMin, vMid + xSize - 1, vMin + 1, vMid);
			for (int x = 1; x < xSize - 1; x++, vMid++) {
				t = SetQuad(
					triangles, t,
					vMid + xSize - 1, vMid + xSize, vMid, vMid + 1);
			}
			t = SetQuad(triangles, t, vMid + xSize - 1, vMax + 1, vMid, vMax);
		}

		int vTop = vMin - 1;
		t = SetQuad(triangles, t, vTop + 1, vTop, vTop + 2, vMid);
		for (int x = 1; x < xSize - 1; x++, vTop--, vMid++) {
			t = SetQuad(triangles, t, vTop, vTop - 1, vMid, vMid + 1);
		}
		t = SetQuad(triangles, t, vTop, vTop - 1, vMid, vTop - 2);

		return t;
	}

猜你喜欢

转载自blog.csdn.net/qq_43617207/article/details/129498914