针对Unity NGUI图集的Alpha通道分离优化

该博客介绍了一种针对Unity NGUI图集过大问题的优化方法,通过分离Alpha透明通道,可以将内存使用降低到原来的八分之一。提供了一个自定义编辑器扩展,支持批量和单个图集的压缩、解压缩以及Alpha通道的处理。
摘要由CSDN通过智能技术生成
功能:主要是针对NGUI图集过大,占用内存过多进行的优化,将NGUI图集的Alpha透明通道分离出来之后,可以将内存减小为原来的八分之一





using System.Collections;
using System.Collections.Generic;
using System.IO;

public static class AssetUtil
{
    public static void ScanFiles(string directory, string type, bool recursive, ref List<string> files)
    {
        if (!Directory.Exists(directory))
        {
            return;
        }

        string[] paths = Directory.GetFiles(directory);
        for (int i = 0; i < paths.Length; ++i)
        {
            if (type.EndsWith("*") || paths[i].EndsWith(type, System.StringComparison.OrdinalIgnoreCase))
            {
                files.Add(paths[i].Replace('\\', '/'));
            }
        }

        if (!recursive)
        {
            return;
        }

        paths = Directory.GetDirectories(directory);
        for (int i = 0; i < paths.Length; ++i)
        {
            if (paths[i].Contains(".svn"))
            {
                continue;
            }

            ScanFiles(paths[i], type, recursive, ref files);
        }
    }
}









using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;

[CustomEditor(typeof(UIAtlas))]
public class UIAtlasEditor : UIAtlasInspector
{
    /// <summary>
    /// 批量处理
    /// </summary>
    [MenuItem("Custom Editor/UI/Compress All UI Atlas")]
    public static void CompressAllAtlases()
    {
        List<string> prefabs = new List<string>();

        AssetUtil.ScanFiles("Assets/Resources/UI/atlas", "prefab", true, ref prefabs);

        EditorUtility.DisplayProgressBar("Compressing", "", 0);

        for (int i = 0; i < prefabs.Count; ++i)
        {
            EditorUtility.DisplayProgressBar("Compressing", prefabs[i], (float)(i + 1) / prefabs.Count);
            UIAtlasUtil.CompressAtlas(prefabs[i]);
        }

        EditorUtility.ClearProgressBar();
    }

    /// <summary>
    /// 单个处理
    /// </summary>
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        UIAtlas atlas = target as UIAtlas;
        if (null == atlas || null == atlas.spriteMaterial)
        {
            return;
        }

        /*
        Texture2D texture = atlas.spriteMaterial.mainTexture as Texture2D;
        if (null == texture || texture.width != texture.height)
        {
            return;
        }
        */

        if (NGUIEditorTools.DrawHeader("Optimize"))
        {
            NGUIEditorTools.BeginContents();
            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(20);
            EditorGUILayout.BeginVertical();

            if (GUILayout.Button("Compress Atlas"))
            {
                EditorUtility.DisplayProgressBar("Compressing", "Plaese wait.", Random.Range(0.5f, 0.8f));

                UIAtlasUtil.CompressAtlas(AssetDatabase.GetAssetPath(atlas));

                EditorUtility.ClearProgressBar();
            }

            if (GUILayout.Button("Compress Clip Atlas"))
            {
                EditorUtility.DisplayProgressBar("Compressing", "Plaese wait.", Random.Range(0.5f, 0.8f));

                UIAtlasUtil.CompressClipAtlas(AssetDatabase.GetAssetPath(atlas));

                EditorUtility.ClearProgressBar();
            }

            if (atlas.spriteMaterial.shader.name.StartsWith("Unlit/Transparent"))
                EditorGUI.BeginDisabledGroup(!atlas.spriteMaterial.shader.name.Equals("Unlit/Transparent ETC Mask"));
            else if (atlas.spriteMaterial.shader.name.StartsWith("Unlit/Icon"))
                EditorGUI.BeginDisabledGroup(!atlas.spriteMaterial.shader.name.Equals("Unlit/Icon IfMask"));

            if (GUILayout.Button("Uncompress Atlas"))
            {
                EditorUtility.DisplayProgressBar("Uncompressing", "Plaese wait.", Random.Range(0.5f, 0.8f));

                UIAtlasUtil.UncompressAtlas(AssetDatabase.GetAssetPath(atlas));

                EditorUtility.ClearProgressBar();
            }
            EditorGUI.EndDisabledGroup();

            if (GUILayout.Button("Unpack Atlas"))
            {
                UIAtlasUtil.UnpackAtlas(AssetDatabase.GetAssetPath(atlas));
            }

            EditorGUILayout.EndVertical();
            GUILayout.Space(20f);
            EditorGUILayout.EndHorizontal();
            NGUIEditorTools.EndContents();
        }
    }
}










