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發佈前合併 用法一樣。只不過是在運行時進行。

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