Unity3D性能优化之资源分析工具篇

Unity资源依赖的分析

我们在前文Unity3D性能优化之资源原理科普篇已经对Unity资源有了了解,现在就对资源的依赖进行下一步的分析。本文是在进行优化过程中分析资源,限于篇幅没有具体实现,工具的具体实现后面会另开新篇。

一、项目资源目录

ResourceDir2020-05-26_162808

二、纹理资源分析

纹理可以被材质引用,材质可以被各种预设所引用,也可以直接被UI预设引用,所以需要针对纹理引用进行分析。

1、UI模块引用的纹理

  • 我们拼UI时用到的Sprite类型的图片,在赶项目时,拼UI时对图片的引用和预设的复制重用会导致几个问题。

    • 1、引用外部的图片

    • 2、引用其它模块图片

    • 3、引用其它模块的预设

    • 4、换UI时有旧图片没删除

    • CheckOutsideTexture

      目的:外部图片是独立打包,然后动态加载的。所以UI模块不能引用外部图片,不然会在被引用的模块又打包进一张图片。 删除外部图片的引用

      原理:获取UI模块下预设所引用的guid,然后在查找外部图片的guid,对比得到所引用的外部图片。

      string path = "Assets/LuaFramework/AssetBundleRes/ui";
      string texture_path = "Assets/LuaFramework/AssetBundleRes/icon";
      CheckTexture(path, texture_path, ".png", "outpnguse.txt", true);
      texture_path = "Assets/LuaFramework/AssetBundleRes/iconjpg";
      CheckTexture(path, texture_path, ".jpg", "outjpguse.txt", true);
      
      资源:Assets/LuaFramework/AssetBundleRes/iconjpg\bg_artifact2.jpg
         预设:Assets/LuaFramework/AssetBundleRes/ui\artifact\prefab\ArtifactStoneView.prefab
      
    • CheckNoUseTexture

      目的:找出在模块内但是没有被引用到的图片,删除冗余图片,也可能是动态加载。

      原理:获取UI模块下预设所引用的guid,然后在查找外部图片的guid,对比得到所引用的外部图片。

      string path = "Assets/LuaFramework/AssetBundleRes/ui";
      CheckTexture(path, path, ".png|.jpg", "resuse.txt");
      
      资源:Assets/LuaFramework/AssetBundleRes/ui\zeroGift\texture\lyui_btn_on.png
      	预设:Assets/LuaFramework/AssetBundleRes/ui\zeroGift\prefab\ZeroGiftView.prefab
        
      以下是没有预设使用的资源:
         纹理:Assets/LuaFramework/AssetBundleRes/ui\account\texture\dlui_btn1.png
         纹理:Assets/LuaFramework/AssetBundleRes/ui\account\texture\dlui_btn2.png
         纹理:Assets/LuaFramework/AssetBundleRes/ui\account\texture\dlui_btn3.png
      
    • CreateTextureDepend

      目的:UI模块下是按模块打包和加载的,所以各模块间不能交叉引用图片。

      原理:获取UI模块下预设和图片的guid,对比得到所引用的外部图片。

      string texture_path = "Assets/LuaFramework/AssetBundleRes/ui/";
      string[] dir_list = Directory.GetDirectories(texture_path);
      if (dir_name.Contains("texture"))
      {
      	//仅针对图片.meta文件
      	string[] file_list = Directory.GetFiles(cur, "*.meta");	
      }
      else
      {
      	//仅针对预设.prefab文件
      	string[] file_list = Directory.GetFiles(cur, "*.prefab");
      }
      
      模块:mapWorld
        预设:Assets/LuaFramework/AssetBundleRes/ui/mapWorld\prefab\WorldMapView.prefab
          依赖其他资源:Assets/LuaFramework/AssetBundleRes/ui/mapArea\texture\icon_dt.png
          依赖其他资源:Assets/LuaFramework/AssetBundleRes/ui/mapArea\texture\dtui_title.png
          
      模块:mapWorld
           预设:Assets/LuaFramework/AssetBundleRes/ui/mapWorld\prefab\WorldMapItem.prefab
                 资源:Assets/LuaFramework/AssetBundleRes/ui/mapWorld\texture\item_ui_locate.png
                  资源:Assets/LuaFramework/AssetBundleRes/ui/mapWorld\texture\kfui_jfbg.png
                  资源:Assets/LuaFramework/AssetBundleRes/ui/common\texture\empty.png
           预设:Assets/LuaFramework/AssetBundleRes/ui/mapWorld\prefab\WorldMapView.prefab
                  资源:Assets/LuaFramework/AssetBundleRes/ui/mapArea\texture\icon_dt.png
                  资源:Assets/LuaFramework/AssetBundleRes/ui/mapArea\texture\dtui_title.png
                  资源:Assets/LuaFramework/AssetBundleRes/ui/mapWorld\texture\dtui_bg1.png
                  资源:Assets/LuaFramework/AssetBundleRes/ui/common\texture\tyui_9.png
      

