子网格不会与其他材质一起出现Unity2D

时间:2018-06-20 20:25:27

标签: c# unity3d mesh

我有一些代码可以创建一个圆形网格,它需要一个半径,多个边(一个圆的边数大约为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坐标并实时更改材质进行了实验,无论我做什么,它们都具有相同的材质出于某种原因。

1 个答案:

答案 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));
}