从优化角度,Mesh需要合并。
从换装的角度(这里指的是换形状、换组成部件的换装,而不是挂点型的换装),都需要网格合并、材质合并。如果是人物的换装,那么需要合并SkinnedMeshRenderer,并重刷对应的骨骼列表。网格合并后对模型的渲染可以降低GPU的负担,但是经过测试发现,虽然网格合并了但是由于子物体网格的材质是不同的并没有降低DrawCall,如果把材质改成相同的,Unity自身会进行批处理合并,所以DrawCall就会减少!在MMO的游戏中,网格动态合并还是非常有必要的!
代码:
using UnityEngine;
using System.Collections;
/// <summary>
/// 网格合并
/// </summary>
public class Combine_Test : MonoBehaviour
{
void Start()
{
//---------------- 先获取材质 -------------------------
//获取自身和所有子物体中所有MeshRenderer组件
MeshRenderer[] meshRenderers = GetComponentsInChildren<MeshRenderer>();
//新建材质球数组
Material[] mats = new Material[meshRenderers.Length];
for (int i = 0; i < meshRenderers.Length; i++)
{
//生成材质球数组
mats[i] = meshRenderers[i].sharedMaterial;
}
//---------------- 合并 Mesh -------------------------
//获取自身和所有子物体中所有MeshFilter组件
MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
//新建一个合并组,长度与meshfilter长度相同
CombineInstance[] combine = new CombineInstance[meshFilters.Length];
for (int i = 0; i < meshFilters.Length; i++)
{
//获取共享材质
mats[i] = meshRenderers[i].sharedMaterial;
//获取共享mesh
combine[i].mesh = meshFilters[i].sharedMesh;
//矩阵(Matrix)自身空间坐标的点转换成世界空间坐标的点
combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
meshFilters[i].gameObject.SetActive(false);
//除了根物体,其他物体统统销毁
if (meshFilters[i].gameObject.name != gameObject.name)
{
Destroy(meshFilters[i].gameObject);
}
}
//为新的整体新建一个mesh
transform.GetComponent<MeshFilter>().mesh = new Mesh();
//合并Mesh. 第二个false参数, 表示并不合并为一个网格, 而是一个子网格列表
transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combine, false);
transform.gameObject.SetActive(true);
//为合并后的新Mesh指定材质 ------------------------------
transform.GetComponent<MeshRenderer>().sharedMaterials = mats;
}
}
运行前效果图:
运行后效果图:
扫描二维码关注公众号,回复:
5099455 查看本文章