接上文:这次主要提供了分离贴图的方法。废话不多说,上代码,里面都有注释。
using System.IO;
using UnityEditor;
using UnityEngine;
public class TextureHandler
{
//来给工具一个快捷键
[MenuItem("Tools/NGUI/ETC1+Alpha", false, 11)]
static void SingleCreateUIAtlasPrefab()
{
CreateUIAtlasPrefab(Selection.activeObject);
AssetDatabase.Refresh();
}
private static void CreateUIAtlasPrefab(Object ob)
{
string path = AssetDatabase.GetAssetPath(ob);
if (string.IsNullOrEmpty(path) || !isTextureFile(path))
{
Debug.LogError("未选择图片或者选中的对象不是图片");
return;
}
if (Path.GetExtension(path) == ".png" && !path.Contains("_Alpha") && !path.Contains("_RGB"))
{
ShowProgress(path, 0.5f);
#region 根据图片创建材质对象
//需要特定的Shader,将分离成的ETC1+Alpha贴图进行叠加
Material mat = new Material(Shader.Find("UI/UI_ETC"));
mat.name = ob.name;
AssetDatabase.CreateAsset(mat, path.Replace(".png", ".mat"));
//设置图片可读
SetTextureReadable(path);
//分离图片 RGB+Alpha
SeperateRGBAndAlpha(path);
//设置原图
TextureSetting(path, TextureImporterType.Advanced, TextureImporterFormat.ETC_RGB4, false);
//给材质赋值贴图信息
Texture2D _mainTex = AssetDatabase.LoadAssetAtPath(path.Replace(".png", "_RGB.png"), typeof(Texture2D)) as Texture2D;
Texture2D _alphaTex = AssetDatabase.LoadAssetAtPath(path.Replace(".png", "_Alpha.png"), typeof(Texture2D)) as Texture2D;
mat.SetTexture("_MainTex", _mainTex);
mat.SetTexture("_AlphaTex", _alphaTex);
#endregion
#region Atlas信息赋值
GameObject go = null;
UIAtlas uiAtlas = null;
if ((go = AssetDatabase.LoadAssetAtPath(path.Replace(".png", ".prefab"), typeof(GameObject)) as GameObject) != null)
{
//如果有Atlas图集,那么修改图集信息
uiAtlas = SetAtlasInfo(go, path, mat);
}
else
{
//如果没有Atlas图集,就创建图集
go = new GameObject(ob.name);
go.AddComponent<UIAtlas>();
uiAtlas = SetAtlasInfo(go, path, mat);
//创建Atlas预制体
CreatAtlasPrefab(go, ob.name, path);
}
#endregion
//完毕!
AssetDatabase.SaveAssets();
EditorUtility.ClearProgressBar();
}
}
/// <summary>
/// 创建预制体
/// </summary>
/// <returns></returns>
static Object CreatAtlasPrefab(GameObject go, string name, string path)
{
Object tmpPrefab = PrefabUtility.CreateEmptyPrefab(path.Replace(".png", ".prefab"));
tmpPrefab = PrefabUtility.ReplacePrefab(go, tmpPrefab, ReplacePrefabOptions.ConnectToPrefab);
Object.DestroyImmediate(go);
return tmpPrefab;
}
/// <summary>
/// 设置图集信息
/// </summary>
static UIAtlas SetAtlasInfo(GameObject go, string path, Material mat)
{
if (AssetDatabase.LoadAssetAtPath(path.Replace(".png", ".txt"), typeof(TextAsset)))
{
UIAtlas uiAtlas = go.GetComponent<UIAtlas>();
uiAtlas.spriteMaterial = mat;
TextAsset ta = AssetDatabase.LoadAssetAtPath(path.Replace(".png", ".txt"), typeof(TextAsset)) as TextAsset;
NGUIJson.LoadSpriteData(uiAtlas, ta);
uiAtlas.MarkAsChanged();
return uiAtlas;
}
return null;
}
public static float sizeScale = 1f;
/// <summary>
/// 分离RGB和Alpha
/// </summary>
/// <param name="texturePath"></param>
static void SeperateRGBAndAlpha(string texturePath)
{
Texture2D sourcetex = AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)) as Texture2D;
if (!sourcetex)
{
Debug.LogError("没有找到图片 : " + texturePath);
return;
}
//创建贴图
Texture2D rgbTex = new Texture2D(sourcetex.width, sourcetex.height, TextureFormat.RGB24, true);
Texture2D alphaTex = new Texture2D((int)(sourcetex.width * sizeScale), (int)(sourcetex.height * sizeScale), TextureFormat.RGB24, true);
for (int i = 0; i < sourcetex.width; i++)
{
for (int j = 0; j < sourcetex.height; j++)
{
//获取像素颜色
Color color = sourcetex.GetPixel(i, j);
//RGB
Color rgbColor = color;
//Alpha
Color alphaColor = color;
alphaColor.r = color.a;
alphaColor.g = color.a;
alphaColor.b = color.a;
//设置像素颜色
rgbTex.SetPixel(i, j, rgbColor);
alphaTex.SetPixel((int)(i * sizeScale), (int)(j * sizeScale), alphaColor);
}
}
rgbTex.Apply();
alphaTex.Apply();
//创建图片
byte[] bytes = rgbTex.EncodeToPNG();
WriteToPNG(texturePath.Replace(".png", "_RGB.png"), bytes);
bytes = alphaTex.EncodeToPNG();
WriteToPNG(texturePath.Replace(".png", "_Alpha.png"), bytes);
Debug.Log("成功分离图片:" + texturePath);
}
static void WriteToPNG(string path, byte[] bytes)
{
File.WriteAllBytes(path, bytes);
AssetDatabase.Refresh();
TextureSetting(path, TextureImporterType.Advanced, TextureImporterFormat.ETC_RGB4, false);
}
/// <summary>
/// 设置图片格式
/// </summary>
static void TextureSetting(string path, TextureImporterType mTextureImporterType = TextureImporterType.Advanced, TextureImporterFormat mTextureImporterFormat = TextureImporterFormat.RGBA32, bool readEnable = false)
{
//纹理导入器
TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
if (textureImporter == null) return;
textureImporter.textureType = mTextureImporterType;
if (textureImporter.textureType == TextureImporterType.Advanced)
{
textureImporter.spriteImportMode = SpriteImportMode.None;
textureImporter.mipmapEnabled = false;
textureImporter.isReadable = readEnable;
textureImporter.alphaIsTransparency = false;
}
else if (textureImporter.textureType == TextureImporterType.Sprite)
{
textureImporter.mipmapEnabled = false;
}
textureImporter.SetPlatformTextureSettings("Android", 2048, mTextureImporterFormat);
textureImporter.SetPlatformTextureSettings("Windows", 2048, mTextureImporterFormat);
textureImporter.SetPlatformTextureSettings("iPhone", 2048, TextureImporterFormat.PVRTC_RGB4);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
/// <summary>
/// 设置纹理格式
/// </summary>
/// <param name="path"></param>
static void SetTextureReadable(string path)
{
//纹理导入器
TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
if (textureImporter == null) return;
textureImporter.textureType = TextureImporterType.Advanced;
//设置纹理可写
textureImporter.isReadable = true;
//导入指定路径资源
AssetDatabase.ImportAsset(path);
}
/// <summary>
/// 显示进度条
/// </summary>
/// <param name="path"></param>
/// <param name="val"></param>
static void ShowProgress(string path, float val)
{
EditorUtility.DisplayProgressBar("批量处理中...", string.Format("Please wait... Path:{0}", path), val);
}
/// <summary>
/// 判断是否是图片
/// </summary>
/// <param name="_path"></param>
/// <returns></returns>
static bool isTextureFile(string _path)
{
string path = _path.ToLower();
return path.EndsWith(".psd") || path.EndsWith(".tga") || path.EndsWith(".png") || path.EndsWith(".jpg") || path.EndsWith(".dds") || path.EndsWith(".bmp") || path.EndsWith(".tif") || path.EndsWith(".gif");
}
}
这里需要注意的一点是:这里需要配合特定的Shader,对RGB+Alpha进行分别的采样叠加,最终输出对应的像素。具体Shader会在接下来的博客中进行分享。