Unity中批量修改圖片壓縮格式 勾選Override for Android Override for iOS項


項目內存占用比較高,前期並沒有設置圖片的壓縮格式,想寫一個方法批量修改,參考網上的文章,在自己做的過程中遇到些問題在這里記錄一下

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默認設置,有大神知道問題所在,請留言指點,謝謝!


免責聲明!

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



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