• Unity3d网格合并


    几个不同的物体,在Unity3d中可以将网格合并在一起,用于优化。

    在Unity3d中构建临时场景如下:建一C#脚本名为"CombineMeshes",挂在Cube上。

    CombineMeshes.cs内容如下:

    using UnityEngine;
    using System.Collections;
    
    public class CombineMeshes : MonoBehaviour
    {
        void Start()
        {
            MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();       //获取自身和所有子物体中所有MeshFilter组件
            CombineInstance[] combine = new CombineInstance[meshFilters.Length];    //新建CombineInstance数组
    
            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);
            }
    
            transform.GetComponent<MeshFilter>().mesh = new Mesh();
            transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combine);       //合并
            transform.gameObject.SetActive(true);
        }
    }

    保存后执行,结果如图:

    观察原本的两个子物体已经变为隐藏状态,观察Cube的网格,已经变为如图中3个物体合并后的网格:

    接着想一想,如果3个物体分别赋了不同的材质球,合并后会是什么样呢?

    那么,接下来,试试我们的想法。修改场景,为3个物体赋上不同的材质球,如下图:

    如果还是用这段代码,将会是如下结果:

    很明显,网格虽然是合并了,但是我们在合并的过程中,并没有代码是处理材质球的,因此,合并后的网格统一赋上了Cube的材质球。

    那么,如果我们既要合并网格,又要保持3个部分保持原来各自的材质球,能否实现呢?答案是肯定的。

    将"CombineMeshes.cs"中的代码进行如下修改:

    using UnityEngine;
    using System.Collections;
    
    public class CombineMeshes : MonoBehaviour
    {
        void Start()
        {
            MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();       
            CombineInstance[] combine = new CombineInstance[meshFilters.Length];    
    
            MeshRenderer[] meshRenderer = GetComponentsInChildren<MeshRenderer>();  //获取自身和所有子物体中所有MeshRenderer组件
            Material[] mats = new Material[meshRenderer.Length];                    //新建材质球数组
    
            for (int i = 0; i < meshFilters.Length; i++)                            
            {
                mats[i] = meshRenderer[i].sharedMaterial;                           //获取材质球列表
    
                combine[i].mesh = meshFilters[i].sharedMesh;
                combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
                meshFilters[i].gameObject.SetActive(false);
            }
    
            transform.GetComponent<MeshFilter>().mesh = new Mesh();
            transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combine, false);//为mesh.CombineMeshes添加一个 false 参数,表示并不是合并为一个网格,而是一个子网格列表
    
            transform.GetComponent<MeshRenderer>().sharedMaterials = mats;          //为合并后的GameObject指定材质
    
            transform.gameObject.SetActive(true);
        }
    }

    再一次运行后,如图:

    达到目的。

    还可以进而在脚本中做相应修改,以满足更复杂一些的需求。主要在于,理解了网格合并的原理,即可灵活运用。比如,在循环中,将

    meshFilters[i].gameObject.SetActive(false);

    替换为

    if (meshFilters[i].gameObject.name != gameObject.name)
    {
        Destroy(meshFilters[i].gameObject);
    }

    即可合并后更洁癖一些。有兴趣的话,可以试试将这三个模型,放在一个空物体下,看看怎样修改代码才能合并明白:)

    晚些时候,我会添加上合并角色骨骼模型的使用方法,即合并含有<SkinnedMeshRenderer>这个组件的,记得初次接触官网那个换装的例子研究了好久。

    附上主要语句的中文手册地址:http://game.ceeger.com/Script/Mesh/Mesh.CombineMeshes.html

  • 相关阅读:
    关于前端开发中的“收口”思想
    Ajax 完整教程(转载)
    GitHub与Git指令入门
    自制一个H5图片拖拽、裁剪插件(原生JS)
    程序猿如何“智斗”产品经理
    Spark 的调度器
    Spark shuffle 过程
    Spark on Yarn 流程
    Spark shuffle 相关参数调优
    Spark shuffle 相关参数调优(带记忆)
  • 原文地址:https://www.cnblogs.com/fengrenyuan/p/3920759.html
Copyright © 2020-2023  润新知