unity 网格合并

编辑器类脚本

 来源:https://www.bilibili.com/video/BV1qg4y1z7YP?t=384

复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

namespace CustomeEditor
{
    public class CombineMesh : EditorWindow
    {
        bool click = false;
        private GameObject combineObjRoot;
        //private GameObject testObj;

        [MenuItem("网格合并/Combine Mesh")]
        static void ShowWindow()
        {
            CombineMesh window = GetWindow<CombineMesh>();
            window.minSize = new Vector2(800, 600);
        }

        private void OnGUI()
        {
            DrawWindow();
            if (click)
            {
                click = false;
                MeshFilter[] filters = combineObjRoot.GetComponentsInChildren<MeshFilter>();
                Debug.Log(filters.Length);
                MeshRenderer[] renderers = combineObjRoot.GetComponentsInChildren<MeshRenderer>();
                CombineInstance[] combines = new CombineInstance[filters.Length];
                HashSet<Material> matSet = new HashSet<Material>();
                Texture2D[] textures = new Texture2D[filters.Length];
                List<Vector2[]> uvList = new List<Vector2[]>();
                int uvCount = 0;
                for (int i = 0; i < filters.Length; i++)
                {
                    if (!matSet.Contains(renderers[i].sharedMaterial)) matSet.Add(renderers[i].sharedMaterial);

                    combines[i].mesh = filters[i].sharedMesh;
                    combines[i].transform = combineObjRoot.transform.worldToLocalMatrix * filters[i].transform.localToWorldMatrix;

                    uvList.Add(filters[i].sharedMesh.uv);
                    uvCount += filters[i].sharedMesh.uv.Length;
                    textures[i] = renderers[i].sharedMaterial.GetTexture("_BaseMap") as Texture2D;

                    filters[i].gameObject.SetActive(false);
                }

                Material[] materials = new Material[matSet.Count];
                int index = 0;
                foreach (Material material in matSet)
                {
                    materials[index] = material;
                    index++;
                }
                Texture2D tex = new Texture2D(1024, 1024);
                Rect[] retcs = tex.PackTextures(textures, 0);
                Debug.Log(retcs[0].xMax);
                Vector2[] uvs = new Vector2[uvCount];
                int j = 0;
                for(int i = 0; i < filters.Length; i++)
                {
                    foreach(Vector2 uv in uvList[i])
                    {
                        uvs[j].x = Mathf.Lerp(retcs[i].xMin, retcs[i].xMax, uv.x);
                        uvs[j].y = Mathf.Lerp(retcs[i].yMin, retcs[i].yMax, uv.y);
                        j++;
                    }
                }

                #region
                //Texture2D tex = new Texture2D(width, height);
                //int x = 0;
                //int y = 0;
                //Debug.Log(textures.Length);
                //Debug.Log(width);
                //for (int i = 0; i < textures.Length; i++)
                //{
                //    for (int xx = 0; xx < textures[i].width; xx++)
                //    {
                //        for (int yy = 0; yy < textures[i].height; yy++)
                //        {
                //            tex.SetPixel(x + xx, y + yy, textures[i].GetPixel(xx, yy));
                //        }
                //    }
                //    x += textures[i].width;
                //    y += textures[i].height;
                //}
                //tex.Apply();
                #endregion
                Material newMat = new Material(materials[0].shader);
                newMat.CopyPropertiesFromMaterial(materials[0]);
                newMat.SetTexture("_BaseMap", tex);
                newMat.name = "TESTMAT";

                //testObj.GetComponent<MeshRenderer>().sharedMaterial = newMat;

                MeshFilter mf = combineObjRoot.AddComponent<MeshFilter>();
                MeshRenderer mr = combineObjRoot.AddComponent<MeshRenderer>();
                Mesh newMesh = new Mesh();
                mf.sharedMesh = newMesh;
                mf.sharedMesh.CombineMeshes(combines);
                mf.sharedMesh.uv = uvs;
                mr.sharedMaterial = newMat;
                combineObjRoot.SetActive(true);   
            }
        }

        private void OnDisable()
        {

        }

        private void DrawWindow()
        {
            BeginWindows();
            EditorGUILayout.LabelField("合并网格物体的根物体: ");
            combineObjRoot = (GameObject)EditorGUILayout.ObjectField(combineObjRoot, typeof(GameObject), true);
            //EditorGUILayout.LabelField("TestObj");
            //testObj = (GameObject)EditorGUILayout.ObjectField(testObj, typeof(GameObject), true);
            click = GUILayout.Button("合并");
            EndWindows();
        }
    }
}
复制代码

 

posted @   三页菌  阅读(318)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
历史上的今天:
2018-04-29 Unity Github 项目收集
2018-04-29 unity收集log工具
点击右上角即可分享
微信分享提示