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性能優化之資源處理工具篇


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM