項目內存占用比較高,前期並沒有設置圖片的壓縮格式,想寫一個方法批量修改,參考網上的文章,在自己做的過程中遇到些問題在這里記錄一下
1、路徑里面Replace("/",@"\")替換原來路徑中的反斜杠,不然找不到資源
2、我用的Unity2019.4 需要用TextureImporterPlatformSettings來設置相應屬性,這里遇到個坑,我直接New一個對象出來,結果 Override for Android始終不會設置為true
下面是我完整的代碼,順便實現了圖片導入時自動設置壓縮格式,目前只測了Android環境的部分。
參考文章:
https://www.cnblogs.com/sanyejun/p/10259766.html
https://www.xuanyusong.com/archives/4663
using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using UnityEditor; using UnityEngine; public class AutoSetTexture : EditorWindow { [MenuItem("Tools/批量設置選中節點下圖片壓縮格式")] static void AutoSetASTC() { string[] guidArray = Selection.assetGUIDs; foreach (var item in guidArray) { string selectFloder = AssetDatabase.GUIDToAssetPath(item); DirectoryInfo root = new DirectoryInfo(selectFloder); GetFloder(root); } } static void GetFloder(DirectoryInfo root) { GetFile(root); //查找子文件夾 DirectoryInfo[] array = root.GetDirectories(); //Debug.Log(root); foreach (DirectoryInfo item in array) { GetFloder(item); } } static void GetFile(DirectoryInfo root) { //DirectoryInfo root = new DirectoryInfo(path); FileInfo[] fileDic = root.GetFiles(); foreach (var file in fileDic) { //Debug.Log(file); if (file.FullName.EndsWith(".png") || file.FullName.EndsWith(".jpg") || file.FullName.EndsWith(".tga") || file.FullName.EndsWith(".psd") || file.FullName.EndsWith(".PSD") || file.FullName.EndsWith(".exr") || file.FullName.EndsWith(".tif")) { //Debug.Log("-------------" + file.FullName); //Debug.Log(Application.dataPath); //Debug.Log(Application.dataPath.Replace("Assets", "")); SetPicFormat(file.FullName.Replace(Application.dataPath.Replace("Assets", "").Replace("/",@"\"), "")); } } } static void SetPicFormat(string path) { //Debug.Log(path); TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter; //判斷圖片大小 Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(path); if (texture != null) { int textureSize = Mathf.Max(texture.height, texture.width); //Debug.Log(textureSize); int SizeType = FitSize(textureSize); //設置圖片壓縮格式 SetPlatformSettings(importer, SizeType); } else { Debug.Log("Texture2D為null:" + path); } } /// <summary> /// 設置圖片平台壓縮格式 /// </summary> /// <param name="importer">導入對象</param> /// <param name="sizeType">尺寸類型(512,1024...)</param> public static void SetPlatformSettings(TextureImporter importer, int sizeType) { //參考 https://www.xuanyusong.com/archives/4663 TextureImporterPlatformSettings setParam = new TextureImporterPlatformSettings(); TextureImporterFormat defaultAlpha; TextureImporterFormat defaultNotAlpha; #if UNITY_IOS //ios版本 setParam = importer.GetPlatformTextureSettings("iOS"); setParam.maxTextureSize = sizeType; bool isPowerOfTwo = IsPowerOfTwo(importer); defaultAlpha = isPowerOfTwo ? TextureImporterFormat.PVRTC_RGBA4 : TextureImporterFormat.ASTC_RGBA_4x4; defaultNotAlpha = isPowerOfTwo ? TextureImporterFormat.PVRTC_RGB4 : TextureImporterFormat.ASTC_RGB_6x6; setParam.overridden = true; setParam.format = importer.DoesSourceTextureHaveAlpha() ? defaultAlpha : defaultNotAlpha; importer.SetPlatformTextureSettings(setParam); #endif #if UNITY_ANDROID //安卓版本 setParam = importer.GetPlatformTextureSettings("Android"); //必須用Get方法得到,否則Override for Android不會被設為true setParam.maxTextureSize = sizeType; setParam.overridden = true; setParam.allowsAlphaSplitting = false; bool divisible4 = IsDivisibleOf4(importer); defaultAlpha = divisible4 || importer.textureType == TextureImporterType.Sprite ? TextureImporterFormat.ETC2_RGBA8 : TextureImporterFormat.ASTC_RGBA_4x4; defaultNotAlpha = divisible4 || importer.textureType == TextureImporterType.Sprite ? TextureImporterFormat.ETC2_RGB4 : TextureImporterFormat.ASTC_RGB_6x6; setParam.format = importer.DoesSourceTextureHaveAlpha() ? defaultAlpha : defaultNotAlpha; importer.SetPlatformTextureSettings(setParam); #endif importer.SaveAndReimport(); //AssetDatabase.ImportAsset(path); } static int[] formatSize = new int[] { 32, 64, 128, 256, 512, 1024, 2048, 4096 }; public static int FitSize(int picValue) { foreach (var one in formatSize) { if (picValue <= one) { return one; } } return 1024; } //被4整除 public static bool IsDivisibleOf4(TextureImporter importer) { Vector2Int size = GetTextureImporterSize(importer); return (size.x % 4 == 0 && size.y % 4 == 0); } //2的整數次冪 public static bool IsPowerOfTwo(TextureImporter importer) { Vector2Int size = GetTextureImporterSize(importer); return (size.x == size.y) && (size.x > 0) && ((size.x & (size.x - 1)) == 0); } //貼圖不存在、meta文件不存在、圖片尺寸發生修改需要重新導入 public static bool IsFirstImport(TextureImporter importer, string assetPath) { Vector2Int size = GetTextureImporterSize(importer); Texture tex = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath); bool hasMeta = File.Exists(AssetDatabase.GetAssetPathFromTextMetaFilePath(assetPath)); return tex == null || !hasMeta || (tex.width != size.x && tex.height != size.y); } //獲取導入圖片的寬高 public static Vector2Int GetTextureImporterSize(TextureImporter importer) { Vector2Int result = Vector2Int.zero; if (importer != null) { object[] args = new object[2]; MethodInfo mi = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance); mi.Invoke(importer, args); return (new Vector2Int((int)args[0], (int)args[1])); } return result; } } // 繼承 AssetPostprocessor 資源管理,用於接收事件 public class AutoSetTextureImport : AssetPostprocessor { // 當導入圖片資源時,觸發該事件 void OnPreprocessTexture() { TextureImporter importer = assetImporter as TextureImporter; if (importer != null) { if (AutoSetTexture.IsFirstImport(importer, assetPath)) { if (importer.mipmapEnabled == true) { importer.mipmapEnabled = false; } if (assetImporter.assetPath.Contains("Assets/Art/UI")) { //UI的圖片導入時都設置為sprite importer.textureType = TextureImporterType.Sprite; } Vector2Int tSize = AutoSetTexture.GetTextureImporterSize(importer); int textureSize = Mathf.Max(tSize.y, tSize.x); int SizeType = AutoSetTexture.FitSize(textureSize); //設置壓縮格式 AutoSetTexture.SetPlatformSettings(importer, SizeType); } } } }
-------------------------------------------------------------------------------------------------------
實際運用遇到的問題:
1、Selected texture format 'Unsupported' for platform 'Android' is not valid with the current texture type 'Default'. 有些圖報錯,暫時跳過
2、在android環境把圖片壓縮后,profiler中看,內存反而增加了,原來場景貼圖4096*4096的圖,默認Default的自動壓縮,內存占用是16m,現在用etc2壓縮,MaxSize設置4096,內存占用是64M,
原來2048*2048內存占用5.3m,maxsize設置2048壓縮后內存占用16m,另外cup原來大部分時間在16ms左右,現在都接近66了
3、我將maxsize設置降低一檔,比如4069設置為2048,1024設為512,這樣再查看profiler,內存確實降下來了,cpu也降下來了,但是圖片質量太低,慘不忍睹。
目前我暫時放棄壓縮了,使用unity默認設置,有大神知道問題所在,請留言指點,謝謝!