Unity网格合并_合并后模型与碰撞器位置变化问题

网格优化:

将多个网格合并为一个网格,即将多个模型合并为一个模型。

如图:

Unity网格合并_合并后模型与碰撞器位置变化问题

编辑脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 合并网格
/// </summary>
public class CombineMesh : MonoBehaviour {

 
 void Start () {

        GetMesh(transform);
 }
 
    /// <summary>
    /// 获得网格
    /// </summary>
 void GetMesh(Transform tf)
    {
      
        //获得自身和所有子物体的MeshFilter组件
        MeshFilter[] meshFilters = tf.GetComponentsInChildren<MeshFilter>();

        //创建CombineInstance数组,长度为所有有MeshFilter组件的物体的长度
        CombineInstance[] combines = new CombineInstance[meshFilters.Length];

        //获得自身和所有子物体的MeshRenderer组件
        MeshRenderer[] meshRenderers = tf.GetComponentsInChildren<MeshRenderer>();

        //新建材质球数组
        Material[] materials = new Material[meshRenderers.Length];

        for (int i = 0; i < meshFilters.Length; i++)
        {
            //获取材质球列表
            materials[i] = meshRenderers[i].sharedMaterial;

            combines[i].mesh = meshFilters[i].sharedMesh;

            //矩阵(Matrix)自身空间坐标的点转换成世界空间坐标的点   
            combines[i].transform = meshFilters[i].transform.localToWorldMatrix;
           

            //如果网格过滤器的物体与当前物体名称不同
            //即 除了父物体,销毁其他所有物体
            if (meshFilters[i].name != gameObject.name)
            {
                Destroy(meshFilters[i].gameObject);
            }
        }

        tf.GetComponent<MeshFilter>().mesh = new Mesh();

        //为mesh.CombineMeshes添加一个 false 参数,表示并不是合并为一个网格,而是一个子网格列表,可以让拥有多个材质球
        //如果要合并的网格用的是同一材质,false改为true,同时将上面的获取Material的代码去掉
        tf.GetComponent<MeshFilter>().mesh.CombineMeshes(combines, false);

        //为合并后的GameObject指定材质球数组
        tf.GetComponent<MeshRenderer>().sharedMaterials = materials;
    }
}

运行时会发现Body下的子物体被销毁了,并且Body身上有三个材质球,但是碰撞器却和模型发生了分离。

Unity网格合并_合并后模型与碰撞器位置变化问题

解决方法是:

变换矩阵的问题,要保持相对位置不变,要转换为父节点的本地坐标,将
combines[i].transform = meshFilters[i].transform.localToWorldMatrix; 这句话改为
combines[i].transform = transform.worldToLocalMatrix * meshFilters[i].transform.localToWorldMatrix; 即可。

运行发现问题解决了,正常显示物体和碰撞器。

Unity网格合并_合并后模型与碰撞器位置变化问题

Get一项新技能,具体可查看官网案例Mesh.CombineMeshes:https://docs.unity3d.com/ScriptReference/Mesh.CombineMeshes.html