unity 静态网格合并、动态网格合并、材质合并,保存网格资源

合并网格的目的

  1. 为了方便Call Drall 静、动态批处理优化
  2. 为了方便模型部分更换、换装

合并网格的几种方法

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发布前合并 用法一样。只不过是在运行时进行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章