using System.ComponentModel;
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;

/// <summary>
/// 批量
/// </summary>
public class UIAtlasUtil
{
    public static void CompressUITexture(Texture2D texture, string shaderName = "Unlit/Transparent ETC Mask", bool alphaIsTransparency = true)
    {

        if (null == texture)
        {
            Debug.LogError("[UITextureUtil::CompressUITexture] invalid texure: @" + texture.name);
            return;
        }





        string mainTexturePath = AssetDatabase.GetAssetPath(texture);
        TextureImporter mainTextureImporter = AssetImporter.GetAtPath(mainTexturePath) as TextureImporter;
        if (!mainTextureImporter.DoesSourceTextureHaveAlpha())
        {
            mainTextureImporter.textureType = TextureImporterType.Advanced;
            mainTextureImporter.isReadable = false;
            mainTextureImporter.anisoLevel = 0;
            mainTextureImporter.npotScale = TextureImporterNPOTScale.ToNearest;
            mainTextureImporter.wrapMode = TextureWrapMode.Repeat;
            mainTextureImporter.filterMode = FilterMode.Bilinear;
            mainTextureImporter.mipmapEnabled = false;
            mainTextureImporter.maxTextureSize = 2048;
            mainTextureImporter.alphaIsTransparency = alphaIsTransparency;
            mainTextureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.PVRTC_RGB4, 100,true);
            mainTextureImporter.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.ETC_RGB4, 100, true);
            AssetDatabase.ImportAsset(mainTexturePath, ImportAssetOptions.ForceUpdate);

            Debug.Log("[UITextureUtil::CompressUITexture] invalid mainTexture: @ No Alpha " + texture.name);
            return;
        }


        Material material ;
        string oldMatPath = Path.GetDirectoryName(mainTexturePath) + "/" + Path.GetFileNameWithoutExtension(mainTexturePath) + ".mat";
        string newMatPath = Path.GetDirectoryName(mainTexturePath) + "/" + Path.GetFileNameWithoutExtension(mainTexturePath) +"_mat"+ ".mat";

        Material oldMat = AssetDatabase.LoadAssetAtPath(oldMatPath, typeof(Material)) as Material;
        if (oldMat != null)
        {
            //string a = AssetDatabase.RenameAsset(oldMatPath, Path.GetFileName(newMatPath));
            //Debug.Log(a);
            //Debug.Log(oldMatPath);
            //Debug.Log(newMatPath);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }

        
        oldMat = AssetDatabase.LoadAssetAtPath(newMatPath, typeof(Material)) as Material;
        if (oldMat != null)
        {
            material = oldMat;

        }
        else
        {
            material = new Material(Shader.Find(shaderName));
            AssetDatabase.CreateAsset(material, newMatPath);
        }

        if (!material.shader.name.Equals("Unlit/Transparent Colored") &&
            !material.shader.name.Equals("Unlit/Transparent ETC Mask") &&
            !material.shader.name.Equals("Unlit/Icon IfMask") &&
            !material.shader.name.Equals("Unlit/Icon If"))
        {
            Debug.LogError("[UITextureUtil::CompressUITexture] invalid shader: @" + texture.name);
            return;
        }

        // 调整texture属性,提取alpha。
        mainTextureImporter.textureType = TextureImporterType.Advanced;
        mainTextureImporter.isReadable = tr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值