3
\$\begingroup\$

I'm in the beginning stages of an RTS game in Unity. I have a procedurally generated terrain with a Perlin noise height map, as well as a function to generate a river. The problem is that the graphical creation of the map is taking the data structure of the map and rotating it by 180 degrees.

I noticed this problem when I was creating my rivers. I would set the river's height to flat, and noticed that the actual tiles that were flat in the graphical representation were flipped and mirrored.

Here are some screenshots of the map from different angles:

enter image description here

enter image description here

enter image description here

As you can see, if you flipped (graphically) the river by 180 degrees on the Z axis, it would fit where the terrain is flattened. I have a suspicion it is being caused by a misunderstanding on my part of how vertices work.

This code here creates a new array of Tile objects, which hold the information for each tile, including its type, coordinate, height, and it's vertices:

public DTileMap (int size_x, int size_y)
{
    this.size_x = size_x;
    this.size_y = size_y;
    //Initialize Map_Data Array of Tile Objects
    map_data = new Tile[size_x, size_y];
    for (int j = 0; j < size_y; j++) {
        for (int i = 0; i < size_x; i++) {
            map_data [i, j] = new Tile ();
            map_data[i,j].coordinate.x = (int)i;
            map_data[i,j].coordinate.y = (int)j;

            map_data[i,j].vertices[0] = new Vector3 (i * GTileMap.TileMap.tileSize, map_data[i,j].Height, -j * GTileMap.TileMap.tileSize);
            map_data[i,j].vertices[1] = new Vector3 ((i+1) * GTileMap.TileMap.tileSize, map_data[i,j].Height, -(j) * GTileMap.TileMap.tileSize);
            map_data[i,j].vertices[2] = new Vector3 (i * GTileMap.TileMap.tileSize, map_data[i,j].Height, -(j-1) * GTileMap.TileMap.tileSize);
            map_data[i,j].vertices[3] = new Vector3 ((i+1) * GTileMap.TileMap.tileSize, map_data[i,j].Height, -(j-1) * GTileMap.TileMap.tileSize);
        }
    }

}

This code sets the river tiles to height 0:

foreach (Tile t in map_data)
{
    if (t.realType == "Water")
    {
        t.vertices[0].y = 0f;
        t.vertices[1].y = 0f;
        t.vertices[2].y = 0f;
        t.vertices[3].y = 0f;
    }
}

Finally, below is the code to generate the actual graphics from the data:

public void BuildMesh ()
{
    DTileMap.DTileMap map = new DTileMap.DTileMap (size_x, size_z);
    int numTiles = size_x * size_z;
    int numTris = numTiles * 2;

    int vsize_x = size_x + 1;
    int vsize_z = size_z + 1;
    int numVerts = vsize_x * vsize_z;

    // Generate the mesh data
    Vector3[] vertices = new Vector3[ numVerts ];
    Vector3[] normals = new Vector3[numVerts];
    Vector2[] uv = new Vector2[numVerts];

    int[] triangles = new int[ numTris * 3 ];

    int x, z;
    for (z=0; z < vsize_z; z++) {
        for (x=0; x < vsize_x; x++) {
            normals [z * vsize_x + x] = Vector3.up;
            uv [z * vsize_x + x] = new Vector2 ((float)x / size_x, 1f - (float)z / size_z);
        }
    }
    for (z=0; z < vsize_z; z+=1) {
        for (x=0; x < vsize_x; x+=1) {
            if (x == vsize_x - 1 && z == vsize_z - 1) {
                vertices [z * vsize_x + x] = DTileMap.DTileMap.map_data [x - 1, z - 1].vertices [3];
            } else if (z == vsize_z - 1) {
                vertices [z * vsize_x + x] = DTileMap.DTileMap.map_data [x, z - 1].vertices [2];
            } else if (x == vsize_x - 1) {
                vertices [z * vsize_x + x] = DTileMap.DTileMap.map_data [x - 1, z].vertices [1];
            } else {
                vertices [z * vsize_x + x] = DTileMap.DTileMap.map_data [x, z].vertices [0];
                vertices [z * vsize_x + x+1] = DTileMap.DTileMap.map_data [x, z].vertices [1];
                vertices [(z+1) * vsize_x + x] = DTileMap.DTileMap.map_data [x, z].vertices [2];
                vertices [(z+1) * vsize_x + x+1] = DTileMap.DTileMap.map_data [x, z].vertices [3];

            }

        }
    }

    for (z=0; z < size_z; z++) {
        for (x=0; x < size_x; x++) {
            int squareIndex = z * size_x + x;
            int triOffset = squareIndex * 6;
            triangles [triOffset + 0] = z * vsize_x + x + 0;
            triangles [triOffset + 2] = z * vsize_x + x + vsize_x + 0;
            triangles [triOffset + 1] = z * vsize_x + x + vsize_x + 1;

            triangles [triOffset + 3] = z * vsize_x + x + 0;
            triangles [triOffset + 5] = z * vsize_x + x + vsize_x + 1;
            triangles [triOffset + 4] = z * vsize_x + x + 1;
        }
    }

    // Create a new Mesh and populate with the data
    Mesh mesh = new Mesh ();
    mesh.vertices = vertices;
    mesh.triangles = triangles;
    mesh.normals = normals;
    mesh.uv = uv;

    // Assign our mesh to our filter/renderer/collider
    MeshFilter mesh_filter = GetComponent<MeshFilter> ();
    MeshCollider mesh_collider = GetComponent<MeshCollider> ();

    mesh_filter.mesh = mesh;
    mesh_collider.sharedMesh = mesh;

    calculateMeshTangents (mesh);
    BuildTexture (map);
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Have you considered the texture being mirrored and not the terrain? You should build your texture data at the same time you build your terrain mesh. This is kind of a "debug my code type question" typically these aren't looked upon very well. Since we like people to understand their own code before asking questions, these type of questions make is seem as though you're just looking for someone to write your code for you. Just letting you know for future questions. \$\endgroup\$ – MichaelHouse Nov 8 '13 at 14:27
  • \$\begingroup\$ My apologies for the type of question. It was mostly a question on how meshes work. Your suggestion was actually correct. The texture's coordinates are different than the meshes coordinates. I wish they would just keep it consistent! Thank you for the help! \$\endgroup\$ – Steve Nov 8 '13 at 23:06
2
\$\begingroup\$

As discussed in the comments, it appears that your texture coordinates were mirrored and not your terrain. When building the mesh from your data structure, it's a good idea to build the the texture coordinates at the same time. This makes the code a bit more readable and helps prevent issues like this.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.