- Home /
Problem Creating a 2D Mesh
I am trying to teach myself how to create custom meshes in Unity. I have started by trying to create a very simple 2d plane. So far I have managed to write some code that creates a 2x2 square, but when I try to increase the size of the plane (that is how many tiles comprise the plane) the compiler throws an index out of range exception. I haven't been programming for long and can't seem to understand why I can build a 2x2 mesh, but nothing larger or smaller. I'm new at this so there are probably a lot of mistakes. Any help would be greatly appreciated. Thanks.
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshCollider))]
public class TileMap : MonoBehaviour
{
//size of mesh in tiles
public int sizeX = 2;
public int sizeZ = 2;
//size of each tile
public float tileSize = 1.0f;
// Use this for initialization
void Start ()
{
BuildMesh();
}
void BuildMesh()
{
//declare mesh variables
int totalTiles = sizeX * sizeZ;
int totalTris = totalTiles * 2;
//vertices, uvs, and normals
int numVertsX = sizeX + 1;
int numVertsZ = sizeZ + 1;
int totalVerts = numVertsX * numVertsZ;
Vector3[] verts = new Vector3[totalVerts];
Vector3[] norms = new Vector3[totalVerts];
Vector2[] uvs = new Vector2[totalVerts];
//triangles
int[] tris = new int[totalTris * 3];
//generate mesh data
//vertices
for(int z = 0; z < numVertsZ; z++)
{
for(int x = 0; x < numVertsX; x++)
{
verts[z * numVertsX + x] = new Vector3(x * tileSize,0,z * tileSize);
norms[z * numVertsX + x] = Vector3.up;
}
}
//uvs
//no texture, just a simple red material
uvs[0] = new Vector2(0,0);
//triangles
int i = 0;
for(int z = 0; z < sizeZ; z++)
{
i = i + z;
for(int x = 0; x < sizeX; x++)
{
i = i + x;
tris[i] = (x * numVertsX) + z + 0;
tris[++i] = (x * numVertsX) + z + 3;
tris[++i] = (x * numVertsX) + z + 4;
tris[++i] = (x * numVertsX) + z + 4;
tris[++i] = (x * numVertsX) + z + 1;
tris[++i] = (x * numVertsX) + z + 0;
}
}
//create a new mesh
Mesh newMesh = new Mesh();
//assign mesh to filter/collider/renderer
MeshCollider meshCollider = GetComponent<MeshCollider>();
MeshFilter meshFilter = GetComponent<MeshFilter>();
MeshRenderer meshRenderer = GetComponent<MeshRenderer>();
meshFilter.mesh = newMesh;
//assign data to mesh
newMesh.vertices = verts;
newMesh.uv = uvs;
newMesh.normals = norms;
newMesh.triangles = tris;
}
}
Check out video 2 and 3 in this playlist : http://www.youtube.com/playlist?list=PLbghT7$$anonymous$$mckI4qGA0Wm_TZS8LVrqS47I9R
Here's my array calculations :
// public variable
var vertCount : Vector2 = new Vector2( 10, 10 );
// in function
var totalVerts : int = vertCount.x * vertCount.y;
verts = new Vector3[ totalVerts ];
uvs = new Vector2[ totalVerts ];
tris = new int[ (vertCount.x - 1) * (vertCount.y - 1) * 6 ];
norms = new Vector3[ totalVerts ];
I watched both those movies before I even started with my attempt. Sometimes when learning something new, one needs to hear the same thing from a number of different sources and expressed in a variety of ways before the brain can begin to make sense of it.
I tried replacing the relevant parts of my script with what you wrote and it doesn't work.
I need some explanation, not just some code (though the code is appreciated). I would also like to know why my script is throwing an index out of range exception when I increase the values of sizeX and sizeZ from 2 and why when I decrease the the values of sizeX and sizeZ to 1 the console says that it "failed setting triangles. Some indices are referencing out of bounds vertices." There is something wrong with my code, but I don't have the experience with this kind of coding, or perhaps coding in general, to identify it.
Thanks for trying to help.
Answer by wkiller · May 25, 2015 at 06:05 AM
In line 47, change to:
verts[z numVertsX + x] = new Vector3(x tileSize, z * tileSize);