mesh合并
helloz 2/7/2025 Unity3d
mesh合并
mesh 合并的过程中,往往会忽略掉submesh的,如果submesh 长度大于1,从而导致顶点 丢失
官方案列:就会导致submesh 丢失
https://docs.unity3d.com/cn/2022.3/ScriptReference/Mesh.CombineMeshes.html
using UnityEngine;
using System.Collections;
// Copy meshes from children into the parent's [Mesh](https://docs.unity3d.com/cn/2022.3/ScriptReference/Mesh.html).
// [CombineInstance](https://docs.unity3d.com/cn/2022.3/ScriptReference/CombineInstance.html) stores the list of meshes. These are combined
// and assigned to the attached [Mesh](https://docs.unity3d.com/cn/2022.3/ScriptReference/Mesh.html).
[[RequireComponent](https://docs.unity3d.com/cn/2022.3/ScriptReference/RequireComponent.html)(typeof([MeshFilter](https://docs.unity3d.com/cn/2022.3/ScriptReference/MeshFilter.html)))]
[[RequireComponent](https://docs.unity3d.com/cn/2022.3/ScriptReference/RequireComponent.html)(typeof([MeshRenderer](https://docs.unity3d.com/cn/2022.3/ScriptReference/MeshRenderer.html)))]
public class ExampleClass : [MonoBehaviour](https://docs.unity3d.com/cn/2022.3/ScriptReference/MonoBehaviour.html)
{
void Start()
{
[MeshFilter](https://docs.unity3d.com/cn/2022.3/ScriptReference/MeshFilter.html)[] meshFilters = GetComponentsInChildren<[MeshFilter](https://docs.unity3d.com/cn/2022.3/ScriptReference/MeshFilter.html)>();
[CombineInstance](https://docs.unity3d.com/cn/2022.3/ScriptReference/CombineInstance.html)[] combine = new [CombineInstance](https://docs.unity3d.com/cn/2022.3/ScriptReference/CombineInstance.html)[meshFilters.Length];
int i = 0;
while (i < meshFilters.Length)
{
combine[i].mesh = meshFilters[i].sharedMesh;
combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
meshFilters[i].gameObject.SetActive(false);
i++;
}
[Mesh](https://docs.unity3d.com/cn/2022.3/ScriptReference/Mesh.html) mesh = new [Mesh](https://docs.unity3d.com/cn/2022.3/ScriptReference/Mesh.html)();
mesh.CombineMeshes(combine);
transform.GetComponent<[MeshFilter](https://docs.unity3d.com/cn/2022.3/ScriptReference/MeshFilter.html)>().sharedMesh = mesh;
transform.gameObject.SetActive(true);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
案列
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using UnityEngine.Rendering;
public class MeshCombiner : MonoBehaviour
{
void Start()
{
MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
List<CombineInstance> combine = new List<CombineInstance>();
List<Material> materials = new List<Material>();
for (int i = 0; i < meshFilters.Length; i++)
{
MeshRenderer renderer = meshFilters[i].GetComponent<MeshRenderer>();
//submesh 合并
//如果忽略了mesh.subMeshCount,subMeshIndex只会为0,可导致其余的submesh丢失
Mesh mesh = meshFilters[i].sharedMesh;
for (int j = 0; j < mesh.subMeshCount; j++)
{
var newCombineInstance = new CombineInstance();
newCombineInstance.mesh = meshFilters[i].sharedMesh;
newCombineInstance.transform = meshFilters[i].transform.localToWorldMatrix;
newCombineInstance.subMeshIndex = j;
combine.Add(newCombineInstance);
}
materials.AddRange(renderer.sharedMaterials);
meshFilters[i].gameObject.SetActive(false);
}
Mesh combinedMesh = new Mesh();
combinedMesh.indexFormat = IndexFormat.UInt32;
combinedMesh.CombineMeshes(combine.ToArray(), true, false); // 设置为true以保留子网格信息
MeshFilter meshFilter = gameObject.AddComponent<MeshFilter>();
meshFilter.mesh = combinedMesh;
MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>();
meshRenderer.materials = materials.ToArray();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48