针对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
- 针对Unity NGUI图集的Alpha通道分离优化
- Unity Android平台下针对Alpha分离的优化---三张Alpha贴图合并为一张
- NGUI下alpha通道的分离与合并
- unity游戏优化之ETC压缩和 Alpha通道处理,让飞起来【NGUI篇】
- Unity工程里图片的RGB和Alpha通道的分离,以及显示所有带有Alpha通道贴图的Material
- Unity工程里图片的RGB和Alpha通道的分离,以及显示所有带有Alpha通道贴图的Material
- 【改进版】Unity工程里图片的RGB和Alpha通道的分离
- Unity工程里图片的RGB和Alpha通道的分离
- unity游戏优化之ETC压缩和 Alpha通道处理
- unity游戏优化之ETC压缩和 Alpha通道处理
- unity游戏优化之ETC压缩和 Alpha通道处理
- 对纹理进行Alpha通道分离的好处
- Unity3D NGUI分离RGBA通道
- unity中基于alpha通道的shadow volume实现
- 移除Unity工程里所有图片的Alpha通道
- 移除Unity工程里所有图片的Alpha通道
- 图片的alpha 通道
- Unity播放带Alpha通道的视频(unity play channel movie)
- hdu5446(组合数取模 Lucas定理 中国剩余定理)
- SDL系列讲解(十一) SDL_QUIT流程
- 统计个位数字
- (webstorm的css编写插件)Emmet:HTML/CSS代码快速编写神器
- 迁移学习全面概述
- 针对Unity NGUI图集的Alpha通道分离优化
- SDL系列讲解(十二)创建窗口流程
- 面试题24:二叉搜索树的后序遍历序列
- Regular Expression Matching--LeetCode
- poj 2965 The Pilots Brothers' refrigerator 【dfs+枚举】【双十一大礼包】【刷题计划】
- 预设置只读文件系统squashfs上的文件的扩展属性的方法
- 惊群
- GAN和DCGAN的讨论
- android SDL系列讲解(十三) 播放音乐库 SDL_mixer教程