2、材质引用的纹理

  • 纹理图片除了最常用的UI模块,制作特效时和模型贴图也是引用了纹理;这些纹理图片的引用就跟UI模块的引用有一些不同。这些引用主是要引用材质球,材质球引用shader,最后在shader引用纹理。

    • CheckTextureDependByPrefab

    • 检测特效预设引用的纹理,按纹理为key,按被引用数量多到少排序,可以得到用的最多的纹理。

      目的:得到特效的依赖关系,可以根据这个结果对纹理资源打包,纹理压缩进行优化。

      原理:获取effect目录下objs预设的guid,根据预设引用材质,材质引用纹理,对比得到所引用的关系。

      string particlePrefabPath = "Assets/LuaFramework/AssetBundleRes/scene/effect/objs";
      FindFileContent(particlePrefabPath, ".prefab");
      //特效引用了那些资源 <guid,fileNames>
      Dictionary<string, List<string>> resList = UtilTool.GetFilesKeyIsGuidDic(files);
      string particleMaterialsFile = "Assets/LuaFramework/AssetBundleRes/scene/effect";
      FindFileContent(particleMaterialsFile, ".mat");
      //材质引用了那些纹理 <guid,fileNames>
      Dictionary<string, List<string>> matList = UtilTool.GetFilesKeyIsGuidDic(files);
      //存放这个路径下纹理的guid
      string particleTextureFile = "Assets/LuaFramework/AssetBundleRes/scene/effect/texture";
      FindFileContent(particleTextureFile, ".png");
      FindFileContent(particleTextureFile, ".jpg");
      FindFileContent(particleTextureFile, ".tga");
      static void FindFileContent(string root_path, string extstr)
      {
      	string[] names = Directory.GetFiles(root_path);
      	string[] dirs = Directory.GetDirectories(root_path);
      	foreach (string filename in names)
      	{
      		string ext = Path.GetExtension(filename);	
      		if (ext.Equals(extstr, StringComparison.Ordinal))
      		{
      			files.Add(filename);
      		}
      	}
      	FindFileContent(dir, extstr);
      }
      
      纹理:Assets/LuaFramework/AssetBundleRes/scene/effect/texture\moibletexture\hero_18_009.tga 使用的预设数量:257
      	Assets/LuaFramework/AssetBundleRes/scene/effect/objs\moster_effect\1790002_at.prefab
      	Assets/LuaFramework/AssetBundleRes/scene/effect/objs\moster_effect\1790103_at.prefab
      

3、总结

纹理被引用的情况分为直接引用和间接引用,要根据不同类型引用,去找到不同的依赖和引用。

  • 直接引用:Image组件引用,材质球引用
  • 间接引用:特效预设引用材质,材质球引用纹理
  • 分析结果:删除外部图片的引用;删除冗余图片;各模块间不能交叉引用图片;对纹理资源打包优化

