Domanda

I'm creating a plane using C# in unity and I've gotten it "working" I get a plane. However the triangles don't seem to be connecting correctly, and I can't work out why.

As you can see by that picture, it explains it better than I can.

I believe the issue is just with my indices, though I'm not sure.

I think there may also be one triangle that isn't there also, so I think my array is to small for some reason also.

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;
}
È stato utile?

Soluzione

You compute uvx this way:

float uvx = 1.0f/width;

Then you cycle over the width this way:

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

If you look close, there are 2 bugs:

  • j is multiplied by uvx but it cycles from 0 to depth (shouldn't that be width?);
  • you need to cycle up to width or depth included (using <= width or < width + 1).

These are just the UV coordinates, don't keep the vertices in that loop. It won't solve your problem but just those 2 bugs you will notice later on.

To solve the triangle problem try this:

0 +--+ 2     + 2
  | /       /|
  |/       / |
1 +     1 +--+ 3

0 -> 1 -> 2
2 -> 1 -> 3

It's important you order them counter-clockwise for backface culling to work correctly. You may use any other order, there are some very clever solutions that switch the diagonal and keep adjacency, which is required for older hardware that optimized mesh buffers. Newer hardware will do those optimizations on the fly and not require you to do that math.

Order the triangles in the triangle buffer as shown above:

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;

At this point all you have to do is position the vertices correctly. You posted this:

vertecies[index] = new Vector3(i,0,-j);

Instead you should do this in a separate loop:

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

I also see you swap y and z, this will cause headaches. Also, you inverted the direction of j in respect to the world space coordinates.

I advise you to rethink it, to correctly position the camera and to adopt the standard way of labeling coordinates. It will simplify enormously thinking about space later on.

If the camera looks towars -Z then the vertices should be computed this way, instead:

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

PLEASE NOTE: this is not trivial code. Minor mistakes (some + or - sign or +1/-1 missing somewhere) are more than possible and you should correct them accordingly. This all should give you a better view on the problem but ultimately you will have to run and debug it until it works correctly.

Altri suggerimenti

I would suggest trying to use the built in functions of Unity when possible, but in case that doesn't work for you, this script should do what you need without a ton of extra effort: http://wiki.unity3d.com/index.php?title=CreatePlane&oldid=10448.

If you want to stick with your code, the above answer covers the issues with your posted code.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top