【轉】Unity網格合並_材質合並


原帖請戳:Unity網格合並_材質合並

寫在前面:

從優化角度,Mesh需要合並。

從換裝的角度(這里指的是換形狀、換組成部件的換裝,而不是掛點型的換裝),都需要網格合並、材質合並。如果是人物的換裝,那么需要合並SkinnedMeshRenderer,並重刷對應的骨骼列表。

 

示例:

1,新建兩個Cube,和一個Cylinder。分別作為坦克的底盤(Cube_chassis)、炮塔(Cube_turret)、炮管(Cylinder_gun)。如下圖所示。

 

2,為了測試換裝,我們加入三個材質球,調整一下顏色,然后分別賦給底盤(Cube_chassis)、炮塔(Cube_turret)、炮管(Cylinder_gun)。

 

3,把炮塔(Cube_turret)和炮管(Cylinder_gun),變成底盤(Cube_chassis)的子物體。也就是說,新的模型,是以底盤為基礎的。

 

4,用CombineMeshes方法,合並mesh。並且用代碼把【材質】也一起“合並”了。把下面的Combine_Test.cs文件,拖拽到底盤(Cube_chassis)上,之后運行。

using UnityEngine;
using System.Collections;

public class Combine_Test : MonoBehaviour {

    // Use this for initialization
    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>();  
        CombineInstance[] combine = new CombineInstance[meshFilters.Length];   
        for (int i = 0; i < meshFilters.Length; i++) {
            combine[i].mesh = meshFilters[i].sharedMesh;
            //矩陣(Matrix)自身空間坐標的點轉換成世界空間坐標的點 
            combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
            meshFilters[i].gameObject.SetActive(false);
        } 
        //為新的整體新建一個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; 
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}

5,運行效果如下。可以看到,Mesh和材質,都很好的得到了合並。坦克已經由零件,變成一個整體了!

 

但是,大家會發現這個模型,產生了一些變形!難道是這樣不對,或者是bug么?不,其實不用擔心。這是因為前面用的Cube、Cylinder 等模擬底盤炮塔,手動調節了他們的縮放比例放造成的。如果以某個組件為根物體,那么它的縮放比例,直接影響合並后生成的新物體。各個部件的縮放比都會按它走!。

也就是說,如果你想合並后不變形,就不要更改根物體的縮放比例。

 


 

 

參考:

 

關鍵函數,就是下面這個合並網格的函數了:

CombineMeshes(CombineInstance[]combine, boolmergeSubMeshes = true, booluseMatrices = true);

 

Unity官網,關於網格合並的例子:

http://docs.unity3d.com/ScriptReference/Mesh.CombineMeshes.html 

 

程序員俱樂部-Unity3d網格合並:

http://www.cxyclub.cn/n/54078/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM