Unity -网格合并
性能优化上,模型网格顶点和面数越少,性能越好,再者同时绘制两个 1000 面的模型,不如一次绘制 一个 2000 面的模型性能好。
换装等都需要网格合并,物体模型网格合并需要合并 MeshRenderer
, 人物模型换装需要合并 SkinnedMeshRenderer
下面例子为合并 MeshRenderer
一、 创建两个Cube模型分别添加材质球如下
二、分别看两个模型网格以及材质
网格
材质
三、下面将两个Cube网格合并在一起添加到两个Cube 的父物体上,将材质球添加到合并后的模型上,效果如下
四、下面看代码如下
创建脚本 Combine.cs
using UnityEngine;
using System.Collections;
public class Combine : MonoBehaviour {
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.A))
{
CombineMesh();
}
}
private void CombineMesh()
{
//获取自身和所有子物体中所有的 MeshRenderer 组件
MeshRenderer[] meshRenderers = GetComponentsInChildren<MeshRenderer>();
//材质球数组
Material[] materials = new Material[meshRenderers.Length];
for (int i = 0; i < meshRenderers.Length; i ++)
{
materials[i] = meshRenderers[i].sharedMaterial;
}
// 合并 Mesh
// 后去自身和子物体中所有 MsehFilter 组件
MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
CombineInstance[] combines = new CombineInstance[meshRenderers.Length];
for (int i = 0; i < meshFilters.Length; i ++)
{
combines[i].mesh = meshFilters[i].sharedMesh;
// 矩阵(Matrix)自身空间坐标的点转换成世界空间坐标的点
combines[i].transform = meshFilters[i].transform.localToWorldMatrix;
meshFilters[i].gameObject.SetActive(false);
}
//重新生成mesh
MeshFilter meshFilter = transform.GetComponent<MeshFilter>();
if (meshFilter == null)
{
meshFilter = gameObject.AddComponent<MeshFilter>();
}
// 给 MeshFilter 组件的 mesh 赋值
meshFilter.mesh = new Mesh();
//合并Mesh, 第二个参数 false,表示并不合并为一个网格,而是一个自网格列表
transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combines, false);
transform.gameObject.SetActive(true);
//为合并后的新Mesh 指定材质
//transform.GetComponent<MeshRenderer>().sharedMaterials = materials;
MeshRenderer meshRender = transform.GetComponent<MeshRenderer>();
if (meshRender == null)
{
meshRender = gameObject.AddComponent<MeshRenderer>();
}
meshRender.sharedMaterials = materials;
}
}
五、将脚本 Combine.cs
挂载到 Cube 的父物体上,运行项目,点击键盘 A 键,即可查看合并后的网格,材质球都挂载到了合并后的父物体上。