zoukankan      html  css  js  c++  java
  • 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/iconjpgg_artifact2.jpg
           预设:Assets/LuaFramework/AssetBundleRes/uiartifactprefabArtifactStoneView.prefab
        
      • CheckNoUseTexture

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

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

        string path = "Assets/LuaFramework/AssetBundleRes/ui";
        CheckTexture(path, path, ".png|.jpg", "resuse.txt");
        
        资源:Assets/LuaFramework/AssetBundleRes/uizeroGift	exturelyui_btn_on.png
        	预设:Assets/LuaFramework/AssetBundleRes/uizeroGiftprefaberoGiftView.prefab
          
        以下是没有预设使用的资源:
           纹理:Assets/LuaFramework/AssetBundleRes/uiaccount	exturedlui_btn1.png
           纹理:Assets/LuaFramework/AssetBundleRes/uiaccount	exturedlui_btn2.png
           纹理:Assets/LuaFramework/AssetBundleRes/uiaccount	exturedlui_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/mapWorldprefabWorldMapView.prefab
            依赖其他资源:Assets/LuaFramework/AssetBundleRes/ui/mapArea	extureicon_dt.png
            依赖其他资源:Assets/LuaFramework/AssetBundleRes/ui/mapArea	exturedtui_title.png
            
        模块:mapWorld
             预设:Assets/LuaFramework/AssetBundleRes/ui/mapWorldprefabWorldMapItem.prefab
                   资源:Assets/LuaFramework/AssetBundleRes/ui/mapWorld	extureitem_ui_locate.png
                    资源:Assets/LuaFramework/AssetBundleRes/ui/mapWorld	exturekfui_jfbg.png
                    资源:Assets/LuaFramework/AssetBundleRes/ui/common	extureempty.png
             预设:Assets/LuaFramework/AssetBundleRes/ui/mapWorldprefabWorldMapView.prefab
                    资源:Assets/LuaFramework/AssetBundleRes/ui/mapArea	extureicon_dt.png
                    资源:Assets/LuaFramework/AssetBundleRes/ui/mapArea	exturedtui_title.png
                    资源:Assets/LuaFramework/AssetBundleRes/ui/mapWorld	exturedtui_bg1.png
                    资源:Assets/LuaFramework/AssetBundleRes/ui/common	exture	yui_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/texturemoibletexturehero_18_009.tga 使用的预设数量:257
        	Assets/LuaFramework/AssetBundleRes/scene/effect/objsmoster_effect1790002_at.prefab
        	Assets/LuaFramework/AssetBundleRes/scene/effect/objsmoster_effect1790103_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/objsuff_effectuffparticle_104_1.prefab
      资源:Assets/LuaFramework/AssetBundleRes/scene/effect/animationsskill_animationsqiu2.controller
      资源:Assets/LuaFramework/AssetBundleRes/scene/effect/materialsuffparticle_hudun1_2.mat
      资源:Assets/LuaFramework/AssetBundleRes/scene/effect/materialsuffparticle_hudun1_3.mat
      资源:Assets/LuaFramework/AssetBundleRes/scene/effect/materialsuffparticle_hudun1_4.mat
      资源:Assets/LuaFramework/AssetBundleRes/scene/effect/modelsOthermesh_banyuan17.FBX
      资源:Assets/LuaFramework/AssetBundleRes/scene/effect/modelsOthermesh_pian4.FBX
      资源:Assets/LuaFramework/AssetBundleRes/scene/effect/sharderFXMaker_Mask Additive Tint.shader
      资源:Assets/LuaFramework/AssetBundleRes/scene/effect/textureglowglow_0105.tga
      资源:Assets/LuaFramework/AssetBundleRes/scene/effect/texture
    ing
    ing_z_0257.tga
      资源:Assets/LuaFramework/AssetBundleRes/scene/effect/texturewenliwenli_0343.TGA
      资源:Assets/LuaFramework/AssetBundleRes/scene/effect/texturewenliwenli_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/textureArraylyz_array_004.tga
          引用:Assets/LuaFramework/AssetBundleRes/sceneeffectobjsui_effectui_shengling_iconfx.prefab
          引用:Assets/LuaFramework/AssetBundleRes/sceneeffect	extureArrayMaterialslyz_array_004.mat
    未使用到的纹理:
    纹理:Assets/LuaFramework/AssetBundleRes/scene/effect/textureArraylyz_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/terrainalphatexture3v3_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性能优化之资源处理工具篇

  • 相关阅读:
    Sql Server系列:分区表操作
    [bug]WCF 内存入口检查失败 Memory gates checking failed
    由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面。
    如何设置IIS程序池的回收时间,才能最大程度的减少对用户的影响?
    IIS 之 在IIS7、IIS7.5中应用程序池最优配置方案
    使用nginx搭建高可用,高并发的wcf集群
    NPOI读写Excel
    用 IIS 实现请求转发
    模型验证组件 FluentValidation
    C#中的 正则表达式
  • 原文地址:https://www.cnblogs.com/wwhhgg/p/12966916.html
Copyright © 2011-2022 走看看