[Unity3D] 5.0 图集合并扩展工具,用于解决UGUI与AssetBundle打包造成资源包过大的问题
UGUI Image已Sprite为主,而简单的合并图集可以使用自带的SpritePacker。
而当在使用AssetBundle的时候情况有些不同,会造成每个AB都会引入完整的Sprite图集,显然就增加了AB的大小,重复资源。
为了解决这个问题我们可以手动合并图集,那么方案也有多种,这里我们可以编辑器自带的API来实现一个小的图集合并工具。
使用方法很简单,可以修改源码中的路径,可以将多个Single Sprite合成一个Multi Sprite。然后在供,UGUI使用,注意最好保存好合并前的源文件,不然可能造成新增图片打图集后对应不上从而造成引用丢失。
而当在使用AssetBundle的时候情况有些不同,会造成每个AB都会引入完整的Sprite图集,显然就增加了AB的大小,重复资源。
为了解决这个问题我们可以手动合并图集,那么方案也有多种,这里我们可以编辑器自带的API来实现一个小的图集合并工具。
private
static
bool
CombineSpritesHelper(
string
path,
string
dpath,
string
name,
int
padding)
{
string[] paths = AssetDatabase.FindAssets("t:sprite", new string[] { path });
List<Sprite> spriteList = new List<Sprite>();
List<Texture2D> texList = new List<Texture2D>();
foreach (var o in paths)
{
Sprite s = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(o), typeof(Sprite)) as Sprite;
if (null != s)
{
spriteList.Add(s);
texList.Add(s.texture);
}
}
if (texList.Count > 0)
{
Texture2D tex = new Texture2D(1024, 1024, TextureFormat.ARGB32, true);
Rect[] uvs = UITexturePacker.PackTextures(tex, texList.ToArray(), 4, 4, padding, 1024);
if (null == uvs)
{
EditorUtility.DisplayDialog(path, "图集超过1024,需要分组成多张图集", "点击退出");
Object.DestroyImmediate(tex);
tex = null;
return false;
}
else
{
List<SpriteMetaData> metaList = new List<SpriteMetaData>();
for (int i = 0; i < uvs.Length; ++i)
{
SpriteMetaData data = new SpriteMetaData();
data.alignment = (int)SpriteAlignment.Center;
data.border = spriteList[i].border;
data.name = spriteList[i].name;
data.pivot = spriteList[i].pivot;
data.rect = new Rect(uvs[i].x * tex.width, uvs[i].y * tex.height, uvs[i].width * tex.width, uvs[i].height * tex.height);
metaList.Add(data);
}
//string dpath = path.Substring(0, path.Length - obj.name.Length) + "SpriteSet";
if (!System.IO.Directory.Exists(dpath))
{
System.IO.Directory.CreateDirectory(dpath);
}
string file = dpath + "/" + name + ".png";
if (System.IO.File.Exists(file))
{
System.IO.File.Delete(file);
}
System.IO.File.WriteAllBytes(file, tex.EncodeToPNG());
AssetDatabase.ImportAsset(file, ImportAssetOptions.ForceUpdate);
TextureImporter importer = AssetImporter.GetAtPath(file) as TextureImporter;
importer.spritesheet = metaList.ToArray();
importer.spriteImportMode = SpriteImportMode.Multiple;
importer.textureType = TextureImporterType.Sprite;
importer.textureFormat = TextureImporterFormat.ARGB32;
importer.mipmapEnabled = true;
importer.mipmapFilter = TextureImporterMipFilter.BoxFilter;
importer.assetBundleName = "ui_image/" + name.ToLower();
AssetDatabase.ImportAsset(file);
AssetDatabase.Refresh();
}
}
return true;
}
[MenuItem( " Tool/Combine Sprites " )]
[MenuItem( " Assets/Tool/Combine Sprites " )]
public static void CombineSprites()
{
EditorUtility.DisplayProgressBar("Combine Sprites", "Initializing ", 0);
try
{
Object obj = Selection.activeObject;
string path = AssetDatabase.GetAssetPath(obj.GetInstanceID());
string dpath = path.Substring(0, path.Length - obj.name.Length) + "SpriteSet";
if (System.IO.Directory.Exists(path))
{
string[] directories = System.IO.Directory.GetDirectories(path);
int count = 0;
if (directories.Length > 0)
{
foreach (var directory in directories)
{
count++;
EditorUtility.DisplayProgressBar("Combine Sprites", string.Format("combing {0}", count), (float)(count) / (directories.Length));
if (!CombineSpritesHelper(directory, dpath, string.Concat(obj.name, "_", count.ToString()), 1))
{
break;
}
}
}
else
{
EditorUtility.DisplayProgressBar("Combine Sprites", "combing 0", 1);
CombineSpritesHelper(path, dpath, obj.name, 1);
}
}
}
catch (System.Exception e)
{
Debug.LogError(e);
}
EditorUtility.ClearProgressBar();
}
{
string[] paths = AssetDatabase.FindAssets("t:sprite", new string[] { path });
List<Sprite> spriteList = new List<Sprite>();
List<Texture2D> texList = new List<Texture2D>();
foreach (var o in paths)
{
Sprite s = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(o), typeof(Sprite)) as Sprite;
if (null != s)
{
spriteList.Add(s);
texList.Add(s.texture);
}
}
if (texList.Count > 0)
{
Texture2D tex = new Texture2D(1024, 1024, TextureFormat.ARGB32, true);
Rect[] uvs = UITexturePacker.PackTextures(tex, texList.ToArray(), 4, 4, padding, 1024);
if (null == uvs)
{
EditorUtility.DisplayDialog(path, "图集超过1024,需要分组成多张图集", "点击退出");
Object.DestroyImmediate(tex);
tex = null;
return false;
}
else
{
List<SpriteMetaData> metaList = new List<SpriteMetaData>();
for (int i = 0; i < uvs.Length; ++i)
{
SpriteMetaData data = new SpriteMetaData();
data.alignment = (int)SpriteAlignment.Center;
data.border = spriteList[i].border;
data.name = spriteList[i].name;
data.pivot = spriteList[i].pivot;
data.rect = new Rect(uvs[i].x * tex.width, uvs[i].y * tex.height, uvs[i].width * tex.width, uvs[i].height * tex.height);
metaList.Add(data);
}
//string dpath = path.Substring(0, path.Length - obj.name.Length) + "SpriteSet";
if (!System.IO.Directory.Exists(dpath))
{
System.IO.Directory.CreateDirectory(dpath);
}
string file = dpath + "/" + name + ".png";
if (System.IO.File.Exists(file))
{
System.IO.File.Delete(file);
}
System.IO.File.WriteAllBytes(file, tex.EncodeToPNG());
AssetDatabase.ImportAsset(file, ImportAssetOptions.ForceUpdate);
TextureImporter importer = AssetImporter.GetAtPath(file) as TextureImporter;
importer.spritesheet = metaList.ToArray();
importer.spriteImportMode = SpriteImportMode.Multiple;
importer.textureType = TextureImporterType.Sprite;
importer.textureFormat = TextureImporterFormat.ARGB32;
importer.mipmapEnabled = true;
importer.mipmapFilter = TextureImporterMipFilter.BoxFilter;
importer.assetBundleName = "ui_image/" + name.ToLower();
AssetDatabase.ImportAsset(file);
AssetDatabase.Refresh();
}
}
return true;
}
[MenuItem( " Tool/Combine Sprites " )]
[MenuItem( " Assets/Tool/Combine Sprites " )]
public static void CombineSprites()
{
EditorUtility.DisplayProgressBar("Combine Sprites", "Initializing ", 0);
try
{
Object obj = Selection.activeObject;
string path = AssetDatabase.GetAssetPath(obj.GetInstanceID());
string dpath = path.Substring(0, path.Length - obj.name.Length) + "SpriteSet";
if (System.IO.Directory.Exists(path))
{
string[] directories = System.IO.Directory.GetDirectories(path);
int count = 0;
if (directories.Length > 0)
{
foreach (var directory in directories)
{
count++;
EditorUtility.DisplayProgressBar("Combine Sprites", string.Format("combing {0}", count), (float)(count) / (directories.Length));
if (!CombineSpritesHelper(directory, dpath, string.Concat(obj.name, "_", count.ToString()), 1))
{
break;
}
}
}
else
{
EditorUtility.DisplayProgressBar("Combine Sprites", "combing 0", 1);
CombineSpritesHelper(path, dpath, obj.name, 1);
}
}
}
catch (System.Exception e)
{
Debug.LogError(e);
}
EditorUtility.ClearProgressBar();
}
使用方法很简单,可以修改源码中的路径,可以将多个Single Sprite合成一个Multi Sprite。然后在供,UGUI使用,注意最好保存好合并前的源文件,不然可能造成新增图片打图集后对应不上从而造成引用丢失。