So, I have a procedural mesh generation system with chunks that load in and generate as the player walks into a nearby cell, and get removed when the player walks out. When each set of 9 cells is getting generated, this takes around 1500 ms. When they are being generated, the game thus freezes. Is there a way to make the game NOT freeze and allow the player to continue doing things in their current chunk while the area is being generated? Like having the terrain gen happening in the background? EDIT- From @DmGregory- the ob struct seems like it would work, but I am a bit confused as to whether or not I can include all of mymesh geneartion and update function in it,or if I need to find a way to pass out the mesh and verts from the job. What is the best way to do this?
I haven't fully started writing code in the struct as i am unsure of where to begin in terms of the mesh update system. Essentially, my code is as follows- In a for loop, it generates vertices, and for every one of these vertices, it uses a noise function to generate height. It then enters another for loop that connects the verts together via triangles. Without the noise function, it essentially forms a plane. The noise function is almost certainly the culprit for the lag, as it gets repeated 65025 times per chunk. I do want to convert the entire gen function into a job, however.
EDIT 2- I am using the coroutine system suggested by @DMGregory, and so have written my coroutine mesh gen as such. It is a combination of my update mesh and mesh generation methods. This now DOES NOT freeze the game, but fails to generate the mesh at all, however, the game is smooth. This is what the code looks like for the co-routine-
IEnumerator meshGen(){
vertices = new Vector3[(xSize + 1) * (zSize + 1)];
for (int i=0, z = 0; z <= zSize; z++){
for(int x = 0; x <= xSize; x++){
vertices[i] = new Vector3(x, generateNoise(x, z), z);
i++;
yield return null;
}
}
triangles = new int[6 * xSize * zSize];
int vert = 0;
int tris = 0;
for( int z = 0; z < zSize; z ++){
for(int x = 0; x < xSize; x++)
{
triangles[0 + tris] = vert + 0;
triangles[1 + tris] = vert + xSize + 1;
triangles[2 + tris] = vert + 1;
triangles[3 + tris] = vert + 1;
triangles[4 + tris] = vert + xSize + 1;
triangles[5 + tris] = vert + xSize + 2;
vert ++;
tris +=6;
}
vert ++;
}
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateNormals();
}
And this is what the code looks like for the generateNoie(x, z) function-
float generateNoise(float x, float z){
//float k = (-1 * noise.Evaluate(new Vector3(x * 0.01f, 0, z * 0.01f)));
float k = (-1 * evalNoise(x, z, 0.01f));
k = Mathf.Pow(k, 2);
// float ty = Mathf.Clamp(1 - Mathf.Abs(noise.Evaluate(new Vector3(x * 0.015f, 0, z * 0.015f))), 0, 1);
float ty = Mathf.Clamp(1 - Mathf.Abs(evalNoise(x, z, 0.015f)), 0, 1);
//float y = (1 - Mathf.Abs(noise.Evaluate(new Vector3(x * 0.03f, 0, z * 0.03f)))) * 5f + 5f;
float y = (1 - Mathf.Abs(evalNoise(x, z, 0.03f))) * 5f + 5f;
y*= ty;
y *= k;
y -= (1 - k) * 1;
float freq = 1;
float ampl = 1;
if(y > CutOffHeight && y < maxCutOffHeight){
for(int i =1; i <= octaves; i++){
freq *= 2;
ampl *= 0.5f;
//y += noise.Evaluate(new Vector3((x * freq),0, (z*freq)/octaves)) * (ty * 2) * k * ampl;
y += evalNoise(x,z, freq) * (ty * 2) * k * ampl;
//print(i);
}
}
// y -= 1- Mathf.Abs(noise.Evaluate(new Vector3(x * 0.05f, 0, z * 0.05f))) * ty;
y -= 1- Mathf.Abs(evalNoise(x,z,0.05f)) * ty;
//float uy = Mathf.Clamp(Mathf.Pow(noise.Evaluate(new Vector3(x * 0.01f, 0, z * 0.01f)), 2), 0, 1);
float uy = Mathf.Clamp(Mathf.Pow(evalNoise(x,z,0.01f), 2), 0, 1);
y+= uy;
y -= ty;
y *= 2f;
float r = evalNoise(x,z, 0.002f);
y *= 1- Mathf.Clamp(Mathf.Pow(r, 3), 0, 1);
if(y <= IslandHeight){
float tempGrad = Mathf.Abs(y - IslandHeight);
y -= Mathf.Abs(tempGrad);
}
return y;
}