Unity3D静态对象优化系列二
在系列一中,我们已经知道了问题所在,一个是优化后我们模型位置改变了,另一个是如果是不同的材质的物体一起优化的时候,不同的材质的对象会消失掉,我们在系列二中主要是解决这两个问题:
接下来我们改进的思路是查找所有的MeshFilter,同时我们根据不同的材质对我们需要优化的对象进行分离。这就需要我们定义两个链表:
ArrayListmaterials=newArrayList();ArrayListcombineInstanceArrays=newArrayList();
下面我们开始遍历我们需要优化对象的MeshFilter和MeshRenderer,因为材质是与MeshRenderder相关联的代码如下:
foreach(GameObjectobjinObjects){if(!obj)continue;MeshFilter[]meshFilters=obj.GetComponentsInChildren<MeshFilter>();foreach(MeshFiltermeshFilterinmeshFilters){MeshRenderermeshRenderer=meshFilter.GetComponent<MeshRenderer>();if(!meshRenderer){Debug.LogError("MeshFilterdoesnothaveacorespondingMeshRenderer.");continue;}if(meshRenderer.materials.Length!=meshFilter.sharedMesh.subMeshCount){Debug.LogError("Mismatchbetweenmaterialcountandsubmeshcount.IsthisthecorrectMeshRenderer?");continue;}for(ints=0;s<meshFilter.sharedMesh.subMeshCount;s++){intmaterialArrayIndex=0;for(materialArrayIndex=0;materialArrayIndex<materials.Count;materialArrayIndex++){if(materials[materialArrayIndex]==meshRenderer.sharedMaterials[s])break;}if(materialArrayIndex==materials.Count){materials.Add(meshRenderer.sharedMaterials[s]);combineInstanceArrays.Add(newArrayList());}CombineInstancecombineInstance=newCombineInstance();combineInstance.transform=meshRenderer.transform.localToWorldMatrix;combineInstance.subMeshIndex=s;combineInstance.mesh=meshFilter.sharedMesh;(combineInstanceArrays[materialArrayIndex]asArrayList).Add(combineInstance);}}}
下面是针对MeshFilter的处理代码:
{MeshFiltermeshFilterCombine=gameObject.GetComponent<MeshFilter>();if(!meshFilterCombine)meshFilterCombine=gameObject.AddComponent<MeshFilter>();Mesh[]meshes=newMesh[materials.Count];CombineInstance[]combineInstances=newCombineInstance[materials.Count];for(intm=0;m<materials.Count;m++){CombineInstance[]combineInstanceArray=(combineInstanceArrays[m]asArrayList).ToArray(typeof(CombineInstance))asCombineInstance[];meshes[m]=newMesh();meshes[m].CombineMeshes(combineInstanceArray,true,true);combineInstances[m]=newCombineInstance();combineInstances[m].mesh=meshes[m];combineInstances[m].subMeshIndex=0;}meshFilterCombine.sharedMesh=newMesh();meshFilterCombine.sharedMesh.CombineMeshes(combineInstances,false,false);foreach(Meshmeshinmeshes){mesh.Clear();DestroyImmediate(mesh);}}
将其组合成一个Mesh,接下来也是最后一步创建Mesh Renderer并将材质赋值给它
{MeshRenderermeshRendererCombine=gameObject.GetComponent<MeshRenderer>();if(!meshRendererCombine)meshRendererCombine=gameObject.AddComponent<MeshRenderer>();Material[]materialsArray=materials.ToArray(typeof(Material))asMaterial[];meshRendererCombine.materials=materialsArray;}}
下面我们看一下优化前后有啥变化,首先我们用四个Cube和一个Sphere,三种材质。效果图如下:
下面我们将我们优化的图展示一下:
对比上图我们可以看到Saved by batching减少了,Used Textures 较少了,Render Textures使用的纹理大小也较少了,虽然相对来说Draw Call增加了,但是由于Render Textures少了,我们的优化效果达到了,而且位置也没变,多种材质也没问题了,但是还有个问题,就是我们的Cube有三个是相同的,但是我们看其材质的效果图:
相同的材质写了三次,这说明我们的程序还需要继续去优化,以上代码只要将其组合在一起就可以使用了,我们将在讲台优化系列三中继续优化我们的优化程序。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。