我有一些代码可以创建一个圆形网格,它需要一个半径,多个边(一个圆的边数大约为100)和“轮廓宽度”。如下初始化网格:
MeshFilter mf = GetComponent<MeshFilter>();
Mesh mesh = new Mesh();
mf.mesh = mesh;
mesh.subMeshCount = 2;
它为顶点分配了一些数学运算,这并不是完全可以自我解释的,但是我猜相信它会将顶点分配为具有n个边的规则多边形,然后再次为轮廓分配:
//vertices
List<Vector3> verticesList = new List<Vector3> { };
float x;
float y;
for (int i = 0; i < n; i++)
{
x = radius * Mathf.Sin((2 * Mathf.PI * i) / n);
y = radius * Mathf.Cos((2 * Mathf.PI * i) / n);
verticesList.Add(new Vector3(x, y, 0f));
}
for (int i = 0; i < n; i++)
{
x = (radius + OLwidth) * Mathf.Sin((2 * Mathf.PI * i) / n);
y = (radius + OLwidth) * Mathf.Cos((2 * Mathf.PI * i) / n);
verticesList.Add(new Vector3(x, y, 0f));
}
Vector3[] vertices = verticesList.ToArray();
然后有两个三角形列表,以后用mesh.SetTriangles()
用这两个三角形数组制作两个子网格:
//triangles
List<int> trianglesList = new List<int> { };
List<int> OLtrianglesList = new List<int> { };
for (int i = 0; i < (n - 2); i++)
{
trianglesList.Add(0);
trianglesList.Add(i + 1);
trianglesList.Add(i + 2);
}
for (int i = 0; i < (n - 2); i++)
{
trianglesList.Add(n);
trianglesList.Add(i + n + 1);
trianglesList.Add(i + n + 2);
}
int[] triangles = trianglesList.ToArray();
int[] OLtriangles = OLtrianglesList.ToArray();
所有法线都只是-Vector3.forward
:
//normals
List<Vector3> normalsList = new List<Vector3> { };
for (int i = 0; i < vertices.Length; i++)
{
normalsList.Add(-Vector3.forward);
}
Vector3[] normals = normalsList.ToArray();
然后按如下所示初始化网格:
//initialise
mesh.vertices = vertices;
mesh.normals = normals;
mesh.SetTriangles(triangles, 0);
mesh.SetTriangles(OLtriangles, 1);
因此完整的代码如下所示(在最后设置了一个多对撞机,但这无关紧要):
public void PolyMesh(float radius, int n, float OLwidth)
{
MeshFilter mf = GetComponent<MeshFilter>();
Mesh mesh = new Mesh();
mf.mesh = mesh;
mesh.subMeshCount = 2;
//vertices
List<Vector3> verticesList = new List<Vector3> { };
float x;
float y;
for (int i = 0; i < n; i++)
{
x = radius * Mathf.Sin((2 * Mathf.PI * i) / n);
y = radius * Mathf.Cos((2 * Mathf.PI * i) / n);
verticesList.Add(new Vector3(x, y, 0f));
}
for (int i = 0; i < n; i++)
{
x = (radius + OLwidth) * Mathf.Sin((2 * Mathf.PI * i) / n);
y = (radius + OLwidth) * Mathf.Cos((2 * Mathf.PI * i) / n);
verticesList.Add(new Vector3(x, y, 0f));
}
Vector3[] vertices = verticesList.ToArray();
//triangles
List<int> trianglesList = new List<int> { };
List<int> OLtrianglesList = new List<int> { };
for (int i = 0; i < (n - 2); i++)
{
trianglesList.Add(0);
trianglesList.Add(i + 1);
trianglesList.Add(i + 2);
}
for (int i = 0; i < (n - 2); i++)
{
trianglesList.Add(n);
trianglesList.Add(i + n + 1);
trianglesList.Add(i + n + 2);
}
int[] triangles = trianglesList.ToArray();
int[] OLtriangles = OLtrianglesList.ToArray();
//normals
List<Vector3> normalsList = new List<Vector3> { };
for (int i = 0; i < vertices.Length; i++)
{
normalsList.Add(-Vector3.forward);
}
Vector3[] normals = normalsList.ToArray();
//initialise
mesh.vertices = vertices;
mesh.normals = normals;
mesh.SetTriangles(triangles, 0);
mesh.SetTriangles(OLtriangles, 1);
//polyCollider
polyCollider.pathCount = 1;
List<Vector2> pathList = new List<Vector2> { };
for (int i = 0; i < n; i++)
{
pathList.Add(new Vector2(vertices[i + n].x, vertices[i + n].y));
}
Vector2[] path = pathList.ToArray();
polyCollider.SetPath(0, path);
}
据我所知,这应该设置了两个网格,一个网格比另一个网格稍大。这项工作可行,但是尽管将两种不同的材质分配给了网格渲染器,但它们始终显示为相同的颜色。
这是网格在游戏中的显示方式:
这表明显然有两个网格:
我的网格渲染器如下:
这些是使用的材料:
我尝试在渲染器中简单地交换材质,但这只会使对象与其他材质成为单一材质。
经过进一步的实验,我想弄清楚这不是由Z角冲突引起的,我通过更改轮廓的z坐标并实时更改材质进行了实验,无论我做什么,它们都具有相同的材质出于某种原因。
答案 0 :(得分:0)
您的“轮廓”网格实际上是一个圆,而不是一个环。
因此,渲染整个事物时,轮廓和内部部分位于同一位置。如果您要移动相机,我怀疑您会看到Z-Fighting。
要正确渲染对象,您实际上需要为轮廓创建一个 ring 。
第二,您将两个“子网格”都粉碎成一个三角形数组:
List<int> trianglesList = new List<int> { };
List<int> OLtrianglesList = new List<int> { };
for (int i = 0; i < (n - 2); i++)
{
trianglesList.Add(0);
trianglesList.Add(i + 1);
trianglesList.Add(i + 2);
}
for (int i = 0; i < (n - 2); i++)
{
trianglesList.Add(n);
trianglesList.Add(i + n + 1);
trianglesList.Add(i + n + 2);
}
请注意,未使用OLtrianglesList
!
对于两个一组的折点使用一个列表可能都无济于事,或者:
for (int i = 0; i < n; i++)
{
x = radius * Mathf.Sin((2 * Mathf.PI * i) / n);
y = radius * Mathf.Cos((2 * Mathf.PI * i) / n);
verticesList.Add(new Vector3(x, y, 0f));
}
for (int i = 0; i < n; i++)
{
x = (radius + OLwidth) * Mathf.Sin((2 * Mathf.PI * i) / n);
y = (radius + OLwidth) * Mathf.Cos((2 * Mathf.PI * i) / n);
verticesList.Add(new Vector3(x, y, 0f));
}