三、特效资源分析

  • CheckParticleUseRes

    目的:得到特效的引用的所有资源,根据这个分析可以知道有些FBX模型会存在冗余,后面会有工具去清除这些冗余资源。

    原理:获取effect目录下所有资源的guid,根据预设引用材质、模型、动画、材质、脚本、shader;材质引用纹理,对比得到所引用的关系。

string particlePrefabPath = "Assets/LuaFramework/AssetBundleRes/scene/effect/objs";
FindFileContent(particlePrefabPath, ".prefab");
Dictionary<string, List<string>> resList = UtilTool.GetFilesKeyIsFileNameDic(files);
string particleTextureFile = "Assets/LuaFramework/AssetBundleRes/scene/effect/texture";
FindFileMeta(particleTextureFile, null);
string particleModelFile = "Assets/LuaFramework/AssetBundleRes/scene/effect/models";
FindFileMeta(particleModelFile, null);
string particleAnimationFile = "Assets/LuaFramework/AssetBundleRes/scene/effect/animations";
FindFileMeta(particleAnimationFile, null);
string particleMaterialsFile = "Assets/LuaFramework/AssetBundleRes/scene/effect/materials";
FindFileMeta(particleMaterialsFile, null);
string particleScriptsFile = "Assets/LuaFramework/AssetBundleRes/scene/effect/script";
FindFileMeta(particleScriptsFile, null);
string particleSharderFile = "Assets/LuaFramework/AssetBundleRes/scene/effect/sharder";
FindFileMeta(particleSharderFile, null);
特效:Assets/LuaFramework/AssetBundleRes/scene/effect/objs\buff_effect\buffparticle_104_1.prefab
  资源:Assets/LuaFramework/AssetBundleRes/scene/effect/animations\skill_animations\qiu2.controller
  资源:Assets/LuaFramework/AssetBundleRes/scene/effect/materials\buffparticle_hudun1_2.mat
  资源:Assets/LuaFramework/AssetBundleRes/scene/effect/materials\buffparticle_hudun1_3.mat
  资源:Assets/LuaFramework/AssetBundleRes/scene/effect/materials\buffparticle_hudun1_4.mat
  资源:Assets/LuaFramework/AssetBundleRes/scene/effect/models\Other\mesh_banyuan17.FBX
  资源:Assets/LuaFramework/AssetBundleRes/scene/effect/models\Other\mesh_pian4.FBX
  资源:Assets/LuaFramework/AssetBundleRes/scene/effect/sharder\FXMaker_Mask Additive Tint.shader
  资源:Assets/LuaFramework/AssetBundleRes/scene/effect/texture\glow\glow_0105.tga
  资源:Assets/LuaFramework/AssetBundleRes/scene/effect/texture\ring\ring_z_0257.tga
  资源:Assets/LuaFramework/AssetBundleRes/scene/effect/texture\wenli\wenli_0343.TGA
  资源:Assets/LuaFramework/AssetBundleRes/scene/effect/texture\wenli\wenli_0347.tga

CheckEffectTextureUse

目的:得到以纹理为key,所引用到的特效预设和材质,和没有被使用的特效目录下的纹理,删除冗余纹理

原理:获取effect目录下纹理、预设、材质的guid,根据预设引用材质,材质引用纹理,对比得到所引用的关系。

string textTurePath = "Assets/LuaFramework/AssetBundleRes/scene/effect/texture";
FindFileContentWithContain(textTurePath, ".meta", "tga");
FindFileContentWithContain(textTurePath, ".meta", "png");
FindFileContentWithContain(textTurePath, ".meta", "jpg");
string scenePath = "Assets/LuaFramework/AssetBundleRes/scene";
FindFileContent(scenePath, ".mat");
FindFileContent(scenePath, ".prefab");
Dictionary<string, List<string>> perfabResList = UtilTool.GetFilesKeyIsGuidDic(files);
纹理:Assets/LuaFramework/AssetBundleRes/scene/effect/texture\Array\lyz_array_004.tga
      引用:Assets/LuaFramework/AssetBundleRes/scene\effect\objs\ui_effect\ui_shengling_iconfx.prefab
      引用:Assets/LuaFramework/AssetBundleRes/scene\effect\texture\Array\Materials\lyz_array_004.mat
