Unity优化杂谈4(UI)

来源:互联网 发布:telnet端口 编辑:程序博客网 时间:2024/06/05 08:37

UI这块我们用的NGUI,这里不得不说NGUI的图集,而图集的使用直接影响一个界面加载的速度。我们的UI加载机制是,有部分常驻UI界面,一些动态加载关闭直接卸载的UI界面,一些动态加载打开另外界面才卸载的,所以如果UI里面引用了太多的图集会使界面卡顿,而图集这里也是分为常驻(头像,图标,以及通用的按钮等)的和无用时卸载的。不管加载方式是同步还是异步,规整好图集会使界面加载速度提升。

一般图集都不会压缩,一张RGBA 1024*1024的图集是4M,但是可以把他分为RGA图一张和A图一张,一共1M,同时图集使用的shader需要做相应的修改,在计算的时候要把两张图叠加返回。当然这个在加载bundle的时候需要加载两张,根据手机性能不同一张大图和两张小图的速度各有不同,但内存减少很多。

publicstaticvoidSetTextureInfo(string texPath)

   {

       TextureImporter textureImporter =AssetImporter.GetAtPath(texPath)asTextureImporter;

       if (null ==textureImporter)

           return;

       textureImporter.textureType = TextureImporterType.Advanced;

       textureImporter.mipmapEnabled = false;

       textureImporter.wrapMode = TextureWrapMode.Clamp;

       textureImporter.filterMode = FilterMode.Trilinear;

       textureImporter.anisoLevel = 5;

       textureImporter.SetPlatformTextureSettings("Default", 2048, TextureImporterFormat.AutomaticCompressed);

       textureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.PVRTC_RGB4, 98,false);

       textureImporter.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.ETC2_RGB4, 98,false);

       AssetDatabase.ImportAsset(texPath,ImportAssetOptions.ForceUpdate |ImportAssetOptions.ForceSynchronousImport);

   }

   privatestaticvoidProcessMaterial(string mPath)

   {

       //更换材质

       Material mat =AssetDatabase.LoadAssetAtPath<Material>(mPath);

       if (mat ==null)

           return;      

       Shader oldShader = mat.shader;

       Shader newShader =Shader.Find(atlasExtendShaderName);

       if (oldShader ==null || newShader==null || oldShader.name !=atlasBaseShaderName)

           return;

       Texture2D tex2D = mat.GetTexture("_MainTex")asTexture2D;

       string texPath =AssetDatabase.GetAssetPath(tex2D);

       if (!texPath.EndsWith(".png"))

           return;

       //设置图片可读

       TextureImporter textureImporter =AssetImporter.GetAtPath(texPath)asTextureImporter;

       textureImporter.isReadable = true;

       AssetDatabase.ImportAsset(texPath,ImportAssetOptions.ForceUpdate |ImportAssetOptions.ForceSynchronousImport);

 

       //进行修改

       int textWidth = 0;

       if (tex2D.width >= tex2D.height)

           textWidth = tex2D.width;

       else

           textWidth = tex2D.height;       

       Texture2D rgbTex =newTexture2D(textWidth,textWidth,TextureFormat.RGB24,false);

       Texture2D aTex =newTexture2D(textWidth,textWidth,TextureFormat.RGB24,false);

 

       if (!SplitTexture(tex2D,ref rgbTex,ref aTex))

           return;

           

       string rgbTexPath = texPath.Replace(".png","_rgb.png");

       string aTexPath = texPath.Replace(".png","_a.png");

 

       if (null == rgbTex || string.IsNullOrEmpty(rgbTexPath))

           return;

       File.WriteAllBytes(prjDataPath.Replace("Assets","") + rgbTexPath, rgbTex.EncodeToPNG());

 

       if (null == aTex || string.IsNullOrEmpty(aTexPath))

           return;

       File.WriteAllBytes(prjDataPath.Replace("Assets","") + texPath, aTex.EncodeToPNG());

      

       AssetDatabase.SaveAssets();

       AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate | ImportAssetOptions.ForceSynchronousImport);

 

       SetTextureInfo(rgbTexPath);

       SetTextureInfo(aTexPath);

           

       Texture2D rgbReplaceTex =AssetDatabase.LoadAssetAtPath<Texture2D>(rgbTexPath);

       Texture2D aReplaceTex =AssetDatabase.LoadAssetAtPath<Texture2D>(aTexPath);

       if (rgbReplaceTex ==null || aReplaceTex ==null)

           return;

 

       mat.shader = newShader;

       mat.SetTexture("_MainTex", rgbReplaceTex);

       mat.SetTexture("_Mask", aReplaceTex);

 

       AssetDatabase.SaveAssets();

       AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate | ImportAssetOptions.ForceSynchronousImport);

 

       Object.DestroyImmediate(rgbTex,true);

       Object.DestroyImmediate(aTex,true);

 

       textureImporter = AssetImporter.GetAtPath(texPath)asTextureImporter;

       textureImporter.isReadable = false;

       AssetDatabase.ImportAsset(texPath,ImportAssetOptions.ForceUpdate |ImportAssetOptions.ForceSynchronousImport);

 

       Resources.UnloadUnusedAssets();

   }

   //拆分贴图

   privatestaticbool SplitTexture(Texture2D oldTex, refTexture2D rgbTex,refTexture2D aTex)

   {

       if (oldTex ==null || rgbTex ==null || aTex ==null)

           returnfalse;

       if (rgbTex.width != rgbTex.height ||

           aTex.width != aTex.width ||

           rgbTex.width != aTex.width ||

           oldTex.width > rgbTex.width ||

           oldTex.height > rgbTex.width)

           returnfalse;

       Color32[] oldPixels = oldTex.GetPixels32();

       Color32[] rgbPixels =newColor32[rgbTex.width *rgbTex.height];

       Color32[] aPixels =newColor32[aTex.width *aTex.height];

       if (oldPixels ==null || rgbPixels==null || aPixels ==null)

           returnfalse;

       for(int i = 0; i <rgbTex.height; ++i)

       {

           for (int j = 0; j <rgbTex.width; ++j)

           {

               int sorIdx = i * oldTex.width + j;

               int tarIdx = i * rgbTex.width + j;

               if (i >= oldTex.height || j >= oldTex.width)

               {

                   rgbPixels[tarIdx] = Color.black;

                   aPixels[tarIdx] = Color.white;

               }

               else

               {

                   //copy color

                   rgbPixels[tarIdx].r =oldPixels[sorIdx].r;

                   rgbPixels[tarIdx].g =oldPixels[sorIdx].g;

                   rgbPixels[tarIdx].b =oldPixels[sorIdx].b;

                   rgbPixels[tarIdx].a = 0;

                   //copy alpha

                   aPixels[tarIdx].r =oldPixels[sorIdx].a;

                   aPixels[tarIdx].g = 0;

                   aPixels[tarIdx].b = 0;

                   aPixels[tarIdx].a = 0;

               }

           }

       }

       rgbTex.SetPixels32(rgbPixels);

       aTex.SetPixels32(aPixels);

       rgbTex.Apply();

       aTex.Apply();

       returntrue;

   }

 

NGUI这里的代码也是有些坑的,类似uiTweenuiTable等使用不当的时候都会存在GC,当然这些最好根据自己项目需求写自己的功能(比如按钮的反馈,图片拖拽,循环滑动列表,UITableresponse方法)。

还有就是场景上的UI,如血条,名字之类的,要在一个panel下。

文字在一个界面上放到一个层级上。

这些都会有利于降低UI上的DC

原创粉丝点击