I am currently developing a simple city builder to further enhance my skills with Unity3D. Unfortunately, I face the dilemma of creating a tile map for building placement(snap to grid, well you could cast position to integer to snap to 1.0fx1.0f tiles), controlling citizen movement speed , collisions etc.
Currently I have a series of tile prefabs(cubes with scripts) instantiated in unity based on a 3D array of the x,z coordinates and height (y). Apparently using too many game objects can pose a problem(tons of lag) in say a map of 1000x1000 tiles. There are two solutions to the problem as I am aware(i think).
**(1) Render a Mesh **
I made a mesh for the first time however, building the mesh is fine but how do I select a tile? I have my tile class with the various properties which I want to apply to the mesh squares (the 2 triangles). The question is how would I use a mesh to build a 3D tilemap for modifying each tile/selecting/accessing etc.
(2) Split a Terrain
I was searching google how to make an efficient 3D grid map and I found some questions on unity3D questions about splitting a terrain into a grid and using it for rts/citybuilder type games.
Perhaps one of you guys can recommend another method or clarify how to accomplish my goal?
Thanks!
EDIT::BELOW
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MeshMap : MonoBehaviour
{
public float[,] tiles;
List<Vector3> newVertices = new List<Vector3>();
List<int> newTriangles = new List<int>();
List<Vector2> newUV = new List<Vector2>();
private Mesh mesh;
private float tUnit = 0.25f;
private Vector2 tStone = new Vector2(1, 0);
private Vector2 tGrass = new Vector2(0, 1);
private int squareCount;
void Start()
{
GenerateTerrain();
BuildMesh();
UpdateMesh();
}
void Update()
{
UpdateMesh();
}
void GenerateSquare(int x, float y, int z, Vector2 texture)
{
newVertices.Add(new Vector3(x, y, z));
newVertices.Add(new Vector3(x, y, z + 1));
newVertices.Add(new Vector3(x + 1, y, z + 1));
newVertices.Add(new Vector3(x + 1, y, z));
newTriangles.Add(squareCount * 4);
newTriangles.Add((squareCount * 4) + 1);
newTriangles.Add((squareCount * 4) + 3);
newTriangles.Add((squareCount * 4) + 1);
newTriangles.Add((squareCount * 4) + 2);
newTriangles.Add((squareCount * 4) + 3);
newUV.Add(new Vector2(tUnit * texture.x, tUnit * texture.y + tUnit));
newUV.Add(new Vector2(tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
newUV.Add(new Vector2(tUnit * texture.x + tUnit, tUnit * texture.y));
newUV.Add(new Vector2(tUnit * texture.x, tUnit * texture.y));
squareCount++;
}
void GenerateTerrain()
{
tiles = new float[100,100];
for(int z = 0; z < tiles.GetLength(0); z++)
{
for (int x = 0; x < tiles.GetLength(1); x++)
{
tiles[z,x] = Mathf.PerlinNoise(x, z);
}
}
}
void BuildMesh()
{
for (int z = 0; z < tiles.GetLength(0); z++)
{
for (int x = 0; x < tiles.GetLength(1); x++)
{
GenerateSquare(x, tiles[z,x], z, tStone);
}
}
}
void UpdateMesh()
{
mesh = GetComponent<MeshFilter>().mesh;
mesh.Clear();
mesh.vertices = newVertices.ToArray();
mesh.triangles = newTriangles.ToArray();
mesh.uv = newUV.ToArray();
mesh.Optimize();
mesh.RecalculateNormals();
squareCount = 0;
newVertices.Clear();
newTriangles.Clear();
newUV.Clear();
}
}