- Home /
Combing Meshes not working as expected?
I'm working on a Uni project where I use 3d noise to create terrain. I'm currently trying to speed up my meshes by combining them using mesh.CombineMeshes. I created one script that uses a lot of .AddComponent and .GetComponent which is obviously quite slow but works. The code for which is:
private void CreateMesh()
{
int meshCount = 0;
List<MeshFilter> meshFilters = new List<MeshFilter>();
for (int i = 0; i < chunkWidth; i++) //x
{
for (int j = 0; j < chunkHeight; j++) //y
{
for (int k = 0; k < chunkWidth; k++) //z
{
if (_thisChunk.ChunkData[i, j, k] > threshold)
{
List<Direction> dirs = new List<Direction>();
for (int l = 0; l < 6; l++)
{
if (!GetIfNeighbour(new Vector3(i, j, k), (Direction) l))
{
dirs.Add((Direction) l);
}
}
if (dirs.Count > 0)
{
GameObject terrainObj = CreateTerrainFace(
new Vector3(_thisChunk.chunkPos.x + i, j, _thisChunk.chunkPos.y + k),
dirs);
meshFilters.Add(terrainObj.GetComponent<MeshFilter>());
meshCount++;
Destroy(terrainObj);
}
}
}
}
}
CombineInstance[] combine = new CombineInstance[meshCount];
int count = 0;
foreach (var meshsF in meshFilters)
{
combine[count].mesh = meshsF.sharedMesh;
combine[count].transform = meshsF.transform.localToWorldMatrix;
count++;
}
MeshFilter tempFilter = new MeshFilter();
tempFilter = _thisChunk.gameObject.AddComponent<MeshFilter>();
tempFilter.mesh = new Mesh();
tempFilter.mesh.CombineMeshes(combine);
_thisChunk.gameObject.GetComponent<MeshFilter>().mesh = tempFilter.mesh;
_thisChunk.gameObject.AddComponent<MeshRenderer>().material = basicMat;
_thisChunk.firstBlockInChunk = true;
_thisChunk.isRendered = true;
}
private GameObject CreateTerrainFace(Vector3 pos, List<Direction> dirs)
{
GameObject terrainObj = new GameObject(pos.ToString());
MeshFilter[] meshFilters = new MeshFilter[6];
terrainObj.AddComponent<MeshFilter>().mesh = new Mesh();
CombineInstance[] CombineMeshes = new CombineInstance[6];
int meshCount = 0;
foreach (var dir in dirs)
{
Mesh mesh = new Mesh();
mesh.vertices = _planes[(int) dir].vertices;
mesh.triangles = _planes[(int) dir].planeTriangles;
mesh.uv = _planes[(int) dir].uvs;
mesh.RecalculateNormals();
GameObject meshObj = new GameObject(dir.ToString());
meshObj.AddComponent<MeshFilter>().mesh = mesh;
meshFilters[meshCount] = meshObj.GetComponent<MeshFilter>();
Destroy(meshObj);
//meshObj.transform.SetParent(terrainObj.transform);
meshCount++;
}
//meshFilters = terrainObj.GetComponentsInChildren<MeshFilter>();
for (int i = 0; i < meshCount; i++)
{
CombineMeshes[i].mesh = meshFilters[i].sharedMesh;
CombineMeshes[i].transform = meshFilters[i].transform.localToWorldMatrix;
}
MeshFilter tempFilter = new MeshFilter();
tempFilter = terrainObj.transform.GetComponent<MeshFilter>();
tempFilter.mesh = new Mesh();
tempFilter.mesh.CombineMeshes(CombineMeshes);
terrainObj.GetComponent<MeshFilter>().mesh = tempFilter.mesh;
terrainObj.AddComponent<MeshRenderer>().material = basicMat;
terrainObj.transform.position = pos;
terrainObj.transform.eulerAngles = new Vector3(0, -90, 0);
terrainObj.transform.SetParent(_thisChunk.transform);
return terrainObj;
//_thisChunk.blockList.Add(terrainObj);
}
This produces a result that looks like this:
My "improved" script looks like this:
private void CreateCombinedMesh()
{
int meshCount = 0;
List<Mesh> meshFilters = new List<Mesh>();
for (int i = 0; i < chunkWidth; i++) //x
{
for (int j = 0; j < chunkHeight; j++) //y
{
for (int k = 0; k < chunkWidth; k++) //z
{
if (_thisChunk.ChunkData[i, j, k] > threshold)
{
List<Direction> dirs = new List<Direction>();
for (int l = 0; l < 6; l++)
{
if (!GetIfNeighbour(new Vector3(i, j, k), (Direction) l))
{
dirs.Add((Direction) l);
}
}
if (dirs.Count > 0)
{
meshFilters.Add(CreateCombinedTerrain(
new Vector3(_thisChunk.chunkPos.x + i, j, _thisChunk.chunkPos.y + k),
dirs));
meshCount++;
}
}
}
}
}
CombineInstance[] combine = new CombineInstance[meshCount];
int count = 0;
foreach (var meshsF in meshFilters)
{
combine[count].mesh = meshsF;
combine[count].transform = _thisChunk.gameObject.transform.localToWorldMatrix;
count++;
}
MeshFilter tempFilter = _thisChunk.gameObject.AddComponent<MeshFilter>();
tempFilter.mesh = new Mesh();
tempFilter.mesh.CombineMeshes(combine);
_thisChunk.gameObject.AddComponent<MeshRenderer>().material = basicMat;
_thisChunk.isRendered = true;
}
private Mesh CreateCombinedTerrain(Vector3 pos, List<Direction> dirs)
{
Mesh[] meshesToCombine = new Mesh[dirs.Count];
CombineInstance[] combine = new CombineInstance[dirs.Count];
Mesh mesh = new Mesh();
int meshCount = 0;
foreach (var dir in dirs)
{
mesh.vertices = _planes[(int) dir].vertices;
mesh.triangles = _planes[(int) dir].planeTriangles;
mesh.uv = _planes[(int) dir].uvs;
mesh.RecalculateNormals();
meshesToCombine[meshCount] = mesh;
meshCount++;
}
for (int i = 0; i < meshCount; i++)
{
combine[i].mesh = meshesToCombine[i];
combine[i].transform = Matrix4x4.TRS(pos, Quaternion.Euler(0,-90,0), Vector3.one);
}
Mesh returnMesh = new Mesh();
returnMesh.CombineMeshes(combine);
return returnMesh;
}
Which produces:
It seems like my new code is getting confused at the edges of the mesh but i don't know why. Is there something im missing when I avoid using mesh filters and components? Any ideas would be appreciated.
I can provide the Git repository as an edit, if that would help.
Thanks,
Blackclaw_
Answer by thisisprojectemerald · Nov 09, 2020 at 04:18 PM
Ive fixed the issue. Inside:
foreach (var dir in dirs)
{
mesh.vertices = _planes[(int) dir].vertices;
mesh.triangles = _planes[(int) dir].planeTriangles;
mesh.uv = _planes[(int) dir].uvs;
mesh.RecalculateNormals();
meshesToCombine[meshCount] = mesh;
meshCount++;
}
I didn't include:
mesh = new Mesh();
And each time I was going through the foreach loop i was replacing all the meshes in meshesToCombine with the latest mesh.
TL;DR: Don't be an idiot and think about references.
Your answer
![](https://koobas.hobune.stream/wayback/20220613015436im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
MeshFilter and CombineMesh Doesn't Build Properly 1 Answer
Using Mesh.CombienMeshes. 0 Answers
Mesh Combine Increases Triangle Count 0 Answers
Combining meshes doesn't reduce triangle count 0 Answers
Combine (skinned) submeshes causes increased vertcount(for each submesh the whole vertcount) 0 Answers