合并网格的目的
- 为了方便Call Drall 静、动态批处理优化
- 为了方便模型部分更换、换装
什么模型适合合并网格
并不是越多模型合并越好哦。那是没有任何意义的。因为他们依旧是一个复杂的模型。
颗粒度较高、相对静态、重复率较高的模型组合,都适合合并 。比如重复率较高的建筑模型、物品。
合并网格的几种方法
1 静态物体自动合并(不会改变结构也不会移动的物体,适用于背景)
所有被设置为静态的物体的Mesh Filter都会被合并Scene中的Combined Mesh对象。静态物体是不允许移动的。
【方法&步骤】
点击物体 -> Inspector窗口 -> static
2 发布前合并(不会发生结构变化的模型)
编写脚本,手动选择要合并的模型和材质。
using UnityEditor;
using UnityEngine;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
public class CombineMeshes : Editor
{
private static GameObject targetMesh;
private static string savedName = "_mesh";
// 工具栏新增按钮
[MenuItem("My Tools/Combine Selected Mesh", false, 100)]
// 合并模型
public static void CombineSelectedMesh()
{
//要处理的目标模型 所有要合并的模型需要放在该模型下
targetMesh = Selection.activeGameObject;//GameObject.Find("Cube11");
//获取自身和所有子物体中MeshRenderer组件
MeshRenderer[] meshRenderers = targetMesh.GetComponentsInChildren<MeshRenderer>();
//新建材质球数组
Material[] materialList = new Material[meshRenderers.Length];
for (int i = 0; i < meshRenderers.Length; i++) {
//生成材质球数组
materialList[i] = meshRenderers[i].sharedMaterial;
}
// 合并mesh
//获取自身和所有子物体中所有MeshFilter组件
MeshFilter[] meshFilters = targetMesh.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.SetActive(false);
}
//新建一个物体 to saving combined mesh
GameObject g = new GameObject();
g.transform.name = targetMesh.transform.name + savedName;
//物体和mesh来源物体同级
g.transform.SetParent(targetMesh.transform.parent);
//设置排序
g.transform.SetSiblingIndex(targetMesh.transform.GetSiblingIndex()+1);
// 新建mesh
g.AddComponent<MeshFilter>().mesh = new Mesh();
//合并Mesh. 第二个参数:true合并为一个网格. false合并为子网格
g.GetComponent<MeshFilter>().sharedMesh.CombineMeshes(combine, false);
// set avaliable be true
g.gameObject.SetActive(true);
//为合并后的新Mesh指定材质
g.AddComponent<MeshRenderer>().sharedMaterials = materialList;
}
//点击该按钮 保存网格资源到Asset目录
[MenuItem("My Tools/Save Selected Mesh To Asset", false, 101)]
public static void SaveSelectedMeshToAsset()
{
Mesh mesh = Selection.activeGameObject.GetComponent<MeshFilter>().sharedMesh;
AssetDatabase.CreateAsset(mesh, "Assets/"+ targetMesh.transform.name + savedName +".asset");
AssetDatabase.SaveAssets();
}
}
将该脚本放在Editor文件夹下。修改目标对象名后,点击工具栏的合并按钮即可在原模型下生成合并后的新模型,点击资源保存即可在Asset目录下生成Asset资源
3 动态合并(适用于经常发生结构变化的模型比如武器升级、换装)
有这样的场景,替换人物的某个部分后,希望不影响骨骼系统正常工作,这时候就需要作动态合并。相当于一种组装。动态合并和 2发布前合并 用法一样。只不过是在运行时进行。