我正在使用C#创建一架飞机,我已经让它“工作”我得到了一架飞机。然而,三角形似乎没有正确连接,我无法理解为什么。
正如你所看到的那样,它比我能更好地解释它。
我认为这个问题只与我的指数有关,但我不确定。
我认为也可能有一个三角形不存在,所以我认为我的阵列也因为某些原因而变小。
Mesh CreatePlane(int width, int depth)
{
Mesh m = new Mesh();
int numVert=(width+1)*(depth+1);
Vector3[] vertecies = new Vector3[numVert];
Vector2[] uvs = new Vector2[numVert];
int[] triangles = new int[width*depth*6];
float uvx = 1.0f/width;
float uvy = 1.0f/depth;
int index = 0;
for (int i = 0;i<width;i++)
{
for(int j = 0;j<depth;j++)
{
vertecies[index] = new Vector3(i,0,-j);
uvs[index++] = new Vector2(j*uvx,i*uvy);
}
}
index = 0;
for(int j=0; j<depth; j++)
{
for(int i=0; i<width; i++)
{
triangles[index++] = (j * (width+1)) + i;
triangles[index++] = ((j+1) * (width+1)) + i;
triangles[index++] = (j * (width+1)) + i + 1;
triangles[index++] = ((j+1) * (width+1)) + i;
triangles[index++] = ((j+1) * (width+1)) + i + 1;
triangles[index++] = (j * (width+1)) + i + 1;
}
}
m.name = "ScriptPlane";
m.vertices = vertecies;
m.uv = uvs;
m.triangles = triangles;
m.RecalculateNormals();
return m;
}
答案 0 :(得分:4)
您以这种方式计算uvx
:
float uvx = 1.0f/width;
然后你以这种方式循环宽度:
for (int i = 0;i<width;i++)
{
for(int j = 0;j<depth;j++)
{
vertecies[index] = new Vector3(i,0,-j);
uvs[index++] = new Vector2(j*uvx,i*uvy);
}
}
如果你近距离看,有2个错误:
j
乘以uvx
,但它从0
到depth
周期(不应该是width
?); width
或depth
包括(使用<= width
或< width + 1
)。这些只是UV坐标,不要将顶点保留在该循环中。它不会解决你的问题,而只是你稍后会注意到的那两个错误。
要解决三角问题,请尝试以下方法:
0 +--+ 2 + 2
| / /|
|/ / |
1 + 1 +--+ 3
0 -> 1 -> 2
2 -> 1 -> 3
重要的是,逆时针方向订购它们以使背面剔除正常工作。 您可以使用任何其他顺序,有一些非常聪明的解决方案可以切换对角线并保持相邻性,这是优化网格缓冲区的旧硬件所必需的。较新的硬件将动态执行这些优化,而不需要您进行数学运算。
如上图所示,在三角形缓冲区中对三角形进行排序:
b = (j * width + i) * 6;
triangles[index++] = b + 0;
triangles[index++] = b + 1;
triangles[index++] = b + 2;
triangles[index++] = b + 2;
triangles[index++] = b + 1;
triangles[index++] = b + 3;
此时,您所要做的就是正确定位顶点。你发布了这个:
vertecies[index] = new Vector3(i,0,-j);
相反,你应该在一个单独的循环中 :
bx = i;
by = -j;
vertecies[index++] = new Vector3(bx + 0, 0, by - 1); // 0
vertecies[index++] = new Vector3(bx + 0, 0, by - 0); // 1
vertecies[index++] = new Vector3(bx + 1, 0, by - 1); // 2
vertecies[index++] = new Vector3(bx + 1, 0, by - 0); // 3
我也看到你交换y
和z
,这会引起头痛。此外,您将j
相对于世界空间坐标的方向反转。
我建议你重新考虑一下,正确定位相机并采用标准的坐标标记方式。它将在以后简化对空间的思考。
如果相机看起来像-Z
那么顶点应该用这种方式计算,而不是:
vertecies[index++] = new Vector3(bx + 0, by + 0, 0); // 0
vertecies[index++] = new Vector3(bx + 0, by + 1, 0); // 1
vertecies[index++] = new Vector3(bx + 1, by + 0, 0); // 2
vertecies[index++] = new Vector3(bx + 1, by + 1, 0); // 3
请注意:这不是简单的代码。轻微错误(某些+
或-
符号或某处遗失+1/-1
)的可能性很大,您应该相应地纠正错误。这一切应该可以让您更好地了解问题,但最终您必须运行并调试它,直到它正常工作。
答案 1 :(得分:1)
我建议尽可能尝试使用Unity的内置函数,但是如果这对你不起作用,这个脚本应该做你需要的而不需要额外的努力:http://wiki.unity3d.com/index.php?title=CreatePlane&oldid=10448。< / p>
如果您想坚持使用代码,上面的答案将涵盖您发布的代码的问题。