- Home /
Procedural mesh redrawing textures causes in game fps drop. Is there a way to optimise this?
I have a procedural mesh drawing a grid of floor textures on in a 3D environment. The player can change the tiles by drawing on them. I am experiencing a significant drop in fps just doing the updating of the new textures. I know enough to understand that this is creating a lot of work, but not enough to understand how to optimise this. I added 2 boolean's that just flag instead of running the update in one whole chunk and this has helped out with about a 10% reduction in the lag it's all causing. Any help would be greatly appreciated. I feel that there should be a more efficient way to run the UpdateMesh as it feels like it's doing more work than it would need to, just to update the new floor tiles.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BuildGrid:MonoBehaviour {
public int floor = 0;
public bool buildPending = false;
public bool updatePending = false;
List<Vector3> newVertices = new List<Vector3>();
List<int> newTriangles = new List<int>();
List<Vector2> newUV = new List<Vector2>();
List<Vector3> colVertices = new List<Vector3>();
List<int> colTriangles = new List<int>();
int colCount;
Mesh mesh;
MeshCollider col;
float tUnit = 0.1f;
int squareCount;
void Start() {
mesh = GetComponent<MeshFilter>().mesh;
col = GetComponent<MeshCollider>();
buildPending = true;
}
void FixedUpdate() {
if(buildPending) {
buildPending = false;
BuildMesh();
}
if(updatePending) {
updatePending = false;
UpdateMesh();
}
}
void BuildMesh() {
for(int px = 0; px < FloorManager.Instance.width; px++) {
for(int py = 0; py < FloorManager.Instance.height; py++) {
GenCollider(px,py);
GenSquare(px,py,TextureMap(StoreManager.Instance.GetStoreColor(FloorManager.Instance.floorLayout[floor,px,py])));
}
}
updatePending = true;
}
void UpdateMesh() {
mesh.Clear();
mesh.vertices = newVertices.ToArray();
mesh.triangles = newTriangles.ToArray();
mesh.uv = newUV.ToArray();
mesh.RecalculateNormals();
newVertices.Clear();
newTriangles.Clear();
newUV.Clear();
squareCount = 0;
Mesh newMesh = new Mesh {
vertices = colVertices.ToArray(),
triangles = colTriangles.ToArray()
};
col.sharedMesh = newMesh;
colVertices.Clear();
colTriangles.Clear();
colCount = 0;
}
Vector2 TextureMap(int _number) {
return new Vector2((_number - (_number % 10)) / 10,_number % 10);
}
void GenCollider(int x,int y) {
colVertices.Add(new Vector3(x,0,y - 1));
colVertices.Add(new Vector3(x,0,y));
colVertices.Add(new Vector3(x + 1,0,y));
colVertices.Add(new Vector3(x + 1,0,y - 1));
ColliderTriangles();
colCount++;
}
void ColliderTriangles() {
colTriangles.Add(colCount * 4);
colTriangles.Add((colCount * 4) + 1);
colTriangles.Add((colCount * 4) + 3);
colTriangles.Add((colCount * 4) + 1);
colTriangles.Add((colCount * 4) + 2);
colTriangles.Add((colCount * 4) + 3);
}
void GenSquare(int x,int y,Vector2 texture) {
newVertices.Add(new Vector3(x,0,y));
newVertices.Add(new Vector3(x + 1.0f,0,y));
newVertices.Add(new Vector3(x + 1.0f,0,y - 1.0f));
newVertices.Add(new Vector3(x,0,y - 1.0f));
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 + 0.01f,tUnit * texture.y + tUnit - 0.01f));
newUV.Add(new Vector2(tUnit * texture.x + tUnit - 0.01f,tUnit * texture.y + tUnit - 0.01f));
newUV.Add(new Vector2(tUnit * texture.x + tUnit - 0.01f,tUnit * texture.y + 0.01f));
newUV.Add(new Vector2(tUnit * texture.x + 0.01f,tUnit * texture.y + 0.01f));
squareCount++;
}
}
Would breaking the following code into parts (like 0 to 9, then 10 to 19, etc) improve the performance?
void Build$$anonymous$$esh() {
for(int px = 0; px < Floor$$anonymous$$anager.Instance.width; px++) {
for(int py = 0; py < Floor$$anonymous$$anager.Instance.height; py++) {
GenCollider(px,py);
GenSquare(px,py,Texture$$anonymous$$ap(Store$$anonymous$$anager.Instance.GetStoreColor(Floor$$anonymous$$anager.Instance.floorLayout[floor,px,py])));
}
}
updatePending = true;
}