Unity中如何合并网格并让顶点围绕单一原点居中?
解决Unity合并网格后顶点不居中于单个原点的问题
我已经把两个网格合并成一个,但希望生成的网格只以一个原点为中心,让所有顶点围绕这个原点对齐。现在合并后的网格顶点还是基于原来两个物体的位置,导致看起来有两个"原点",该怎么调整?
我的合并脚本如下:
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Splines; public class MeshCalculations : SingletonMonoBehaviour<MeshCalculations> { public GameObject Zone01; public GameObject Zone02; public Mesh createdMesh; private void Update() { if (Input.GetKeyDown(KeyCode.V)) { MergeMeshes(); } } public void MergeMeshes() { // Get MeshFilters from the two GameObjects MeshFilter meshFilter1 = Zone01.GetComponent<MeshFilter>(); MeshFilter meshFilter2 = Zone02.GetComponent<MeshFilter>(); if (meshFilter1 == null || meshFilter2 == null) { Debug.LogError("One of the objects does not have a MeshFilter!"); return; } // CombineInstance array to hold the meshes CombineInstance[] combine = new CombineInstance[2]; // Add the first mesh combine[0].mesh = meshFilter1.sharedMesh; combine[0].transform = meshFilter1.transform.localToWorldMatrix; // Add the second mesh combine[1].mesh = meshFilter2.sharedMesh; combine[1].transform = meshFilter2.transform.localToWorldMatrix; // Create a new mesh Mesh combinedMesh = new Mesh(); combinedMesh.CombineMeshes(combine); // Create a new GameObject to hold the combined mesh GameObject combinedObject = new GameObject("CombinedMesh"); combinedObject.transform.position = Vector3.zero; combinedObject.transform.rotation = Quaternion.identity; // Add a MeshFilter and MeshRenderer to the new GameObject MeshFilter combinedMeshFilter = combinedObject.AddComponent<MeshFilter>(); combinedMeshFilter.mesh = combinedMesh; MeshRenderer combinedMeshRenderer = combinedObject.AddComponent<MeshRenderer>(); combinedMeshRenderer.sharedMaterial = Zone01.GetComponent<MeshRenderer>().sharedMaterial; createdMesh = combinedMesh; } }
问题原因
你当前的代码把两个网格的顶点转换到世界空间后合并,新创建的CombinedMesh物体虽然放在原点,但合并后的网格顶点还是原来两个物体在世界空间的位置,导致网格的中心和物体原点不重合,看起来像是有两个"原点"。
解决方法
合并网格后,计算整个网格的包围盒中心,然后将所有顶点偏移,让这个中心对齐到新物体的原点。修改后的MergeMeshes方法如下:
public void MergeMeshes() { // Get MeshFilters from the two GameObjects MeshFilter meshFilter1 = Zone01.GetComponent<MeshFilter>(); MeshFilter meshFilter2 = Zone02.GetComponent<MeshFilter>(); if (meshFilter1 == null || meshFilter2 == null) { Debug.LogError("One of the objects does not have a MeshFilter!"); return; } // CombineInstance array to hold the meshes CombineInstance[] combine = new CombineInstance[2]; // Add the first mesh combine[0].mesh = meshFilter1.sharedMesh; combine[0].transform = meshFilter1.transform.localToWorldMatrix; // Add the second mesh combine[1].mesh = meshFilter2.sharedMesh; combine[1].transform = meshFilter2.transform.localToWorldMatrix; // Create a new mesh Mesh combinedMesh = new Mesh(); combinedMesh.CombineMeshes(combine); // --- 新增:让网格顶点围绕原点居中 --- // 重新计算包围盒,确保获取准确的网格范围 combinedMesh.RecalculateBounds(); Bounds bounds = combinedMesh.bounds; // 计算包围盒中心 Vector3 centerOffset = bounds.center; // 获取所有顶点 Vector3[] vertices = combinedMesh.vertices; // 每个顶点减去中心偏移,让网格中心对齐到原点 for (int i = 0; i < vertices.Length; i++) { vertices[i] -= centerOffset; } // 更新网格顶点 combinedMesh.vertices = vertices; // 重新计算包围盒和法线,确保网格数据正确 combinedMesh.RecalculateBounds(); combinedMesh.RecalculateNormals(); // --- 新增结束 --- // Create a new GameObject to hold the combined mesh GameObject combinedObject = new GameObject("CombinedMesh"); combinedObject.transform.position = Vector3.zero; combinedObject.transform.rotation = Quaternion.identity; // Add a MeshFilter and MeshRenderer to the new GameObject MeshFilter combinedMeshFilter = combinedObject.AddComponent<MeshFilter>(); combinedMeshFilter.mesh = combinedMesh; MeshRenderer combinedMeshRenderer = combinedObject.AddComponent<MeshRenderer>(); combinedMeshRenderer.sharedMaterial = Zone01.GetComponent<MeshRenderer>().sharedMaterial; createdMesh = combinedMesh; }
关键步骤说明
combinedMesh.RecalculateBounds():合并网格后重新计算包围盒,确保能获取到整个合并网格的准确范围。- 计算
centerOffset:这是当前网格中心相对于新物体原点的偏移量。 - 遍历顶点并减去偏移量:把所有顶点的位置调整,让网格中心对齐到新物体的原点。
- 重新计算包围盒和法线:调整顶点后更新网格的基础数据,避免渲染异常。
内容的提问来源于stack exchange,提问作者Noyan Berkay Aşkın
相关产品推荐
相关产品推荐

