Unity --- MeshRenderer之网格合并
创建如图所示的对象结构,parent为空对象,然后将下面的代码挂载到parent对象上运行即可。
1 using UnityEngine; 2 using System.Collections; 3 4 public class CombineMeshAndMaterials : MonoBehaviour 5 { 6 void Start() 7 { 8 CombineMesh(); 9 } 10 void CombineMesh() 11 { 12 //收集要合并的贴图 13 MeshRenderer[] oldMRArray = GetComponentsInChildren<MeshRenderer>(); 14 Material[] oldMArray = new Material[oldMRArray.Length]; 15 Texture2D[] textures = new Texture2D[oldMRArray.Length]; 16 for (int i = 0, iMax = oldMRArray.Length; i < iMax; ++i) 17 { 18 oldMArray[i] = oldMRArray[i].sharedMaterial; 19 Texture2D t2d = oldMArray[i].GetTexture("_MainTex") as Texture2D; 20 Texture2D _t2d = new Texture2D(t2d.width, t2d.height, TextureFormat.ARGB32, false); 21 _t2d.SetPixels(t2d.GetPixels(0, 0, t2d.width, t2d.height)); 22 _t2d.Apply(); 23 textures[i] = _t2d; 24 } 25 26 //创建合并后的材质 27 MeshRenderer newMR = gameObject.AddComponent<MeshRenderer>(); 28 Material newM = new Material(oldMArray[0].shader); 29 newM.CopyPropertiesFromMaterial(oldMArray[0]); 30 newMR.sharedMaterial = newM; 31 32 //创建合并后的贴图, 33 Texture2D newTex = new Texture2D(1024, 1024); 34 newM.SetTexture("_MainTex", newTex); //将合并后的贴图赋给合并后的材质 35 36 //重新计算贴图UV 37 MeshFilter[] oldMF = GetComponentsInChildren<MeshFilter>(); 38 CombineInstance[] combines = new CombineInstance[oldMF.Length]; 39 Rect[] rects = newTex.PackTextures(textures, 10, 1024); //贴图打包 ,矩形的数组包含每个输入的纹理的UV坐标 40 for (int i = 0, iMax = oldMF.Length; i < iMax; ++i) 41 { 42 Rect rect = rects[i]; 43 Mesh mesh = oldMF[i].mesh; 44 Vector2[] newUVs = new Vector2[mesh.uv.Length]; 45 46 //刷新uv 47 for (int j = 0, jMax = mesh.uv.Length; j < jMax; ++j) 48 { 49 //如果这里看不太懂,说明对uv的确切含义不太明白 50 //uv是一个比值,u = 横向第u个像素/原始贴图的宽度 v = 竖向第v个像素/原始贴图的高度 51 //rect.x : 原贴图在合并后的贴图的 x 坐标, rect.y : 原贴图在合并后的贴图的 y 坐标 52 newUVs[j].x = mesh.uv[j].x * rect.width + rect.x; 53 newUVs[j].y = mesh.uv[j].y * rect.height + rect.y; 54 } 55 mesh.uv = newUVs; 56 combines[i].mesh = mesh; 57 combines[i].transform = oldMF[i].transform.localToWorldMatrix; //没有这句,合并后的网格无法看到 58 oldMF[i].gameObject.SetActive(false); 59 } 60 61 //创建合并后的网格 62 MeshFilter newMF = gameObject.AddComponent<MeshFilter>(); 63 Mesh newMesh = new Mesh(); 64 newMesh.CombineMeshes(combines, true, true); 65 newMF.mesh = newMesh; 66 } 67 }