|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
using
UnityEngine;
using
System.Collections;
public
class
Combine : MonoBehaviour
{
void
Start()
{
MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
CombineInstance[] combine =
new
CombineInstance[meshFilters.Length];
for
(
int
i = 0; i < meshFilters.Length; i++)
{
combine[i].mesh = meshFilters[i].sharedMesh;
combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
meshFilters[i].gameObject.active =
false
;
}
transform.GetComponent<MeshFilter>().mesh =
new
Mesh();
transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combine);
transform.gameObject.active =
true
;
}
}
|
|
1
2
|
ArrayList materials =
new
ArrayList();
ArrayList combineInstanceArrays =
new
ArrayList();
|
|
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
|
foreach
(GameObject obj
in
Objects)
{
if
(!obj)
continue
;
MeshFilter[] meshFilters = obj.GetComponentsInChildren<MeshFilter>();
foreach
(MeshFilter meshFilter
in
meshFilters)
{
MeshRenderer meshRenderer = meshFilter.GetComponent<MeshRenderer>();
if
(!meshRenderer)
{
Debug.LogError(
"MeshFilter does not have a coresponding MeshRenderer."
);
continue
;
}
if
(meshRenderer.materials.Length != meshFilter.sharedMesh.subMeshCount)
{
Debug.LogError(
"Mismatch between material count and submesh count. Is this the correct MeshRenderer?"
);
continue
;
}
for
(
int
s = 0; s < meshFilter.sharedMesh.subMeshCount; s++)
{
int
materialArrayIndex = 0;
for
(materialArrayIndex = 0; materialArrayIndex < materials.Count; materialArrayIndex++)
{
if
(materials[materialArrayIndex] == meshRenderer.sharedMaterials[s])
break
;
}
if
(materialArrayIndex == materials.Count)
{
materials.Add(meshRenderer.sharedMaterials[s]);
combineInstanceArrays.Add(
new
ArrayList());
}
CombineInstance combineInstance =
new
CombineInstance();
combineInstance.transform = meshRenderer.transform.localToWorldMatrix;
combineInstance.subMeshIndex = s;
combineInstance.mesh = meshFilter.sharedMesh;
(combineInstanceArrays[materialArrayIndex]
as
ArrayList).Add(combineInstance);
}
}
}
|
|
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
|
{
MeshFilter meshFilterCombine = gameObject.GetComponent<MeshFilter>();
if
(!meshFilterCombine)
meshFilterCombine = gameObject.AddComponent<MeshFilter>();
Mesh[] meshes =
new
Mesh[materials.Count];
CombineInstance[] combineInstances =
new
CombineInstance[materials.Count];
for
(
int
m = 0; m < materials.Count; m++)
{
CombineInstance[] combineInstanceArray = (combineInstanceArrays[m]
as
ArrayList).ToArray(
typeof
(CombineInstance))
as
CombineInstance[];
meshes[m] =
new
Mesh();
meshes[m].CombineMeshes(combineInstanceArray,
true
,
true
);
combineInstances[m] =
new
CombineInstance();
combineInstances[m].mesh = meshes[m];
combineInstances[m].subMeshIndex = 0;
}
meshFilterCombine.sharedMesh =
new
Mesh();
meshFilterCombine.sharedMesh.CombineMeshes(combineInstances,
false
,
false
);
foreach
(Mesh mesh
in
meshes)
{
mesh.Clear();
DestroyImmediate(mesh);
}
}
|
|
1
2
3
4
5
6
7
8
9
|
{
MeshRenderer meshRendererCombine = gameObject.GetComponent<MeshRenderer>();
if
(!meshRendererCombine)
meshRendererCombine = gameObject.AddComponent<MeshRenderer>();
Material[] materialsArray = materials.ToArray(
typeof
(Material))
as
Material[];
meshRendererCombine.materials = materialsArray;
}
}
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
for
(
int
s = 0; s < meshFilter.sharedMesh.subMeshCount; s++)
{
int
materialArrayIndex = 0;
for
(materialArrayIndex = 0; materialArrayIndex < materials.Count; materialArrayIndex++)
{
if
(materials[materialArrayIndex] == meshRenderer.sharedMaterials[s])
break
;
}
if
(materialArrayIndex == materials.Count)
{
materials.Add(meshRenderer.sharedMaterials[s]);
combineInstanceArrays.Add(
new
ArrayList());
}
CombineInstance combineInstance =
new
CombineInstance();
combineInstance.transform = meshRenderer.transform.localToWorldMatrix;
combineInstance.subMeshIndex = s;
combineInstance.mesh = meshFilter.sharedMesh;
(combineInstanceArrays[materialArrayIndex]
as
ArrayList).Add(combineInstance);
}
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
for
(
int
s = 0; s < meshFilter.sharedMesh.subMeshCount; s++)
{
int
materialArrayIndex = Contains(materials, meshRenderer.sharedMaterials[s].name);
if
(materialArrayIndex == -1)
{
materials.Add(meshRenderer.sharedMaterials[s]);
materialArrayIndex = materials.Count - 1;
}
combineInstanceArrays.Add(
new
ArrayList());
CombineInstance combineInstance =
new
CombineInstance();
combineInstance.transform = meshRenderer.transform.localToWorldMatrix;
combineInstance.subMeshIndex = s;
combineInstance.mesh = meshFilter.sharedMesh;
(combineInstanceArrays[materialArrayIndex]
as
ArrayList).Add(combineInstance);
}
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
private
int
Contains(ArrayList searchList,
string
searchName)
{
for
(
int
i = 0; i < searchList.Count; i++)
{
if
(((Material)searchList[i]).name == searchName)
{
return
i;
}
}
return
-1;
}
|
本文深入探讨Unity3D中静态对象优化方法,从使用Unity自带功能到自定义脚本进行优化,逐步解析并实现优化流程。通过代码示例,展示如何将多个对象组合为一个大Mesh,减少DrawCall并保持模型位置不变,解决材质相同对象消失的问题,最终实现优化效果。同时,提供进一步优化代码以处理相同材质的优化问题,确保程序性能提升的同时,不影响模型布局与材质一致性。










1万+





