简体   繁体   中英

The length of this integer array is 0?

I've been trying to create a plane mesh in Unity using code, and I've come across a very interesting problem. I created an int[] , filled it up with some values, and it's length is somehow zero. I've never encountered anything this quirky, so I'd enjoy a bit of help.

mesh.triangles = new int[]
{
    4, 6, 5, 5, 6, 7
};
... // Not important stuff
Debug.Log(mesh.triangles.Length);

I don't know what is happening, so I really haven't tried anything. But in the console, there is an error message stating Failed setting triangles. Some indices are referencing out of bounds vertices. IndexCount: 6, VertexCount: 4 Failed setting triangles. Some indices are referencing out of bounds vertices. IndexCount: 6, VertexCount: 4 Failed setting triangles. Some indices are referencing out of bounds vertices. IndexCount: 6, VertexCount: 4 .This is probably really important, but I don't understand some parts of the message(especially the last part). And if it makes a difference, I have an array concatenation method being called to add the first triangles to these ones. I initially identified this problem when the half of my mesh still wasn't appearing. I would really appreciate help; thanks.

Edit: To cut confusion, I'm just going to paste my whole entire method.

private void CreateQuad(ref Mesh mesh, Vector3 offset, bool first)
    {
        if (first)
        {
            mesh.vertices = new Vector3[]
            {
                Vector3.zero, Vector3.right, Vector3.forward, new Vector3(1, 0, 1)
            };
            mesh.triangles = new int[]
            {
                0, 2, 1, 1, 2, 3
            };
            mesh.normals = new Vector3[]
            {
                Vector3.back, Vector3.back, Vector3.back, Vector3.back
            };
            mesh.tangents = new Vector4[]
            {
                new Vector4(1, 0, 0, -1),
                new Vector4(1, 0, 0, -1),
                new Vector4(1, 0, 0, -1),
                new Vector4(1, 0, 0, -1)
            };
            mesh.uv = new Vector2[]
            {
                Vector2.zero, Vector2.right, Vector2.up, Vector2.one
            };
        }
        else if (!first)
        {
            mesh.vertices = new Vector3[]
            {
                Vector3.zero + offset,
                Vector3.right + offset,
                Vector3.forward + offset,
                new Vector3(1, 0, 1) + offset
            };
            mesh.triangles = new int[]
            {
                4, 6, 5, 5, 6, 7
            };
            mesh.normals = new Vector3[]
            {
                Vector3.back, Vector3.back, Vector3.back, Vector3.back
            };
            mesh.tangents = new Vector4[]
            {
                new Vector4(1, 0, 0, -1),
                new Vector4(1, 0, 0, -1),
                new Vector4(1, 0, 0, -1),
                new Vector4(1, 0, 0, -1)
            };
            mesh.uv = new Vector2[]
            {
                Vector2.zero, Vector2.right, Vector2.up, Vector2.one
            };
            Debug.Log(mesh.triangles.Length);
        }
    }

You first need to set the vertex array before altering the triangles. As Unity writes "It is recommended to assign a triangle array after assigning the vertex array, in order to avoid out of bounds errors."

mesh.vertices = new Vector3[] { new Vector3(-1,0,1), new Vector3(-1,0,-1),
    new Vector3(1,0,-1), new Vector3(1,0,1) };
mesh.triangles = new int[] {0,1,2,0,2,3};

You only have FOUR vertices!

mesh.vertices = new Vector3[]
{
    Vector3.zero + offset,
    Vector3.right + offset,
    Vector3.forward + offset,
    new Vector3(1, 0, 1) + offset
};

So the indices 4, 6, 5, 5, 6, 7 are all invalid ! If you have only four vertices you can maximum have the indices 0, 1, 2, 3

=> Unity simply rejects them all. You should have already taken that hint from the error you get

Failed setting triangles. Some indices are referencing out of bounds vertices . IndexCount: 6, VertexCount: 4


