You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键步骤说明

  1. combinedMesh.RecalculateBounds():合并网格后重新计算包围盒,确保能获取到整个合并网格的准确范围。
  2. 计算centerOffset:这是当前网格中心相对于新物体原点的偏移量。
  3. 遍历顶点并减去偏移量:把所有顶点的位置调整,让网格中心对齐到新物体的原点。
  4. 重新计算包围盒和法线:调整顶点后更新网格的基础数据,避免渲染异常。

内容的提问来源于stack exchange,提问作者Noyan Berkay Aşkın

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 18:43:14