未使用到的纹理:
纹理:Assets/LuaFramework/AssetBundleRes/scene/effect/texture\Array\lyz_array_249.tga

总结:分析可以知道有些FBX模型会存在冗余;删除冗余纹理

四、模型资源分析

CheckObjUseMaterialAndShader

目的:得到所有模型预设所引用到的材质和纹理。以模型预设为Key。

Object[] UnityAssets = AssetDatabase.LoadAllAssetsAtPath("Resources/unity_builtin_extra");
Object[] UnityDefaultAssets = AssetDatabase.LoadAllAssetsAtPath("Library/unity default resources");
string objectPath = "Assets/LuaFramework/AssetBundleRes/scene/object";
FindFileContent(objectPath, ".prefab");
预设:Assets/LuaFramework/AssetBundleRes/scene/object/headwear/objs/model_head_101000.prefab
依赖:Assets/LuaFramework/AssetBundleRes/scene/object/headwear/res/model_Head_101000/model/Materials/model_Head_101000.mat
依赖:Assets/LuaFramework/AssetBundleRes/scene/object/headwear/res/model_Head_101000/model/model_Head_101000.jpg
依赖:Unlit/Texture

预设:Assets/LuaFramework/AssetBundleRes/scene/object/headwear/objs/model_head_10101001.prefab
     依赖:材质丢失 GUID:6b8e154183c6cd742ad238dd8b174885
     依赖:材质丢失 GUID:562aa29fa58127943879e67bc95368b4

CheckTerrainPrefabsDepend

目的:得到地形预设所引用到的材质和纹理,以地形预设为key。

Object[] UnityAssets = AssetDatabase.LoadAllAssetsAtPath("Resources/unity_builtin_extra");
string terrainPath = "Assets/LuaFramework/AssetBundleRes/scene/terrain";
FindFileContent(terrainPath, ".prefab");
预设:Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Prefab/xsc_1_00.prefab
      引用:Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Materials/xsc_1.mat
      引用:Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Textures/xsc_1.png
      引用:Mobile/Diffuse

CheckTerrainTextureUse

目的:得到地形预设所引用到的纹理,以纹理为key,输出纹理被材质、预设引用的关系。

string terrainPath = "Assets/LuaFramework/AssetBundleRes/scene/terrain";
FindFileContent(terrainPath, ".jpg");
FindFileContent(terrainPath, ".png");
FindFileContent(terrainPath, ".tga");
纹理:Assets/LuaFramework/AssetBundleRes/scene/terrain\alphatexture\3v3_g.png
    引用:Assets/LuaFramework/AssetBundleRes/scene/terrain/map/6000/Materials/3v3_g.mat
    引用:Assets/LuaFramework/AssetBundleRes/scene/terrain/map/6000/Materials/3v3_g_013.mat
    引用:Assets/LuaFramework/AssetBundleRes/scene/terrain/map/6000/Materials/3v3_g1.mat
    引用:Assets/LuaFramework/AssetBundleRes/scene/terrain/map/6000/Prefab/3v3_g_013.prefab

总结

模型的分析是一步一步来,从全部模型到地形模型,然后再纹理被引用,从这些分析文件可以进行什么优化呢?因为模型的打包是单独一个预设打包成一个AB的。如果一张图片被多个预设引用,那么如果单独打包时这张图片会被打包多次,可以进行纹理单独打包,减少冗余纹理。

这篇是资源分析工具,对资源分析输出的结果,针对不同情况,应该要有不同的处理,所以有了下篇文章资源处理工具,敬请期待!Unity3D性能优化之资源处理工具篇

posted @ 2020-05-27 16:10  学习使我进步  阅读(2812)  评论(0编辑  收藏  举报