Now it is a bit unclear what exactly you are trying to achieve here but

  • either you want to REPLACE the vertices: In this case there is no reason to set new triangle instances etc at all! It is enough to connect them only once:

     private void CreateQuad(ref Mesh mesh, Vector3 offset, bool first) { if (first) { mesh.vertices = new Vector3[] { Vector3.zero, Vector3.right, Vector3.forward, new Vector3(1, 0, 1) }; mesh.triangles = new int[] { 0, 2, 1, 1, 2, 3 }; mesh.normals = new Vector3[] { Vector3.back, Vector3.back, Vector3.back, Vector3.back }; mesh.tangents = new Vector4[] { new Vector4(1, 0, 0, -1), new Vector4(1, 0, 0, -1), new Vector4(1, 0, 0, -1), new Vector4(1, 0, 0, -1) }; mesh.uv = new Vector2[] { Vector2.zero, Vector2.right, Vector2.up, Vector2.one }; } else if (!first) { mesh.vertices = new Vector3[] { Vector3.zero + offset, Vector3.right + offset, Vector3.forward + offset, new Vector3(1, 0, 1) + offset }; } }

    the other properties can simply be left untouched since you only want to update the vertex positions.

  • Or you actually wanted to ADD more faces. In that case you rather want to append to the existing arrays:

     private void CreateQuad(ref Mesh mesh, Vector3 offset, bool first) { if (first) { mesh.vertices = new Vector3[] { Vector3.zero, Vector3.right, Vector3.forward, new Vector3(1, 0, 1) }; mesh.triangles = new int[] { 0, 2, 1, 1, 2, 3 }; mesh.normals = new Vector3[] { Vector3.back, Vector3.back, Vector3.back, Vector3.back }; mesh.tangents = new Vector4[] { new Vector4(1, 0, 0, -1), new Vector4(1, 0, 0, -1), new Vector4(1, 0, 0, -1), new Vector4(1, 0, 0, -1) }; mesh.uv = new Vector2[] { Vector2.zero, Vector2.right, Vector2.up, Vector2.one }; } else if (!first) { // fist get already existing verts etc var oldVerts = mesh.vertices; var oldTris = mesh.triangles; // create new vertices and triangles arrays with additional space for the new quad var newVerts = new Vector3[oldVerts.Length + 4]; var newTris = new int[oldTris.Length + 6]; // copy over the existing vertices and triangles Array.Copy(oldVerts, newVerts, olVerts.Length); Array.Copy(oldTris, newtris, oldtris.Length); // then append the new vertices newVerts[oldverts.Length + 0] = Vector3.zero + offset; newVerts[oldverts.Length + 1] = Vector3.right + offset; newVerts[oldverts.Length + 2] = Vector3.forward + offset; newVerts[oldverts.Length + 3] = new Vector3(1, 0, 1) + offset; // append the new triangles newTris[oldTris.Length + 0] = oldverts.Length + 0; newTris[oldTris.Length + 1] = oldverts.Length + 2; newTris[oldTris.Length + 2] = oldverts.Length + 1; newTris[oldTris.Length + 3] = oldverts.Length + 1; newTris[oldTris.Length + 4] = oldverts.Length + 2; newTris[oldTris.Length + 5] = oldverts.Length + 3; // get the min and max points for filling the uvs (not the most efficient way probably but it is what it is ^^) // we later want to spread out the UV values linear between 0 (min) and 1 (max) on the given vertices var min = Vector3.zero; var max = Vector3.zero; foreach(var vertex in newVerts) { min = Vector3.Min(min, vertex); max = Vector3.Max(max, vertex); } // also fill new tangents and normals and uvs (if really necessary) var newNormals = new Vector3[newVerts.Length]; var newTangents = new Vector4[newVerts.Length]; var newUVs = new Vector2[newVerts.Length]; for(var i = 0; i < newVerts.Length; i++) { var vertex = newVerts[i]; newUVs[i] = new Vector2((vertex.x - min.x) / (max.x - min.x), (vertex.z - min.z) / (max.z - min.z)); newNormals[i] = Vector3.back; newTangents[i] = new Vector4(1, 0, 0, -1); }; // finally set them all back mesh.vertices = newVerts; mesh.triangles = newTris; mesh.normals = newNormals; mesh.tangents = newTangents; mesh.uv = newUs; } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM