您的位置:首页 > 移动开发 > Unity3D

Unity优化杂谈4(UI)

2017-10-12 16:59 447 查看
UI这块我们用的NGUI,这里不得不说NGUI的图集,而图集的使用直接影响一个界面加载的速度。我们的UI加载机制是,有部分常驻UI界面,一些动态加载关闭直接卸载的UI界面,一些动态加载打开另外界面才卸载的,所以如果UI里面引用了太多的图集会使界面卡顿,而图集这里也是分为常驻(头像,图标,以及通用的按钮等)的和无用时卸载的。不管加载方式是同步还是异步,规整好图集会使界面加载速度提升。
一般图集都不会压缩,一张RGBA 1024*1024的图集是4M,但是可以把他分为RGA图一张和A图一张,一共1M,同时图集使用的shader需要做相应的修改,在计算的时候要把两张图叠加返回。当然这个在加载bundle的时候需要加载两张,根据手机性能不同一张大图和两张小图的速度各有不同,但内存减少很多。





public
static
voidSetTextureInfo(string
texPath)
   
{
       
TextureImporter textureImporter =
AssetImporter.GetAtPath(texPath)
as
TextureImporter;
       
if (null
==textureImporter)
           
return;
      
4000
 
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);
   
}
   
private
static
voidProcessMaterial(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")
as
Texture2D;
       
string texPath =
AssetDatabase.GetAssetPath(tex2D);
       
if (!texPath.EndsWith(".png"))
           
return;
       
//设置图片可读
       
TextureImporter textureImporter =
AssetImporter.GetAtPath(texPath)
as
TextureImporter;
       
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 =
new
Texture2D(textWidth,textWidth,
TextureFormat.RGB24,
false);
       
Texture2D aTex =
new
Texture2D(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)
as
TextureImporter;
       
textureImporter.isReadable = false;
       
AssetDatabase.ImportAsset(texPath,
ImportAssetOptions.ForceUpdate |
ImportAssetOptions.ForceSynchronousImport);
 
       
Resources.UnloadUnusedAssets();
   
}
   
//拆分贴图
   
private
static
bool SplitTexture(Texture2D
oldTex, ref
Texture2D rgbTex,
ref
Texture2D aTex)
   
{
       
if (oldTex ==
null || rgbTex ==
null || aTex ==
null)
           
return
false;
       
if (rgbTex.width != rgbTex.height ||
           
aTex.width != aTex.width ||
           
rgbTex.width != aTex.width ||
           
oldTex.width > rgbTex.width ||
           
oldTex.height > rgbTex.width)
           
return
false;
       
Color32[] oldPixels = oldTex.GetPixels32();
       
Color32[] rgbPixels =
new
Color32[rgbTex.width *rgbTex.height];
       
Color32[] aPixels =
new
Color32[aTex.width *aTex.height];
       
if (oldPixels ==
null || rgbPixels==
null || aPixels ==
null)
           
return
false;
       
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();
       
return
true;
   }
 
NGUI这里的代码也是有些坑的,类似uiTween,uiTable等使用不当的时候都会存在GC,当然这些最好根据自己项目需求写自己的功能(比如按钮的反馈,图片拖拽,循环滑动列表,UITable的response方法)。
还有就是场景上的UI,如血条,名字之类的,要在一个panel下。
文字在一个界面上放到一个层级上。
这些都会有利于降低UI上的DC。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unity ui 优化 ngui