Unity資源依賴的分析
我們在前文Unity3D性能優化之資源原理科普篇已經對Unity資源有了了解,現在就對資源的依賴進行下一步的分析。本文是在進行優化過程中分析資源,限於篇幅沒有具體實現,工具的具體實現后面會另開新篇。
一、項目資源目錄
二、紋理資源分析
紋理可以被材質引用,材質可以被各種預設所引用,也可以直接被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性能優化之資源處理工具篇