Currently, I handle the mesh data in my game with the following code:
Block class:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable()]
public class Block
{
public BlockType type;
public Block(BlockType type1)
{
type = type1;
}
public enum Direction { north, east, south, west, up, down };
[System.SerializableAttribute()]
public struct Tile { public int x; public int y;}
const float tileSize = 0.0625f;
public virtual MeshData Blockdata
(PlanetChunk planetchunk, int x, int y, int z, MeshData meshData)
{
meshData.useRenderDataForCol = true;
if (type != BlockTypes.typeEmpty)
{
if (!planetchunk.GetBlock(x, y + 1, z).IsSolid)
{
meshData = FaceDataUp(planetchunk, x, y, z, meshData);
}
if (!planetchunk.GetBlock(x, y - 1, z).IsSolid)
{
meshData = FaceDataDown(planetchunk, x, y, z, meshData);
}
if (!planetchunk.GetBlock(x, y, z + 1).IsSolid)
{
meshData = FaceDataNorth(planetchunk, x, y, z, meshData);
}
if (!planetchunk.GetBlock(x, y, z - 1).IsSolid)
{
meshData = FaceDataSouth(planetchunk, x, y, z, meshData);
}
if (!planetchunk.GetBlock(x + 1, y, z).IsSolid)
{
meshData = FaceDataEast(planetchunk, x, y, z, meshData);
}
if (!planetchunk.GetBlock(x - 1, y, z).IsSolid)
{
meshData = FaceDataWest(planetchunk, x, y, z, meshData);
}
if (type.light == true)
{
if (planetchunk.GetBlock(x - 1, y, z).IsSolid == false || planetchunk.GetBlock(x + 1, y, z).IsSolid == false || planetchunk.GetBlock(x, y, z - 1).IsSolid == false ||
planetchunk.GetBlock(x, y, z + 1).IsSolid == false || planetchunk.GetBlock(x, y - 1, z).IsSolid == false || planetchunk.GetBlock(x, y + 1, z).IsSolid == false)
{
meshData.AddLight(x, y, z, type.LR, type.LG, type.LB, type.LA, type.LightRange, type.LightIntensity);
}
}
return meshData;
}
return meshData;
}
protected virtual MeshData FaceDataUp
(PlanetChunk planetchunk, int x, int y, int z, MeshData meshData)
{
meshData.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z + 0.5f));
meshData.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f));
meshData.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z - 0.5f));
meshData.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z - 0.5f));
meshData.AddQuadTriangles();
meshData.uv.AddRange(FaceUVs(Direction.up));
return meshData;
}
protected virtual MeshData FaceDataDown
(PlanetChunk planetchunk, int x, int y, int z, MeshData meshData)
{
meshData.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z - 0.5f));
meshData.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z - 0.5f));
meshData.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z + 0.5f));
meshData.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z + 0.5f));
meshData.AddQuadTriangles();
meshData.uv.AddRange(FaceUVs(Direction.down));
return meshData;
}
protected virtual MeshData FaceDataNorth
(PlanetChunk planetchunk, int x, int y, int z, MeshData meshData)
{
meshData.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z + 0.5f));
meshData.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f));
meshData.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z + 0.5f));
meshData.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z + 0.5f));
meshData.AddQuadTriangles();
meshData.uv.AddRange(FaceUVs(Direction.north));
return meshData;
}
protected virtual MeshData FaceDataEast
(PlanetChunk planetchunk, int x, int y, int z, MeshData meshData)
{
meshData.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z - 0.5f));
meshData.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z - 0.5f));
meshData.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z + 0.5f));
meshData.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z + 0.5f));
meshData.AddQuadTriangles();
meshData.uv.AddRange(FaceUVs(Direction.east));
return meshData;
}
protected virtual MeshData FaceDataSouth
(PlanetChunk planetchunk, int x, int y, int z, MeshData meshData)
{
meshData.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z - 0.5f));
meshData.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z - 0.5f));
meshData.AddVertex(new Vector3(x + 0.5f, y + 0.5f, z - 0.5f));
meshData.AddVertex(new Vector3(x + 0.5f, y - 0.5f, z - 0.5f));
meshData.AddQuadTriangles();
meshData.uv.AddRange(FaceUVs(Direction.south));
return meshData;
}
protected virtual MeshData FaceDataWest
(PlanetChunk planetchunk, int x, int y, int z, MeshData meshData)
{
meshData.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z + 0.5f));
meshData.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z + 0.5f));
meshData.AddVertex(new Vector3(x - 0.5f, y + 0.5f, z - 0.5f));
meshData.AddVertex(new Vector3(x - 0.5f, y - 0.5f, z - 0.5f));
meshData.AddQuadTriangles();
meshData.uv.AddRange(FaceUVs(Direction.west));
return meshData;
}
public virtual Vector2[] FaceUVs(Direction direction)
{
Vector2[] UVs = new Vector2[4];
Tile tilePos = type.tile;
UVs[0] = new Vector2(tileSize * tilePos.x + tileSize,
tileSize * tilePos.y);
UVs[1] = new Vector2(tileSize * tilePos.x + tileSize,
tileSize * tilePos.y + tileSize);
UVs[2] = new Vector2(tileSize * tilePos.x,
tileSize * tilePos.y + tileSize);
UVs[3] = new Vector2(tileSize * tilePos.x,
tileSize * tilePos.y);
return UVs;
}
?}
MeshData:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MeshData
{
public List<Vector3> vertices = new List<Vector3>();
public List<int> triangles = new List<int>();
public List<Vector2> uv = new List<Vector2>();
public List<Vector3> colVertices = new List<Vector3>();
public List<int> colTriangles = new List<int>();
public Color32[,,] lightcolors = new Color32[localVars.chunklength, localVars.chunklength, localVars.chunklength];
public float[,,] lightintensity = new float[localVars.chunklength, localVars.chunklength, localVars.chunklength];
public float[,,] lightrange = new float[localVars.chunklength, localVars.chunklength, localVars.chunklength];
public List<Vector3> lightpositions = new List<Vector3>(localVars.chunklength * localVars.chunklength * localVars.chunklength);
public bool useRenderDataForCol;
public void AddQuadTriangles()
{
triangles.Add(vertices.Count - 4);
triangles.Add(vertices.Count - 3);
triangles.Add(vertices.Count - 2);
triangles.Add(vertices.Count - 4);
triangles.Add(vertices.Count - 2);
triangles.Add(vertices.Count - 1);
if (useRenderDataForCol)
{
colTriangles.Add(colVertices.Count - 4);
colTriangles.Add(colVertices.Count - 3);
colTriangles.Add(colVertices.Count - 2);
colTriangles.Add(colVertices.Count - 4);
colTriangles.Add(colVertices.Count - 2);
colTriangles.Add(colVertices.Count - 1);
}
}
public void AddVertex(Vector3 vertex)
{
vertices.Add(vertex);
if (useRenderDataForCol)
{
colVertices.Add(vertex);
}
}
public void AddTriangle(int tri)
{
triangles.Add(tri);
if (useRenderDataForCol)
{
colTriangles.Add(tri - (vertices.Count - colVertices.Count));
}
}
public void AddLight (int x, int y, int z, byte R, byte G, byte B, byte A, float range, float intensity)
{
lightcolors[x, y, z] = new Color32(R, G, B, A);
lightintensity[x, y, z] = intensity;
lightrange[x, y, z] = range;
lightpositions.Add(new Vector3(x, y, z));
}
public void Clear()
{
vertices.Clear();
triangles.Clear();
uv.Clear();
colVertices.Clear();
colTriangles.Clear();
lightcolors = new Color32[16, 16, 16];
lightintensity = new float[16, 16, 16];
lightrange = new float[16, 16, 16];
lightpositions.Clear();
}
}
And Rendering:
// Sends the calculated mesh information
// to the mesh and collision components
void RenderMesh()
{
filter.mesh.Clear();
filter.mesh.vertices = meshData.vertices.ToArray();
filter.mesh.triangles = meshData.triangles.ToArray();
filter.mesh.uv = meshData.uv.ToArray();
filter.mesh.RecalculateNormals();
meshnew.Clear();
meshnew.vertices = meshData.colVertices.ToArray();
meshnew.triangles = meshData.colTriangles.ToArray();
foreach (Vector3 position in meshData.lightpositions)
{
int x = (int)position.x;
int y = (int)position.y;
int z = (int)position.z;
if (lights[x, y, z] == null)
{
Color32 color = meshData.lightcolors[x, y, z]; //Optimize lights later
float intensity = meshData.lightintensity[x, y, z];
float range = meshData.lightrange[x, y, z];
GameObject light = new GameObject("Light " + x + " " + y + " " + z);
Light lightComp = light.AddComponent<Light>();
lightComp.color = color;
lightComp.intensity = intensity;
lightComp.range = range;
light.transform.parent = this.transform;
light.transform.localPosition = new Vector3(x, y, z);
lights[x, y, z] = light;
}
}
meshnew.RecalculateNormals();
coll.sharedMesh = meshnew;
}
Problem: MeshData uses lists, and when the mesh is updated... yep, so are the lists. Clearing the lists create quite a bit of garbage. I wanted to know if there's a way I should be doing this that would be less garbage-prone. Thanks.