Unity场景Mesh网格合并

Unity场景Mesh网格合并

今天突然被美术问傻了,就是在游戏场景中Mesh找不到了源文件,就是这个在这里插入图片描述
查了一下,原来是之前项目在做场景的时候把一些mesh合并了。到底怎么实现的呢?

为什么要合并Mesh

unity引擎中渲染代价的指标是场景中网格(Mesh)的数量,对显卡来说渲染一个100面的物体和渲染一个1500面的物体几乎是等价的,于是当多个物体的材质(Shader)相同时,可以把他们的网格合并起来,然后共用一个材料(Material)来降低渲染的成本,达成优化游戏体验的效果。ps(不是所有的Mesh都可以合并的)

1.shader相同的物体才可以合并、

2.要合并的物体需要处于一定范围内(具体什么范围看自己的需求)

3.物体的光照贴图需要相同(lightmapindex属性相同)

代码实现

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;

public class ChangeMesh
{
    [MenuItem("Custom /ChangeMesh")]
    static void BuildPCChangeIconName()
    {
        List<GameObject> listGo = GetAllSceneObjectsWithInactive();
        GameObject mountscripts = null;
        for (int i = 0; i < listGo.Count; i++)
        {
            Debug.LogError(listGo[i].name);
            if (listGo[i].name == "scenes_Mesh")
            {
                mountscripts = listGo[i];
                break;
            }
        }
        //合并Mount Scripts的所有网格
        MergeMesh(mountscripts);
    }

    /// <summary>
    /// 合并网格
    /// </summary>
    static void MergeMesh(GameObject go)
    {
        //获取 所有子物体的网格
        MeshFilter[] meshFilters = go.GetComponentsInChildren<MeshFilter>();
        //新建一个合并组,长度与 meshfilters一致
        CombineInstance[] combineInstances = new CombineInstance[meshFilters.Length]; 
        for (int i = 0; i < meshFilters.Length; i++)                                
        {
            combineInstances[i].mesh = meshFilters[i].sharedMesh;                   //将共享mesh,赋值
            combineInstances[i].transform = meshFilters[i].transform.localToWorldMatrix; //本地坐标转矩阵,赋值
        }
        //新网格对象
        Mesh newMesh = new Mesh();
        //将combineInstances数组传入函数
        newMesh.CombineMeshes(combineInstances);
        //给当前空物体,添加网格组件;将合并后的网格,给到自身网格
        go.gameObject.AddComponent<MeshFilter>().sharedMesh = newMesh;
        //给当前空物体添加渲染组件,给新模型网格上色;       
        go.gameObject.AddComponent<MeshRenderer>().material = Resources.Load<Material>("Materials/Koala");                                              
    }

    /// <summary>
    /// 获取当前的场景所有预设
    /// </summary>
    /// <returns></returns>
    static List<GameObject> GetAllSceneObjectsWithInactive()
    {
        var allTransforms = Resources.FindObjectsOfTypeAll(typeof(Transform));
        var previousSelection = Selection.objects;
        Selection.objects = allTransforms.Cast<Transform>()
            .Where(x => x != null)
            .Select(x => x.gameObject)
            //如果你只想获取所有在Hierarchy中被禁用的物体,反注释下面代码
            //.Where(x => x != null && !x.activeInHierarchy)
            .Cast<UnityEngine.Object>().ToArray();

        var selectedTransforms = Selection.GetTransforms(SelectionMode.Editable | SelectionMode.ExcludePrefab);
        Selection.objects = previousSelection;
        return selectedTransforms.Select(tr => tr.gameObject).ToList();
    }
}

运行看看效果吧

  1. 运行在这里插入图片描述
  2. 运行之前,Sense_mesh是没有挂任何组建的,在这里插入图片描述3. 运行之后,在scenes_Mesh对象上就会自动挂上Mesh_Filter 和 MeshRenderer,说明我们合并成功了。我们就可以把 scenes_Mesh对象的子物体删除掉。在这里插入图片描述
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页