- Home /
Optimizing Procedural terrain
I am making a voxel game in unity and all mi faces are culled correctly and it is still really laggy when i generate a new chunk i think this problem is its trying to generate a chunk instantly and it cant do that it needs to take as much time as it needs to do this kinda like a loading screen but i cant figure out how to do this.
Show us your code for generating the new block. Chances are you're doing it a very clunky / cloggy way that can be remedied.
Answer by flaviusxvii · Oct 03, 2013 at 03:33 PM
CreateVisualMesh needs:
yield return new WaitForSeconds(0.001f);
every so often. Maybe at line 64. This will let it generate some stuff, and then it'll yield to the render loop, and then it can come back and continue until it is done.
Good answer, it will eli$$anonymous$$ate the lag from a for(x ^ y ^ z) computation.
were would you suggest i put this i try'd in different places and they did't work.i try'd at the end of the loops and before and after mesh rendering ,before collision and all these did't work. but thanks for all the help
Answer by ProgramYourFace · Oct 03, 2013 at 03:26 PM
this is what i do for instantiating the chunks.
for (float x = transform.position.x - viewSize; x < transform.position.x + viewSize; x+= Chunk.width)
{
for (float z = transform.position.z - viewSize; z < transform.position.z + viewSize; z+= Chunk.width)
{
Vector3 pos = new Vector3(x, 0, z);
pos.x = Mathf.Floor(pos.x / (float)Chunk.width) * Chunk.width;
pos.z = Mathf.Floor(pos.z / (float)Chunk.width) * Chunk.width;
Chunk chunk = Chunk.FindChunk(pos);
if (chunk != null) continue;
chunk = (Chunk)Instantiate(chunkFab, pos, Quaternion.identity);
}
}
and this is what i use for creating a visual mesh
public virtual IEnumerator CreateVisualMesh() {
visualMesh = new Mesh();
List<Vector3> verts = new List<Vector3>();
List<Vector2> uvs = new List<Vector2>();
List<int> tris = new List<int>();
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
for (int z = 0; z < width; z++)
{
if (map[x,y,z] == 0) continue;
byte block = GetByte(x,y,z);
Vector3 start = new Vector3(x, y, z);
Vector3 offset1, offset2;
if (IsTransparent(x, y - 1, z))
{
offset1 = Vector3.left;
offset2 = Vector3.back;
DrawFace(start + Vector3.right, offset1, offset2, block,verts,uvs,tris);
}
if (IsTransparent(x, y + 1, z))
{
offset1 = Vector3.right;
offset2 = Vector3.back;
DrawFace(start + Vector3.up, offset1, offset2, block,verts,uvs,tris);
}
if (IsTransparent(x - 1, y, z))
{
offset1 = Vector3.back;
offset2 = Vector3.down;
DrawFace(start + Vector3.up, offset1, offset2, block,verts,uvs,tris);
}
if (IsTransparent(x + 1, y, z))
{
offset1 = Vector3.forward;
offset2 = Vector3.down;
DrawFace(start + Vector3.right + Vector3.up + Vector3.back, offset1, offset2, block,verts,uvs,tris);
}
if (IsTransparent(x, y, z - 1))
{
offset1 = Vector3.right;
offset2 = Vector3.down;
DrawFace(start + Vector3.back + Vector3.up, offset1, offset2, block,verts,uvs,tris);
}
if (IsTransparent(x, y, z + 1))
{
offset1 = Vector3.left;
offset2 = Vector3.down;
DrawFace(start + Vector3.up + Vector3.right, offset1, offset2, block,verts,uvs,tris);
}
}
}
}
visualMesh.vertices = verts.ToArray();
visualMesh.uv = uvs.ToArray();
visualMesh.triangles = tris.ToArray();
visualMesh.RecalculateBounds();
visualMesh.RecalculateNormals();
meshFilter.mesh = visualMesh;
meshCollider.sharedMesh = visualMesh;
yield return 0;
}
public void DrawFace(Vector3 start, Vector3 offset1, Vector3 offset2, byte block,List<Vector3> verts, List<Vector2> uv, List<int> tris)
{
Terrain terrain = Terrain.activeTerrain;
int index = verts.Count;
BlockType blockType = Terrain.blocks.GetBlock(block);
float zoom = 0.0625F;
Vector2 uvBase = blockType.uv;
if(blockType.sideTexture == true)
{
if ((offset2 == Vector3.down))
{
uvBase = blockType.side;
}
}
if(blockType.bottomTexture == true)
{
if (!(offset2 == Vector3.down) && !(offset1 == Vector3.right))
{
uvBase = blockType.bottom;
}
}
uv.Add(uvBase);
uv.Add(uvBase + new Vector2(-zoom , 0F));
uv.Add(uvBase + new Vector2(0F , zoom));
uv.Add(uvBase + new Vector2(-zoom , zoom));
verts.Add (start);
verts.Add (start + offset1);
verts.Add (start + offset2);
verts.Add (start + offset1 + offset2);
tris.Add (index + 0);
tris.Add (index + 1);
tris.Add (index + 2);
tris.Add (index + 3);
tris.Add (index + 2);
tris.Add (index + 1);
}
Your answer
Follow this Question
Related Questions
Loading prefabs to prevent a lag during play 3 Answers
Performance issues when loading first scene 1 Answer
optimizing load scene 0 Answers
How to instantiate prefabs in an unloaded (or just loaded) scene? 1 Answer
How to make a loading screen? 2 Answers