[Unity3D] 5.0 图集合并扩展工具,用于解决UGUI与AssetBundle打包造成资源包过大的问题

UGUI Image已Sprite为主,而简单的合并图集可以使用自带的SpritePacker。
而当在使用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(10241024, TextureFormat.ARGB32, true);
            Rect[] uvs 
= UITexturePacker.PackTextures(tex, texList.ToArray(), 44, 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使用,注意最好保存好合并前的源文件,不然可能造成新增图片打图集后对应不上从而造成引用丢失。
阅读更多
换一批

没有更多推荐了,返回首页