Texturas comprimidas por lotes

Recientemente he estado trabajando en la conversión de Unity a minijuegos de WeChat. Los minijuegos de WeChat tienen altos requisitos para la optimización del tamaño del paquete y los recursos de imágenes de textura siempre han ocupado una gran parte del tamaño del paquete. Este artículo registra las herramientas para la compresión por lotes de Recursos de textura.

Unity2021 , el formato de compresión de texturas compatible con las plataformas Unity,
comienza a admitir el formato de compresión ASTC, por lo que es mejor utilizar Unity2021 y versiones posteriores para los juegos WeChat para obtener el mejor soporte de compresión de texturas.

using System;
using System.IO;
using System.Reflection;
using UnityEngine;
using UnityEditor;


public class SpriteImporter : AssetPostprocessor
{
    
    
    [MenuItem("Assets/Custom Reimport Images")]
    static void SetAllTextureType()
    {
    
    
        //获取鼠标点击目录
        var arr = Selection.GetFiltered(typeof(DefaultAsset), SelectionMode.Assets);
        string folder = AssetDatabase.GetAssetPath(arr[0]);
        Debug.Log($"Reimport Path: {
      
      folder}");
        
        DirectoryInfo direction = new DirectoryInfo(folder);
        FileInfo[] pngFiles = direction.GetFiles("*.png", SearchOption.AllDirectories);
        FileInfo[] jpgFiles = direction.GetFiles("*.jpg", SearchOption.AllDirectories);

        try
        {
    
     
            SetTexture(pngFiles);
            SetTexture(jpgFiles);
        }
        catch (Exception e)
        {
    
    
            Debug.Log(e);
            throw;
        }
        finally
        {
    
    
            EditorUtility.ClearProgressBar();
            AssetDatabase.Refresh();
        }
    }

    private static void SetTexture(FileInfo[] files)
    {
    
    
        for (int i = 0; i < files.Length; i++)
        {
    
    
            //返回绝对路径
            string fullPath = files[i].FullName.Replace("\\", "/");
            //Debug.Log($"Set {fullPath}");
            //通过替换Application.dataPath为Assets变为相对路径
            string path = fullPath.Replace(Application.dataPath, "Assets");
            TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
            EditorUtility.DisplayProgressBar("批量处理图片",files[i].Name,i/(float)files.Length);
            SetTextureFormat(textureImporter);
        }
    }

    private static void SetTextureFormat(TextureImporter textureImporter)
    {
    
    
      
        textureImporter.mipmapEnabled = false;
        textureImporter.isReadable = false;
        int maxSize = GetMaxSize(textureImporter);
        TextureImporterFormat defaultAlpha;
        TextureImporterFormat defaultNoAlpha;

//这里设置要放在对应的平台代码块内,否则改变的就是默认的平台            
#if UNITY_ANDROID 
        TextureImporterPlatformSettings settings_Android = new TextureImporterPlatformSettings();
        //标识平台为Android 大小写都可以
        settings_Android.name = "Android";
        settings_Android.overridden = true;
        settings_Android.maxTextureSize = maxSize;
        bool divisibleOf4 = IsDivisibleOf4(textureImporter);
        defaultAlpha = divisibleOf4 ? TextureImporterFormat.ETC2_RGBA8 : TextureImporterFormat.ASTC_4x4;
        defaultNoAlpha = divisibleOf4 ? TextureImporterFormat.ETC2_RGB4  : TextureImporterFormat.ASTC_4x4;
        settings_Android.format = textureImporter.DoesSourceTextureHaveAlpha() ? defaultAlpha : defaultNoAlpha;
        textureImporter.SetPlatformTextureSettings(settings_Android);
#elif UNITY_IOS
        TextureImporterPlatformSettings settings_IOS = new TextureImporterPlatformSettings();
        settings_IOS.name = "IOS";
        settings_IOS.overridden = true;
        settings_IOS.maxTextureSize = maxSize / 4;
        bool powerOfTwo = IsPowerOfTwo(textureImporter);
        defaultAlpha = powerOfTwo ? TextureImporterFormat.PVRTC_RGBA4 : TextureImporterFormat.ASTC_4x4;
        defaultNoAlpha = powerOfTwo ? TextureImporterFormat.PVRTC_RGB4 : TextureImporterFormat.ASTC_4x4;
        settings_IOS.format = textureImporter.DoesSourceTextureHaveAlpha() ? defaultAlpha : defaultNoAlpha;
        textureImporter.SetPlatformTextureSettings(settings_IOS);
#elif UNITY_WEBGL
        TextureImporterPlatformSettings settings_WebGl = new TextureImporterPlatformSettings();
        settings_WebGl.name = "WebGL";
        settings_WebGl.overridden = true;
        settings_WebGl.maxTextureSize = (maxSize / 4) <= 32 ? 32 : maxSize / 4;
        bool divisibleOf4 = IsDivisibleOf4(textureImporter);
        defaultAlpha = divisibleOf4 ? TextureImporterFormat.DXT5Crunched : TextureImporterFormat.ASTC_4x4;
        defaultNoAlpha = divisibleOf4 ? TextureImporterFormat.DXT1Crunched : TextureImporterFormat.ASTC_4x4;
        //defaultAlpha = TextureImporterFormat.ASTC_4x4;
        //defaultNoAlpha = TextureImporterFormat.ASTC_4x4;
        settings_WebGl.format = textureImporter.DoesSourceTextureHaveAlpha() ? defaultAlpha : defaultNoAlpha;
        textureImporter.SetPlatformTextureSettings(settings_WebGl);
#elif UNITY_STANDALONE
        
#endif
        //保存更改并重新导入图片
        textureImporter.SaveAndReimport();
    }

    
    private static int[] sizes = {
    
    32, 64, 128, 256, 512, 1024, 2048, 4096};

    private static int GetMaxSize(TextureImporter textureImporter)
    {
    
    
        (int width, int height) = GetTextureImporterSize(textureImporter);
        //Debug.Log($"width: {width} height: {height}");
        int tempMax = Mathf.Max(height, width);
        foreach (var size in sizes)
        {
    
    
            if (tempMax <= size)
                return size;
        }

        return 2048;
    }
    
    
    //获取导入图片的宽高
    static (int, int) GetTextureImporterSize(TextureImporter textureImporter)
    {
    
    
        if (textureImporter != null)
        {
    
    
            object[] args = new object[2];
            MethodInfo mi = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
            mi.Invoke(textureImporter, args);
            return ((int)args[0], (int)args[1]);
        }
        return (0, 0);
    }


    //长宽都被4整除
    static bool IsDivisibleOf4(TextureImporter textureImporter)
    {
    
    
        (int width, int height) = GetTextureImporterSize(textureImporter);
        return (width % 4 == 0 && height % 4 == 0);
    }

    //2的整数次幂
    static bool IsPowerOfTwo(TextureImporter textureImporter)
    {
    
    
        (int width, int height) = GetTextureImporterSize(textureImporter);
        return (width == height) && (width > 0) && ((width & (width - 1)) == 0);
    }
}

Referencia:
Unity implementa la función de compresión de imágenes por lotes en
Unity. Cómo implementar la modificación por lotes de formatos de imagen en Unity.
Modificación por lotes de formatos de compresión de imágenes en Unity.

Supongo que te gusta

Origin blog.csdn.net/weixin_44276280/article/details/130830888
Recomendado
Clasificación