通过脚本绘制地形网格
Drawing a terrain mesh by script
我正在尝试使用脚本绘制一些地形。但是我得到了奇怪的结果,似乎无法查明问题所在。
在 Start
方法中,我正在构建我的初始网格。
Vector3[] verts = new Vector3[mapWidth * mapHeight * 6];
Vector2[] uvs = new Vector2[mapWidth * mapHeight * 6];
int[] triangles = new int[mapWidth * mapHeight * 6];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
verts[x * y * 6 + 0] = new Vector3(x, 0, y);
verts[x * y * 6 + 1] = new Vector3(x + 1, 0, y);
verts[x * y * 6 + 2] = new Vector3(x + 1, 0, y + 1);
verts[x * y * 6 + 3] = new Vector3(x, 0, y);
verts[x * y * 6 + 4] = new Vector3(x + 1, 0, y + 1);
verts[x * y * 6 + 5] = new Vector3(x, 0, y + 1);
uvs[x * y * 6 + 0] = new Vector2(0, 0);
uvs[x * y * 6 + 1] = new Vector2(1, 0);
uvs[x * y * 6 + 2] = new Vector2(1, 1);
uvs[x * y * 6 + 3] = new Vector2(0, 0);
uvs[x * y * 6 + 4] = new Vector2(1, 1);
uvs[x * y * 6 + 5] = new Vector2(0, 1);
for (int t = 0; t < 6; t++)
{
triangles[x * y * 6 + t] = x * y * 6 + 5 - t;
}
}
}
terrain.vertices = verts;
terrain.uv = uvs;
terrain.triangles = triangles;
terrain.RecalculateNormals();
我绘制网格所做的只是Graphics.DrawMesh(terrain, Vector3.zero, Quaternion.identity, mat, 1);
。 Material(mat) 只是一个简单的网格纹理,似乎工作正常。然而,Unity 决定不随机绘制三角对。
gizmo 位于 0, 0, 0
并且每个 运行 它呈现相同的形状。我需要画一个 10 x 10
形状。我正在创建重复的顶点,因为我最终需要硬边。
你这样做的问题是你的指数。 "flattening" 二维数组的公式是 x + y * 宽度(或 x * 高度 + y),而不是 x * y。
IMO 解决此类问题的最佳方法是手动计算有效值和未按预期工作的值,然后查看是否找到规律。
在你的情况下,似乎 (0|0) 不起作用,而 (0|9) 却起作用,让我们看看为什么。
所以如果我们使用 x = 0 和 y = 0,我们会得到 verts[0 * 0 * 6 + num] = 0 + num。现在我们为 x = 0,y = 9 做这件事,唉,verts[0 * 9 * 6 + num] 仍然是 0 + num。由于 (0|9) 是稍后计算的,问题是 (0|0) 的顶点、uvs 和三角形被这些值覆盖 - 这中间的所有内容都是同样的问题,例如,3 * 5 是等同于 5 * 3.
因此,要修复您的代码,以下应该可行。
Vector3[] verts = new Vector3[mapWidth * mapHeight * 6];
Vector2[] uvs = new Vector2[mapWidth * mapHeight * 6];
int[] triangles = new int[mapWidth * mapHeight * 6];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int tileIndex = x + y * width;
verts[tileIndex * 6 + 0] = new Vector3(x, 0, y);
verts[tileIndex * 6 + 1] = new Vector3(x + 1, 0, y);
verts[tileIndex * 6 + 2] = new Vector3(x + 1, 0, y + 1);
verts[tileIndex * 6 + 3] = new Vector3(x, 0, y);
verts[tileIndex * 6 + 4] = new Vector3(x + 1, 0, y + 1);
verts[tileIndex * 6 + 5] = new Vector3(x, 0, y + 1);
uvs[tileIndex * 6 + 0] = new Vector2(0, 0);
uvs[tileIndex * 6 + 1] = new Vector2(1, 0);
uvs[tileIndex * 6 + 2] = new Vector2(1, 1);
uvs[tileIndex * 6 + 3] = new Vector2(0, 0);
uvs[tileIndex * 6 + 4] = new Vector2(1, 1);
uvs[tileIndex * 6 + 5] = new Vector2(0, 1);
for (int t = 0; t < 6; t++) {
triangles[tileIndex * 6 + t] = tileIndex * 6 + 5 - t;
}
}
}
terrain.vertices = verts;
terrain.uv = uvs;
terrain.triangles = triangles;
terrain.RecalculateNormals();
我正在尝试使用脚本绘制一些地形。但是我得到了奇怪的结果,似乎无法查明问题所在。
在 Start
方法中,我正在构建我的初始网格。
Vector3[] verts = new Vector3[mapWidth * mapHeight * 6];
Vector2[] uvs = new Vector2[mapWidth * mapHeight * 6];
int[] triangles = new int[mapWidth * mapHeight * 6];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
verts[x * y * 6 + 0] = new Vector3(x, 0, y);
verts[x * y * 6 + 1] = new Vector3(x + 1, 0, y);
verts[x * y * 6 + 2] = new Vector3(x + 1, 0, y + 1);
verts[x * y * 6 + 3] = new Vector3(x, 0, y);
verts[x * y * 6 + 4] = new Vector3(x + 1, 0, y + 1);
verts[x * y * 6 + 5] = new Vector3(x, 0, y + 1);
uvs[x * y * 6 + 0] = new Vector2(0, 0);
uvs[x * y * 6 + 1] = new Vector2(1, 0);
uvs[x * y * 6 + 2] = new Vector2(1, 1);
uvs[x * y * 6 + 3] = new Vector2(0, 0);
uvs[x * y * 6 + 4] = new Vector2(1, 1);
uvs[x * y * 6 + 5] = new Vector2(0, 1);
for (int t = 0; t < 6; t++)
{
triangles[x * y * 6 + t] = x * y * 6 + 5 - t;
}
}
}
terrain.vertices = verts;
terrain.uv = uvs;
terrain.triangles = triangles;
terrain.RecalculateNormals();
我绘制网格所做的只是Graphics.DrawMesh(terrain, Vector3.zero, Quaternion.identity, mat, 1);
。 Material(mat) 只是一个简单的网格纹理,似乎工作正常。然而,Unity 决定不随机绘制三角对。
gizmo 位于 0, 0, 0
并且每个 运行 它呈现相同的形状。我需要画一个 10 x 10
形状。我正在创建重复的顶点,因为我最终需要硬边。
你这样做的问题是你的指数。 "flattening" 二维数组的公式是 x + y * 宽度(或 x * 高度 + y),而不是 x * y。
IMO 解决此类问题的最佳方法是手动计算有效值和未按预期工作的值,然后查看是否找到规律。
在你的情况下,似乎 (0|0) 不起作用,而 (0|9) 却起作用,让我们看看为什么。
所以如果我们使用 x = 0 和 y = 0,我们会得到 verts[0 * 0 * 6 + num] = 0 + num。现在我们为 x = 0,y = 9 做这件事,唉,verts[0 * 9 * 6 + num] 仍然是 0 + num。由于 (0|9) 是稍后计算的,问题是 (0|0) 的顶点、uvs 和三角形被这些值覆盖 - 这中间的所有内容都是同样的问题,例如,3 * 5 是等同于 5 * 3.
因此,要修复您的代码,以下应该可行。
Vector3[] verts = new Vector3[mapWidth * mapHeight * 6];
Vector2[] uvs = new Vector2[mapWidth * mapHeight * 6];
int[] triangles = new int[mapWidth * mapHeight * 6];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int tileIndex = x + y * width;
verts[tileIndex * 6 + 0] = new Vector3(x, 0, y);
verts[tileIndex * 6 + 1] = new Vector3(x + 1, 0, y);
verts[tileIndex * 6 + 2] = new Vector3(x + 1, 0, y + 1);
verts[tileIndex * 6 + 3] = new Vector3(x, 0, y);
verts[tileIndex * 6 + 4] = new Vector3(x + 1, 0, y + 1);
verts[tileIndex * 6 + 5] = new Vector3(x, 0, y + 1);
uvs[tileIndex * 6 + 0] = new Vector2(0, 0);
uvs[tileIndex * 6 + 1] = new Vector2(1, 0);
uvs[tileIndex * 6 + 2] = new Vector2(1, 1);
uvs[tileIndex * 6 + 3] = new Vector2(0, 0);
uvs[tileIndex * 6 + 4] = new Vector2(1, 1);
uvs[tileIndex * 6 + 5] = new Vector2(0, 1);
for (int t = 0; t < 6; t++) {
triangles[tileIndex * 6 + t] = tileIndex * 6 + 5 - t;
}
}
}
terrain.vertices = verts;
terrain.uv = uvs;
terrain.triangles = triangles;
terrain.RecalculateNormals();