Unity資源依賴的處理
我們在前文Unity3D性能優化之資源分析工具篇已經對Unity資源進行了分析,現在就對資源的處理。本文是在進行優化過程中,針對出現的問題和進行處理,只記錄原因和處理目的,限於篇幅沒有具體實現,工具的具體實現后面會另開新篇。
一、紋理資源處理
TextureSetAlphaTranspaency
目的:檢測到 alpha 通道, 但數值都是 1, 禁用Alpha is Transparency 選項,去掉
不必要的 alpha 通道,避免造成內的浪費。
string path = Application.dataPath + "/LuaFramework/AssetBundleRes/iconjpg";
FindFileContent(path, ".png");
FindFileContent(path, ".jpg");
path = Application.dataPath + "/LuaFramework/AssetBundleRes/icon";
FindFileContent(path, ".png");
FindFileContent(path, ".jpg");
//獲得紋理的導入屬性
TextureImporter importer = AssetImporter.GetAtPath(name) as TextureImporter;
if (importer != null)
if (importer.alphaIsTransparency || importer.alphaSource != TextureImporterAlphaSource.None)
if (importer.DoesSourceTextureHaveColor())
//檢測每個像素是否用到透明屬性
public static bool GetTextureHaveAlpha(Color32[] colors, Texture2D texture)
{
int num = texture.width;
int num2 = texture.height;
for (int i = 0; i < num2; i++)
{
for (int j = 0; j < num; j++)
{
int index = (i * num) + j;
if (colors[index].a < 255)
return true;
}
}
return false;
}
//修改設置
importer.alphaIsTransparency = false;
importer.alphaSource = TextureImporterAlphaSource.None;
AssetDatabase.ImportAsset(name);
path=Assets/LuaFramework/AssetBundleRes/iconjpg/activityExchange_bg2.jpg
path=Assets/LuaFramework/AssetBundleRes/iconjpg/bag_bg.jpg
path=Assets/LuaFramework/AssetBundleRes/iconjpg/bag_bg_1.jpg
SetIconPackingTag
目的:在制作UI時,會把圖片放到模塊內,后面大圖標就放到外部目錄去動態加載。有時會誤操作把外部的圖片設置了PackingTag,導致把圖片打包時打進了模塊的圖集中。
TextureImporter importer = AssetImporter.GetAtPath(name) as TextureImporter;
importer.spritePackingTag = "";
importer.mipmapEnabled = false;
importer.isReadable = false;
importer.textureType = TextureImporterType.Sprite;
AssetDatabase.ImportAsset(name);
二、特效資源處理
ParticleClearUnUseFbx
目的:在前文Unity3D性能優化之資源原理科普篇中Unity資源引用的機制已經知道會存在冗余的FBX,所以此工具為了清除這個冗余的FBX。
原理:主要是檢測特效預設中的ParticleSystemRenderer的m_RenderMode字段,如果不是4,說明沒有引用Mesh,那么m_Mesh字段就不應該引用FBX的guid,所以如果檢測到這個guid就應該清理掉。
string particlePrefabPath = "Assets/LuaFramework/AssetBundleRes/scene/effect/objs";
FindFileContent(particlePrefabPath, ".prefab");
Dictionary<string, List<string>> resList = UtilTool.GetFilesKeyIsFileNameDic(files);
ParticleSystemRenderer:
serializedVersion: 4
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1624572044551098}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 0
m_ReflectionProbeUsage: 0
m_Materials:
- {fileID: 2100000, guid: 2a80663029bb2c74cbf77095989a02ec, type: 2}
- {fileID: 2100000, guid: 2a80663029bb2c74cbf77095989a02ec, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 0
m_SelectedEditorRenderState: 0
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_RenderMode: 0
m_SortMode: 0
m_MinParticleSize: 0
m_MaxParticleSize: 2
m_CameraVelocityScale: 0
m_VelocityScale: 0
m_LengthScale: 2
m_SortingFudge: 10
m_NormalDirection: 1
m_RenderAlignment: 0
m_Pivot: {x: 0, y: 0, z: 0}
m_UseCustomVertexStreams: 0
m_VertexStreams: 0001030405
m_Mesh: {fileID: 0}
m_Mesh1: {fileID: 0}
m_Mesh2: {fileID: 0}
m_Mesh3: {fileID: 0}
m_MaskInteraction: 0
ChangeParticleMatToMobileShader
目的:批量修改特效材質引用的Shader替換成Mobile的Shader,因為美術有時在做特效時,對Shader的引用不會考慮性能,所以需要替換成高性能的Shader。直接替換guid。
string materialPath = "Assets/LuaFramework/AssetBundleRes/scene/effect";
FindFileContent(materialPath, ".mat");
if (data.Contains("m_Shader:"))
if (data.Contains("fileID: 203"))
data = data.Replace("fileID: 203, guid: 0000000000000000f000000000000000, type: 0", "fileID: 4800000, guid: 67689383928bb944480f563671a16b6e, type: 3");
三、Animation資源處理
CheckPrefabDependByAnim
目的:將有多個預設使用的Controller和anim打成一個單獨的ab包,然后多個預設根據依賴去加載ab包,而不是每一個prefab的包都打進去相同的一個Controller和anim,減少ab包的體積。
string PrefabPath = "Assets/LuaFramework/AssetBundleRes/scene/object";
FindFileContent(PrefabPath, ".prefab");
//預設引用了那些資源 <guid,fileNames>
Dictionary<string, List<string>> prefabList = UtilTool.GetFilesKeyIsGuidDic(files);
FindFileContent(PrefabPath, ".controller");
//控制器引用了那些資源 <guid,fileNames>
Dictionary<string, List<string>> controllerList = UtilTool.GetFilesKeyIsGuidDic(files);
FindFileContent(PrefabPath, ".anim");
//anim 存放字典<guid,fileName>
Dictionary<string, string> animMap = new Dictionary<string, string>();
anim沒有被Prefab引用列表--------------------------------
-------------anim被多個controll引用列表(引用數量大於1)--------------------------------
-------------controll被Prefab引用列表(引用數量大於1)--------------------------------
controll引用預設個數:5 Assets/LuaFramework/AssetBundleRes/scene/object\monster\res\model_clothe_2040014\action\action.controller
引用的預設:Assets/LuaFramework/AssetBundleRes/scene/object\monster\objs\model_clothe_2040014.prefab
引用的預設:Assets/LuaFramework/AssetBundleRes/scene/object\monster\objs\model_clothe_2040015.prefab
引用的預設:Assets/LuaFramework/AssetBundleRes/scene/object\monster\objs\model_clothe_2040016.prefab
引用的預設:Assets/LuaFramework/AssetBundleRes/scene/object\monster\objs\model_clothe_2040017.prefab
引用的預設:Assets/LuaFramework/AssetBundleRes/scene/object\monster\objs\model_clothe_2040018.prefab
引用的Anim數:1
Assets/LuaFramework/AssetBundleRes/scene/object/monster/res/model_clothe_2040014/action/idle.anim
<item action_path="Assets/LuaFramework/AssetBundleRes/scene/object/monster/res/model_clothe_2040014/action/action.controller" action_packageName="model_clothe_2040014" />
<item action_path="Assets/LuaFramework/AssetBundleRes/scene/object/monster/res/model_clothe_2040014/action/idle.anim" action_packageName="model_clothe_2040014" />
四、打包資源處理
OpenSettingIconWindow
原因:外部小圖標和會經常出現在同個界面,按之前外部圖片的打包流程是每個資源都打成一個ab包,所以會造成打開一個界面時會同時加載多個ab包,如果資源沒下載到本地,還會同時下載多個ab包。
目的:所以針對這種情況將同個界面經常一起加載顯示的小圖標打成一個大的ab包,優化下載和加載時ab包的數量。
CreatTerrainTextureUseConfig
原因:按之前項目的打包策略,是按一個預設打成一個ab包,這樣會造成一個地圖內的資源會有大量小體積的ab包,這樣在下載和加載都會導致性能方面的下降。
目的:對於同一個地圖下的地形資源,如果引用了同一個材質球,就說明引用的紋理資源是一樣的,而地形的紋理已經是單獨打包了,所以將引用同材質球的地形模型預設打到同一個ab包。為了減少小ab包的數量,和下載加載速度。
string terrainPath = "Assets/LuaFramework/AssetBundleRes/scene/terrain";
FindFileContent(terrainPath, ".jpg");
FindFileContent(terrainPath, ".png");
FindFileContent(terrainPath, ".tga");
材質:Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Materials/xsc_1.mat
引用:xsc_1_00 Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Prefab/xsc_1_00.prefab
引用:xsc_1_01 Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Prefab/xsc_1_01.prefab
引用:xsc_1_02 Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Prefab/xsc_1_02.prefab
引用:xsc_1_04 Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Prefab/xsc_1_04.prefab
引用:xsc_1_05 Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Prefab/xsc_1_05.prefab
//打包讀取的文件
<item prefab_name="xsc_1_00" package_name="xsc_1" />
<item prefab_name="xsc_1_01" package_name="xsc_1" />
<item prefab_name="xsc_1_02" package_name="xsc_1" />
<item prefab_name="xsc_1_04" package_name="xsc_1" />
<item prefab_name="xsc_1_05" package_name="xsc_1" />
//打包后的文件
Assets:
- Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Prefab/xsc_1_00.prefab
- Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Prefab/xsc_1_01.prefab
- Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Prefab/xsc_1_02.prefab
- Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Prefab/xsc_1_03.prefab
- Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Prefab/xsc_1_04.prefab
- Assets/LuaFramework/AssetBundleRes/scene/terrain/map/1000/Prefab/xsc_1_05.prefab
Dependencies:
- D:/yzzz_kf/code/u3d/StreamingAssets/rdata/terrain_texture_xsc_1.syrd
CreatParticleUseTexABConfig
原因:影響ab包體積的大小是包里紋理的大小,如果多個特效預設引用同個紋理,那這個大紋理會被打包進多個ab包,形成冗余。
目的:
-
將有2個以上預設使用和紋理大於300k打成一個單獨ab包;
-
將有10個以上預設使用和紋理大於10k打成一個單獨ab包;
-
將紋理寬和高都大於512打成一個單獨ab包;
-
將紋理寬或高有大於600打成一個單獨ab包;
string particlePrefabPath = "Assets/LuaFramework/AssetBundleRes/scene/effect/objs";
FindFileContent(particlePrefabPath, ".prefab");
Dictionary<string, List<string>> resList = UtilTool.GetFilesKeyIsGuidDic(files);
string particleMaterialsFile = "Assets/LuaFramework/AssetBundleRes/scene/effect";
FindFileContent(particleMaterialsFile, ".mat");
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");
//獲取紋理體積大小
fileInfo = new FileInfo(texture_fileName.Replace('\\', '/'));
double size = System.Math.Ceiling(fileInfo.Length / 1024.0);
//獲取紋理寬高
if (texture_fileName.Contains(".tga"))
{
ImageTGA tga = new ImageTGA(texture_fileName);
image = new System.Drawing.Bitmap(tga.Image);
}
else
{
image = new System.Drawing.Bitmap(texture_fileName);
}
width = image.Width;
height = image.Height;