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

来源:互联网 发布:散打教学软件 编辑:程序博客网 时间:2024/05/22 14:40
功能:主要是针对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 = true;        mainTextureImporter.anisoLevel = 0;        mainTextureImporter.npotScale = TextureImporterNPOTScale.ToNearest;        mainTextureImporter.wrapMode = TextureWrapMode.Repeat;        mainTextureImporter.filterMode = FilterMode.Bilinear;        mainTextureImporter.mipmapEnabled = false;        mainTextureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.RGBA32, 100, true);        mainTextureImporter.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.RGBA32, 100, true);        AssetDatabase.ImportAsset(mainTexturePath, ImportAssetOptions.ForceUpdate);        // 提取alpha        texture = AssetDatabase.LoadMainAssetAtPath(mainTexturePath) as Texture2D;        Color[] mainTextureColors = texture.GetPixels();        Texture2D maskTexture = new Texture2D(texture.width, texture.height, TextureFormat.RGB24, false);        Color[] maskTextureColors = maskTexture.GetPixels();        for (int i = 0; i < maskTextureColors.Length; ++i)        {            maskTextureColors[i].r = maskTextureColors[i].g = maskTextureColors[i].b = mainTextureColors[i].a;        }        maskTexture.SetPixels(maskTextureColors);        maskTexture.Apply();        // 保存alpha到png        string maskTexturePath = string.Format("{0}/{1}_alpha.png", Path.GetDirectoryName(mainTexturePath), Path.GetFileNameWithoutExtension(mainTexturePath));        using (FileStream stream = new FileStream(maskTexturePath, FileMode.OpenOrCreate, FileAccess.Write))        using (BinaryWriter writer = new BinaryWriter(stream))        {            writer.Write(maskTexture.EncodeToPNG());        }        // 加载alpha        AssetDatabase.ImportAsset(maskTexturePath, ImportAssetOptions.ForceUpdate);        maskTexture = AssetDatabase.LoadMainAssetAtPath(maskTexturePath) as Texture2D;        TextureImporter maskTextureImporter = AssetImporter.GetAtPath(maskTexturePath) as TextureImporter;        // 修改importer属性,开始压缩        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);        maskTextureImporter.textureType = TextureImporterType.Advanced;        maskTextureImporter.isReadable = false;        maskTextureImporter.anisoLevel = 0;        maskTextureImporter.npotScale = TextureImporterNPOTScale.ToNearest;        maskTextureImporter.wrapMode = TextureWrapMode.Repeat;        maskTextureImporter.filterMode = FilterMode.Bilinear;        maskTextureImporter.mipmapEnabled = false;        maskTextureImporter.maxTextureSize = 2048;        maskTextureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.PVRTC_RGB4, 100, true);        maskTextureImporter.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.ETC_RGB4, 100, true);        AssetDatabase.ImportAsset(maskTexturePath, ImportAssetOptions.ForceUpdate);        // 修改material        //if (material.shader.name.StartsWith("Unlit/Transparent Colored"))        {            material.shader = Shader.Find(shaderName);            material.SetTexture("_MainTex", texture);            material.SetTexture("_MaskTex", maskTexture);        }        AssetDatabase.SaveAssets();        Debug.Log("[UITextureUtil::CompressUITexture] optimize success: @" + texture.name);             }    public static void CompressUITexture(UITexture texture, string shaderName = "Unlit/Transparent ETC Mask", bool alphaIsTransparency = true)    {        if (null == texture)        {            Debug.LogError("[UITextureUtil::CompressUITexture] invalid texure: @" + texture.name);            return;        }                Texture2D mainTexture = texture.mainTexture as Texture2D;        if (null == mainTexture)        {            Debug.LogError("[UITextureUtil::CompressUITexture] invalid mainTexture: @" + texture.name);            return;        }        string mainTexturePath = AssetDatabase.GetAssetPath(mainTexture);        TextureImporter mainTextureImporter = AssetImporter.GetAtPath(mainTexturePath) as TextureImporter;        if (!mainTextureImporter.DoesSourceTextureHaveAlpha())        {            Debug.Log("[UITextureUtil::CompressUITexture] invalid mainTexture: @ No Alpha " + texture.name);            return;        }        Material material = texture.material;        if (null == material)        {            string matPath = Path.GetDirectoryName(mainTexturePath) + "/" + Path.GetFileNameWithoutExtension(mainTexturePath) + "_mat" + ".mat";            Material oldMat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;            if (oldMat != null)            {                material = oldMat;            }            else            {                material = new Material(Shader.Find(shaderName));                AssetDatabase.CreateAsset(material, matPath);            }            texture.material = material;        }        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 = true;        mainTextureImporter.anisoLevel = 0;        mainTextureImporter.npotScale = TextureImporterNPOTScale.ToNearest;        mainTextureImporter.wrapMode = TextureWrapMode.Repeat;        mainTextureImporter.filterMode = FilterMode.Bilinear;        mainTextureImporter.mipmapEnabled = false;        mainTextureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.RGBA32, 100, true);        mainTextureImporter.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.RGBA32, 100, true);        AssetDatabase.ImportAsset(mainTexturePath, ImportAssetOptions.ForceUpdate);        // 提取alpha        mainTexture = AssetDatabase.LoadMainAssetAtPath(mainTexturePath) as Texture2D;        Color[] mainTextureColors = mainTexture.GetPixels();        Texture2D maskTexture = new Texture2D(mainTexture.width, mainTexture.height, TextureFormat.RGB24, false);        Color[] maskTextureColors = maskTexture.GetPixels();        for (int i = 0; i < maskTextureColors.Length; ++i)        {            maskTextureColors[i].r = maskTextureColors[i].g = maskTextureColors[i].b = mainTextureColors[i].a;        }        maskTexture.SetPixels(maskTextureColors);        maskTexture.Apply();        // 保存alpha到png        string maskTexturePath = string.Format("{0}/{1}_alpha.png", Path.GetDirectoryName(mainTexturePath), Path.GetFileNameWithoutExtension(mainTexturePath));        using (FileStream stream = new FileStream(maskTexturePath, FileMode.OpenOrCreate, FileAccess.Write))        using (BinaryWriter writer = new BinaryWriter(stream))        {            writer.Write(maskTexture.EncodeToPNG());        }        // 加载alpha        AssetDatabase.ImportAsset(maskTexturePath, ImportAssetOptions.ForceUpdate);        maskTexture = AssetDatabase.LoadMainAssetAtPath(maskTexturePath) as Texture2D;        TextureImporter maskTextureImporter = AssetImporter.GetAtPath(maskTexturePath) as TextureImporter;        // 修改importer属性,开始压缩        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);        maskTextureImporter.textureType = TextureImporterType.Advanced;        maskTextureImporter.isReadable = false;        maskTextureImporter.anisoLevel = 0;        maskTextureImporter.npotScale = TextureImporterNPOTScale.ToNearest;        maskTextureImporter.wrapMode = TextureWrapMode.Repeat;        maskTextureImporter.filterMode = FilterMode.Bilinear;        maskTextureImporter.mipmapEnabled = false;        maskTextureImporter.maxTextureSize = 2048;        maskTextureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.PVRTC_RGB4, 100, true);        maskTextureImporter.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.ETC_RGB4, 100, true);        AssetDatabase.ImportAsset(maskTexturePath, ImportAssetOptions.ForceUpdate);        // 修改material        //if (material.shader.name.StartsWith("Unlit/Transparent Colored"))        {            material.shader = Shader.Find(shaderName);            material.SetTexture("_MainTex", mainTexture);            material.SetTexture("_MaskTex", maskTexture);        }        //else if (material.shader.name.StartsWith("Unlit/Icon"))        //{        //    material.shader = Shader.Find("Unlit/Icon IfMask");        //    material.SetTexture("_MainTex", mainTexture);        //    material.SetTexture("_MaskTex", maskTexture);        //}        AssetDatabase.SaveAssets();        // string materialPath = AssetDatabase.GetAssetPath(material);        // AssetDatabase.WriteImportSettingsIfDirty(materialPath);        Debug.Log("[UITextureUtil::CompressUITexture] optimize success: @" + texture.name);    }    public static void CompressAtlas(string prefab, string shaderName = "Unlit/Transparent ETC Mask", bool alphaIsTransparency = true)      {        GameObject go = AssetDatabase.LoadMainAssetAtPath(prefab) as GameObject;        if (null == go)        {            Debug.LogError("[UIAtlasUtil::CompressAtlas] invalid prefab: @" + prefab);            return;        }        UIAtlas atlas = go.GetComponent<UIAtlas>();        if (null == atlas)        {            Debug.LogError("[UIAtlasUtil::CompressAtlas] invalid atlas: @" + prefab);            return;        }        Material material = atlas.spriteMaterial;        if (null == material)        {            Debug.LogError("[UIAtlasUtil::CompressAtlas] invalid material: @" + prefab);            return;        }               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("[UIAtlasUtil::CompressAtlas] invalid shader: @" + prefab);            return;        }        Texture2D mainTexture = material.mainTexture as Texture2D;        if (null == mainTexture)        {            Debug.LogError("[UIAtlasUtil::CompressAtlas] invalid mainTexture: @" + prefab);            return;        }        string mainTexturePath = AssetDatabase.GetAssetPath(mainTexture);        TextureImporter mainTextureImporter = AssetImporter.GetAtPath(mainTexturePath) as TextureImporter;        // 调整texture属性,提取alpha。        mainTextureImporter.textureType = TextureImporterType.Advanced;        mainTextureImporter.isReadable = true;        mainTextureImporter.anisoLevel = 0;        mainTextureImporter.npotScale = TextureImporterNPOTScale.ToNearest;        mainTextureImporter.wrapMode = TextureWrapMode.Repeat;        mainTextureImporter.filterMode = FilterMode.Bilinear;        mainTextureImporter.mipmapEnabled = false;        mainTextureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.RGBA32, 100, true);        mainTextureImporter.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.RGBA32, 100, true);        AssetDatabase.ImportAsset(mainTexturePath, ImportAssetOptions.ForceUpdate);        // 提取alpha        mainTexture = AssetDatabase.LoadMainAssetAtPath(mainTexturePath) as Texture2D;        Color[] mainTextureColors = mainTexture.GetPixels();        Texture2D maskTexture = new Texture2D(mainTexture.width, mainTexture.height, TextureFormat.RGB24, false);        Color[] maskTextureColors = maskTexture.GetPixels();        for (int i=0; i<maskTextureColors.Length; ++i)        {            maskTextureColors[i].g =maskTextureColors[i].r  = maskTextureColors[i].b = mainTextureColors[i].a;        }         maskTexture.SetPixels(maskTextureColors);        maskTexture.Apply(true);        // 保存alpha到png        string maskTexturePath = string.Format("{0}/{1}_alpha.png", Path.GetDirectoryName(mainTexturePath), Path.GetFileNameWithoutExtension(mainTexturePath));        using(FileStream stream = new FileStream(maskTexturePath, FileMode.OpenOrCreate, FileAccess.Write))        using(BinaryWriter writer = new BinaryWriter(stream))        {            writer.Write(maskTexture.EncodeToPNG());        }        // 加载alpha        AssetDatabase.ImportAsset(maskTexturePath, ImportAssetOptions.ForceUpdate);        maskTexture = AssetDatabase.LoadMainAssetAtPath(maskTexturePath) as Texture2D;        TextureImporter maskTextureImporter = AssetImporter.GetAtPath(maskTexturePath) as TextureImporter;                        // 修改importer属性,开始压缩        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);        maskTextureImporter.textureType = TextureImporterType.Advanced;        maskTextureImporter.isReadable = false;        maskTextureImporter.anisoLevel = 0;        maskTextureImporter.npotScale = TextureImporterNPOTScale.ToNearest;        maskTextureImporter.wrapMode = TextureWrapMode.Repeat;        maskTextureImporter.filterMode = FilterMode.Bilinear;        maskTextureImporter.mipmapEnabled = false;        maskTextureImporter.maxTextureSize = 2048;        maskTextureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.PVRTC_RGB4, 100, true);        maskTextureImporter.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.ETC_RGB4, 100, true);        AssetDatabase.ImportAsset(maskTexturePath, ImportAssetOptions.ForceUpdate);        // 修改material        //if (material.shader.name.StartsWith("Unlit/Transparent Colored"))        {            material.shader = Shader.Find(shaderName);            material.SetTexture("_MainTex", mainTexture);            material.SetTexture("_MaskTex", maskTexture);        }        //else if (material.shader.name.StartsWith("Unlit/Icon"))        //{        //    material.shader = Shader.Find("Unlit/Icon IfMask");        //    material.SetTexture("_MainTex", mainTexture);        //    material.SetTexture("_MaskTex", maskTexture);        //}        AssetDatabase.SaveAssets();        // string materialPath = AssetDatabase.GetAssetPath(material);        // AssetDatabase.WriteImportSettingsIfDirty(materialPath);        Debug.Log("[UIAtlasUtil::CompressAtlas] optimize success: @" + prefab);    }    public static void CompressClipAtlas(string prefab, string shaderName = "Unlit/Transparent ETC Mask", bool alphaIsTransparency = true)    {        GameObject go = AssetDatabase.LoadMainAssetAtPath(prefab) as GameObject;        if (null == go)        {            Debug.LogError("[UIAtlasUtil::CompressClipAtlas] invalid prefab: @" + prefab);            return;        }        UIAtlas atlas = go.GetComponent<UIAtlas>();        if (null == atlas)        {            Debug.LogError("[UIAtlasUtil::CompressClipAtlas] invalid atlas: @" + prefab);            return;        }        Material material = atlas.spriteMaterial;        if (null == material)        {            Debug.LogError("[UIAtlasUtil::CompressClipAtlas] invalid material: @" + prefab);            return;        }        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("[UIAtlasUtil::CompressAtlas] invalid shader: @" + prefab);            return;        }        Texture2D mainTexture = material.mainTexture as Texture2D;        if (null == mainTexture)        {            Debug.LogError("[UIAtlasUtil::CompressAtlas] invalid mainTexture: @" + prefab);            return;        }        string mainTexturePath = AssetDatabase.GetAssetPath(mainTexture);        TextureImporter mainTextureImporter = AssetImporter.GetAtPath(mainTexturePath) as TextureImporter;        // 调整texture属性,提取alpha。        mainTextureImporter.textureType = TextureImporterType.Advanced;        mainTextureImporter.isReadable = true;        mainTextureImporter.anisoLevel = 0;        mainTextureImporter.npotScale = TextureImporterNPOTScale.ToNearest;        mainTextureImporter.wrapMode = TextureWrapMode.Repeat;        mainTextureImporter.filterMode = FilterMode.Bilinear;        mainTextureImporter.mipmapEnabled = false;        mainTextureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.RGBA32, 100, true);        mainTextureImporter.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.RGBA32, 100, true);        AssetDatabase.ImportAsset(mainTexturePath, ImportAssetOptions.ForceUpdate);        // 提取alpha        mainTexture = AssetDatabase.LoadMainAssetAtPath(mainTexturePath) as Texture2D;        Color[] mainTextureColors = mainTexture.GetPixels();        Texture2D maskTexture = new Texture2D(mainTexture.width, mainTexture.height, TextureFormat.RGB24, false);        Color[] maskTextureColors = maskTexture.GetPixels();        for (int i = 0; i < maskTextureColors.Length; ++i)        {            maskTextureColors[i].g = maskTextureColors[i].r = maskTextureColors[i].b = mainTextureColors[i].a;        }        maskTexture.SetPixels(maskTextureColors);        maskTexture.Apply(true);        Texture2D clipTexture = Resources.Load<Texture2D>("settingfragment6");        Color[] defaultClipColors = clipTexture.GetPixels();        List<string> allList = new List<string>(atlas.GetListOfSprites().ToArray());        for (int i = 0; i < allList.Count; i++)        {            Color[] clipColors = defaultClipColors;            UISpriteData spriteData = atlas.GetSprite(allList[i]);            int deltaWidth = spriteData.width - clipTexture.width;            int deltaHeight = spriteData.height - clipTexture.height;            int clipUseX = 0;            int clipUseY = 0;            if (deltaWidth < 0 || deltaHeight < 0)            {                int useClipWidth = clipTexture.width;                if (deltaWidth < 0)                {                    useClipWidth = spriteData.width;                    clipUseX = Mathf.Abs(deltaWidth) / 2 + Mathf.Abs(deltaWidth) % 2;                }                int useClipHeight = clipTexture.height;                if (deltaHeight < 0)                {                    useClipHeight = spriteData.height;                    clipUseY = Mathf.Abs(deltaHeight) / 2 + Mathf.Abs(deltaHeight) % 2;                }                clipColors = clipTexture.GetPixels(clipUseX, clipUseY, useClipWidth, useClipHeight);            }            //差值最小为0            deltaWidth = deltaWidth < 0 ? 0 : deltaWidth;            deltaHeight = deltaHeight < 0 ? 0 : deltaHeight;            //找到中间位置并解决一像素误差            int oneWPixelRemain = deltaWidth % 2;            int oneHPixelRemain = deltaHeight % 2;            int halfDeltaWidth = deltaWidth / 2;            int halfDeltaHeight = deltaHeight / 2;            //atlas给出的坐标是是以左上角为00点,Texture的坐标是以左下角为00点,需要计算一下            int startX = spriteData.x;            int startY = maskTexture.height - spriteData.y - spriteData.height;            int useX = spriteData.x + halfDeltaWidth + oneWPixelRemain;            int useY = startY + halfDeltaHeight + oneHPixelRemain;            //实际需要裁剪的宽度和高度,用来去颜色数组            int useWidth = spriteData.width - deltaWidth;            int useHeight = spriteData.height - deltaHeight;            //先把所有色值g值写为0            Color[] allColors = maskTexture.GetPixels(startX, startY, spriteData.width, spriteData.height);            for (int j = 0; j < allColors.Length; j++)            {                allColors[j].g = 0;            }            maskTexture.SetPixels(startX, startY, spriteData.width, spriteData.height, allColors);            Color[] clipSourceColors = maskTexture.GetPixels(useX, useY, useWidth, useHeight);            //写入新的裁剪后的颜色值            for (int j = 0; j < clipSourceColors.Length; j++)            {                clipSourceColors[j].g = 0.0f;                if (j < clipColors.Length)                {                    //Debug.LogError(clipSourceColors[j].r);                    if (clipColors[j].g > 0.9f && clipSourceColors[j].r>0.01f)                        clipSourceColors[j].g = 1.0f;                }            }            maskTexture.SetPixels(useX, useY, useWidth, useHeight, clipSourceColors);            //for (int j = 0; j < useWidth; j++)            //{            //    for (int k = 0; k < useHeight; k++)            //    {            //        Color defaultColor = maskTexture.GetPixel(useX + j, useY + k);            //        Color clipColor = clipTexture.GetPixel(clipUseX + j, clipUseY + k);            //        Color useColor = new Color(defaultColor.r, defaultColor.g, defaultColor.b);            //        useColor.g = 0f;            //        if (clipColor.g > 0.001f)            //            useColor.g = 1f;            //        //Debug.LogError(defaultColor);            //        maskTexture.SetPixel(useX + j, useY + k, useColor);            //        //if (j==2)            //        //{            //        //    Color test = maskTexture.GetPixel(useX + j, useY + k);            //        //    Debug.LogError((useX + j )+ "     " + "  " + (useY + k) +"   "+ test + "   " + defaultColor);            //        //}            //    }            //}            maskTexture.Apply(true);        }        maskTexture.Apply(true);        // 保存alpha到png        string maskTexturePath = string.Format("{0}/{1}_alpha.png", Path.GetDirectoryName(mainTexturePath), Path.GetFileNameWithoutExtension(mainTexturePath));        using (FileStream stream = new FileStream(maskTexturePath, FileMode.OpenOrCreate, FileAccess.Write))        using (BinaryWriter writer = new BinaryWriter(stream))        {            writer.Write(maskTexture.EncodeToPNG());        }        // 加载alpha        AssetDatabase.ImportAsset(maskTexturePath, ImportAssetOptions.ForceUpdate);        maskTexture = AssetDatabase.LoadMainAssetAtPath(maskTexturePath) as Texture2D;        TextureImporter maskTextureImporter = AssetImporter.GetAtPath(maskTexturePath) as TextureImporter;        // 修改importer属性,开始压缩        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);        maskTextureImporter.textureType = TextureImporterType.Advanced;        maskTextureImporter.isReadable = true;        maskTextureImporter.anisoLevel = 0;        maskTextureImporter.npotScale = TextureImporterNPOTScale.ToNearest;        maskTextureImporter.wrapMode = TextureWrapMode.Repeat;        maskTextureImporter.filterMode = FilterMode.Bilinear;        maskTextureImporter.mipmapEnabled = false;        maskTextureImporter.maxTextureSize = 2048;        maskTextureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.PVRTC_RGB4, 100, true);        maskTextureImporter.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.ETC_RGB4, 100, true);        AssetDatabase.ImportAsset(maskTexturePath, ImportAssetOptions.ForceUpdate);        // 修改material        //if (material.shader.name.StartsWith("Unlit/Transparent Colored"))        {            material.shader = Shader.Find(shaderName);            material.SetTexture("_MainTex", mainTexture);            material.SetTexture("_MaskTex", maskTexture);        }        //else if (material.shader.name.StartsWith("Unlit/Icon"))        //{        //    material.shader = Shader.Find("Unlit/Icon IfMask");        //    material.SetTexture("_MainTex", mainTexture);        //    material.SetTexture("_MaskTex", maskTexture);        //}        AssetDatabase.SaveAssets();        // string materialPath = AssetDatabase.GetAssetPath(material);        // AssetDatabase.WriteImportSettingsIfDirty(materialPath);        Debug.Log("[UIAtlasUtil::CompressAtlas] optimize success: @" + prefab);    }    public static void UncompressAtlas(string prefab)    {        GameObject go = AssetDatabase.LoadMainAssetAtPath(prefab) as GameObject;        if (null == go)        {            Debug.LogError("[UIAtlasUtil::UncompressAtlas] invalid prefab: @" + prefab);            return;        }        UIAtlas atlas = go.GetComponent<UIAtlas>();        if (null == atlas)        {            Debug.LogError("[UIAtlasUtil::UncompressAtlas] invalid atlas: @" + prefab);            return;        }        Material material = atlas.spriteMaterial;        if (null == material)        {            Debug.LogError("[UIAtlasUtil::UncompressAtlas] invalid material: @" + prefab);            return;        }        if (!material.shader.name.Equals("Unlit/Transparent ETC Mask")&&            !material.shader.name.Equals("Unlit/Icon IfMask"))        {            Debug.LogError("[UIAtlasUtil::UncompressAtlas] invalid shader: @" + prefab);            return;        }        Texture2D mainTexture = material.mainTexture as Texture2D;        if (null == mainTexture)        {            Debug.LogError("[UIAtlasUtil::CompressAtlas] invalid mainTexture: @" + prefab);            return;        }        string mainTexturePath = AssetDatabase.GetAssetPath(mainTexture);        TextureImporter mainTextureImporter = AssetImporter.GetAtPath(mainTexturePath) as TextureImporter;        // 还原texture属性        mainTextureImporter.textureType = TextureImporterType.Advanced;        mainTextureImporter.isReadable = true;        mainTextureImporter.anisoLevel = 0;        mainTextureImporter.npotScale = TextureImporterNPOTScale.ToNearest;        mainTextureImporter.wrapMode = TextureWrapMode.Repeat;        mainTextureImporter.filterMode = FilterMode.Bilinear;        mainTextureImporter.mipmapEnabled = false;        mainTextureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.RGBA32, 100, true);        mainTextureImporter.SetPlatformTextureSettings("Android", 2048, TextureImporterFormat.RGBA32, 100, true);        AssetDatabase.ImportAsset(mainTexturePath, ImportAssetOptions.ForceUpdate);        // 还原material属性        if (material.shader.name.StartsWith("Unlit/Transparent"))            material.shader = Shader.Find("Unlit/Transparent Colored");        else if (material.shader.name.StartsWith("Unlit/Icon"))            material.shader = Shader.Find("Unlit/Icon If");        material.SetTexture("_MainTex", mainTexture);        AssetDatabase.SaveAssets();        // string materialPath = AssetDatabase.GetAssetPath(material);        // AssetDatabase.ImportAsset(materialPath, ImportAssetOptions.ForceUpdate);        Debug.Log("[UIAtlasUtil::UncompressAtlas] optimize success: @" + prefab);    }    public static void UnpackAtlas(string prefab)    {        GameObject go = AssetDatabase.LoadMainAssetAtPath(prefab) as GameObject;        if (null == go)        {            Debug.LogError("[UIAtlasUtil::UnpackAtlas] invalid prefab: @" + prefab);            return;        }        UIAtlas atlas = go.GetComponent<UIAtlas>();        if (null == atlas)        {            Debug.LogError("[UIAtlasUtil::UnpackAtlas] invalid atlas: @" + prefab);            return;        }        string path = prefab.Substring(0, prefab.LastIndexOf('/'));        path += "/sprites/";        if (Directory.Exists(path))        {            Directory.Delete(path, true);        }        Directory.CreateDirectory(path);        EditorUtility.DisplayProgressBar("unpacking", "Plaese wait.", 0);        Texture2D texture = NGUIEditorTools.ImportTexture(atlas.texture, true, true, false);        for (int i = 0; i < atlas.spriteList.Count; ++i)        {            UISpriteData sprite = atlas.spriteList[i];            EditorUtility.DisplayProgressBar("unpacking" + sprite.name + ".png", "Plaese wait.", (float)i / (float)atlas.spriteList.Count);            Color[] pixels = texture.GetPixels(sprite.x, texture.height - sprite.y - sprite.height, sprite.width, sprite.height);            if (null != pixels)            {                Texture2D tex = new Texture2D(sprite.width, sprite.height);                tex.SetPixels(pixels);                File.WriteAllBytes(path + sprite.name + ".png", tex.EncodeToPNG());            }        }        EditorUtility.ClearProgressBar();        /* very slow        foreach (UISpriteData sprite in atlas.spriteList)        {            if (!string.IsNullOrEmpty(path))            {                UIAtlasMaker.SpriteEntry se = UIAtlasMaker.ExtractSprite(atlas, sprite.name);                if (se != null)                {                    byte[] bytes = se.tex.EncodeToPNG();                    File.WriteAllBytes(path + "/" + sprite.name + ".png", bytes);                    Debug.Log("unpacked: " + path + "/" + sprite.name + ".png");                }            }        }*/    }}

阅读全文
0 0
原创粉丝点击