编辑器类脚本
来源: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(); } } }