コード例 #1
0
ファイル: AtlasRawEditor.cs プロジェクト: SylarLi/AtlaS
        private static void CreateAtlasRaw()
        {
            var path = AssetDatabase.GetAssetPath(Selection.activeObject);

            path = string.IsNullOrEmpty(path) ? "Assets" : path;
            if (File.Exists(path))
            {
                path = Path.GetDirectoryName(path);
            }
            var atlas = CreateInstance <AtlasRaw>();

            atlas.bins = new BinRaw[0];
            var setting = new PackSetting();

            atlas.maxSize     = setting.maxAtlasSize;
            atlas.padding     = setting.padding;
            atlas.isPOT       = setting.isPOT;
            atlas.forceSquare = setting.forceSquare;
            var assetPath = Path.Combine(path, PackConst.DefaultAtlasAssetName);

            assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath);
            atlas.id  = PackUtil.GenerateAtlasId();
            AssetDatabase.CreateAsset(atlas, assetPath);
            Selection.activeObject = AssetDatabase.LoadAssetAtPath <AtlasRaw>(assetPath);
        }
コード例 #2
0
 public PackSetting(PackSetting data)
 {
     maxAtlasSize = data.maxAtlasSize;
     padding      = data.padding;
     isPOT        = data.isPOT;
     forceSquare  = data.forceSquare;
 }
コード例 #3
0
ファイル: AtlasPacker.cs プロジェクト: SylarLi/AtlaS
        public static AtlasRaw Pack(string targetFolder, IPackSprite[] textures, PackSetting setting)
        {
            EditorUtility.DisplayProgressBar("", "generate atlas...", 0.5f);
            var atlasPath = Path.Combine(targetFolder, PackConst.DefaultAtlasAssetName);

            atlasPath = AssetDatabase.GenerateUniqueAssetPath(atlasPath);
            var atlasRaw = new PackAtlas(setting, atlasPath, textures).GenerateAtlas();

            EditorUtility.ClearProgressBar();
            return(atlasRaw);
        }
コード例 #4
0
 public void Setup(PackSetting setting, BinRaw bin)
 {
     this.setting  = setting;
     this.bin      = bin;
     mainAsset     = bin.main;
     mainAssetPath = AssetDatabase.GetAssetPath(mainAsset);
     mainImporter  = AssetImporter.GetAtPath(mainAssetPath) as TextureImporter;
     if (bin.addition != null)
     {
         addAsset     = bin.addition;
         addAssetPath = AssetDatabase.GetAssetPath(addAsset);
         addImporter  = AssetImporter.GetAtPath(addAssetPath) as TextureImporter;
     }
     transparency   = PackUtil.CheckAtlasBinTranparency(bin);
     maxTextureSize = PackUtil.Scale2POT(Mathf.Max((int)bin.size.x, (int)bin.size.y));
 }
コード例 #5
0
 public PackAtlas(PackSetting setting, string atlasPath, IPackSprite[] sprites)
 {
     mSetting   = setting;
     mAtlasPath = atlasPath;
     mSprites   = sprites;
 }
コード例 #6
0
        /// <summary>
        /// Translate by sprite's type
        /// </summary>
        /// <param name="targetFolder">Target folder for generating atlas or sprite.</param>
        /// <param name="forward">If true, translate sprite to atlas, else translate atlas to sprite</param>
        public void Translate(string targetFolder, bool forward, string resourceFolder = null, PackSetting setting = null)
        {
            var collectors = new List <ICollector>();
            var transfer   = new List <UnityEngine.UI.Sprite>();
            var exclude    = new List <UnityEngine.UI.Sprite>();
            var prefabs    = AssetDatabase.FindAssets("t:prefab").Select(i => AssetDatabase.GUIDToAssetPath(i)).ToArray();

            for (int i = 0; i < prefabs.Length; i++)
            {
                EditorUtility.DisplayProgressBar("Prefab", prefabs[i], (float)i / prefabs.Length);
                var prefabCollector = new PrefabCollector();
                prefabCollector.path = prefabs[i];
                prefabCollector.Collect();
                collectors.Add(prefabCollector);
                transfer.AddRange(prefabCollector.sprites);
            }
            var scenes = AssetDatabase.FindAssets("t:scene").Select(i => AssetDatabase.GUIDToAssetPath(i)).ToArray();

            for (int i = 0; i < scenes.Length; i++)
            {
                EditorUtility.DisplayProgressBar("Scene", scenes[i], (float)i / scenes.Length);
                var sceneCollector = new SceneCollector();
                sceneCollector.path = scenes[i];
                sceneCollector.Collect();
                collectors.Add(sceneCollector);
                transfer.AddRange(sceneCollector.sprites);
            }
            var clips = AssetDatabase.FindAssets("t:animationclip").Select(i => AssetDatabase.GUIDToAssetPath(i)).ToArray();

            for (int i = 0; i < clips.Length; i++)
            {
                EditorUtility.DisplayProgressBar("AnimationClip", clips[i], (float)i / scenes.Length);
                var clipCollector = new AnimationClipCollector();
                clipCollector.path = clips[i];
                clipCollector.Collect();
                exclude.AddRange(clipCollector.sprites);
            }
            // 过滤类型不符的sprite,过滤在AnimationClip引用的sprite,过滤不在resourceFolder中的资源
            for (int i = transfer.Count - 1; i >= 0; i--)
            {
                if (transfer[i] != null &&
                    ((transfer[i].type == UnityEngine.UI.Sprite.Type.Sprite) != forward ||
                     exclude.Any(e => e == transfer[i])))
                {
                    transfer[i] = null;
                }
            }
            if (!string.IsNullOrEmpty(resourceFolder))
            {
                for (int i = transfer.Count - 1; i >= 0; i--)
                {
                    if (transfer[i] != null)
                    {
                        var transferPath = "";
                        if (transfer[i].type == UnityEngine.UI.Sprite.Type.Sprite)
                        {
                            transferPath = AssetDatabase.GetAssetPath(transfer[i].sprite);
                        }
                        else if (transfer[i].type == UnityEngine.UI.Sprite.Type.Atlas)
                        {
                            transferPath = AssetDatabase.GetAssetPath(transfer[i].atlasRaw);
                        }
                        if (!transferPath.Contains(resourceFolder))
                        {
                            transfer[i] = null;
                        }
                    }
                }
            }
            if (forward)
            {
                MapSprite2Atlas(targetFolder, setting, transfer);
            }
            else
            {
                MapAtlas2Sprite(targetFolder, transfer);
            }
            Util.RebindThenTranslate(collectors, transfer);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            EditorUtility.ClearProgressBar();
        }
コード例 #7
0
        private static void MapSprite2Atlas(string targetFolder, PackSetting setting, List <UnityEngine.UI.Sprite> sprites)
        {
            var spritePaths = new List <string>();

            foreach (var sprite in sprites)
            {
                if (sprite != null && sprite.type == UnityEngine.UI.Sprite.Type.Sprite)
                {
                    var path = AssetDatabase.GetAssetPath(sprite.sprite);
                    if (!string.IsNullOrEmpty(path) && !spritePaths.Contains(path))
                    {
                        spritePaths.Add(path);
                    }
                }
            }
            var pathSpriteMap = new Dictionary <string, UnityEngine.UI.Sprite>();
            var spriteGroups  = spritePaths.GroupBy(path =>
            {
                var importer = AssetImporter.GetAtPath(path) as TextureImporter;
                return(importer.spritePackingTag);
            });

            foreach (var group in spriteGroups)
            {
                var groupPaths   = group.ToArray();
                var groupNames   = Util.MapSpritePath2SpriteNameInAtlas(groupPaths);
                var groupSprites = new PackAssetSprite[groupPaths.Length];
                for (int i = 0; i < groupPaths.Length; i++)
                {
                    groupSprites[i] = new PackAssetSprite(groupPaths[i])
                    {
                        name = groupNames[i]
                    };
                    groupSprites[i].quality = PackUtil.CheckTextureCompressed(groupPaths[i]) ? PackQuality.AlphaSplit : PackQuality.Full;
                }
                var groupTag    = string.IsNullOrEmpty(group.Key) ? EmptyTagName : group.Key;
                var groupFolder = Path.Combine(targetFolder, groupTag);
                if (!Directory.Exists(groupFolder))
                {
                    Directory.CreateDirectory(groupFolder);
                }
                var atlasRaw = AtlasPacker.Pack(groupFolder, groupSprites, setting);
                for (int i = 0; i < groupPaths.Length; i++)
                {
                    pathSpriteMap[groupPaths[i]] = new UnityEngine.UI.Sprite(atlasRaw, groupNames[i]);
                }
            }
            ;
            for (int i = 0; i < sprites.Count; i++)
            {
                var sprite = sprites[i];
                if (sprite != null && sprite.type == UnityEngine.UI.Sprite.Type.Sprite)
                {
                    var path = AssetDatabase.GetAssetPath(sprite.sprite);
                    if (!string.IsNullOrEmpty(path))
                    {
                        sprites[i] = pathSpriteMap[path];
                    }
                }
            }
        }
コード例 #8
0
ファイル: AtlasRawEditor.cs プロジェクト: SylarLi/AtlaS
        public override void OnInspectorGUI()
        {
            OnValidateSelected();
            var atlas = target as AtlasRaw;

            EditorGUILayout.GetControlRect(false, 2);
            int clickIndex = AtlasEditorUtil.TitleBar(new GUIContent[]
            {
                new GUIContent("+File"),
                new GUIContent("+Folder"),
            });

            if (clickIndex == 0)
            {
                DisplayImportMenu(atlas, false);
            }
            else if (clickIndex == 1)
            {
                DisplayImportMenu(atlas, true);
            }
            mRepackFold = AtlasEditorUtil.ToggleBar(new GUIContent("Settings"), mRepackFold);
            if (mRepackFold)
            {
                if (!mPackDataInit)
                {
                    mPackDataInit = true;
                    mSetting      = new PackSetting(atlas.maxSize, atlas.padding, atlas.isPOT, atlas.forceSquare);
                }
                EditorGUI.indentLevel += 1;
                mSetting.maxAtlasSize  = EditorGUILayout.IntPopup("Max Size", mSetting.maxAtlasSize, Array.ConvertAll(PackConst.AtlasSizeList, value => value.ToString()), PackConst.AtlasSizeList);
                mSetting.padding       = EditorGUILayout.IntField("Padding", mSetting.padding);
                mSetting.isPOT         = EditorGUILayout.Toggle("Power Of 2", mSetting.isPOT);
                GUI.enabled            = mSetting.isPOT;
                if (!mSetting.isPOT)
                {
                    mSetting.forceSquare = false;
                }
                mSetting.forceSquare = EditorGUILayout.Toggle("Force Square", mSetting.forceSquare);
                GUI.enabled          = true;
                var rect = EditorGUILayout.GetControlRect(false, 20);
                if (GUI.Button(new Rect(rect.center.x - 75, rect.y, 150, rect.height), "Repack"))
                {
                    AtlasPacker.Repack(atlas, null, mSetting);
                }
                EditorGUI.indentLevel -= 1;
                EditorGUILayout.Space();
            }
            EditorGUI.BeginChangeCheck();
            mSearchPattern = AtlasEditorUtil.SearchBar(new GUIContent("Search Sprite"), mSearchPattern);
            if (EditorGUI.EndChangeCheck() || mAtlasDirty)
            {
                mSearchResults.Clear();
                if (!string.IsNullOrEmpty(mSearchPattern))
                {
                    mSearchResults.AddRange(AtlasEditorUtil.SearchSprites(atlas, 0, mSearchPattern));
                }
            }
            if (mAtlasDirty)
            {
                mAtlasDirty  = false;
                mSelectedBin = Mathf.Clamp(mSelectedBin, 0, atlas.bins.Length - 1);
                mSelectedSprites.Clear();
            }
            EditorGUI.indentLevel += 1;
            if (!string.IsNullOrEmpty(mSearchPattern))
            {
                EditorGUILayout.LabelField(string.Format("{0} results", mSearchResults.Count));
            }
            if (mSearchResults != null && mSearchResults.Count > 0)
            {
                OnValidateResult();
                OnSearchResultGUI();
            }
            EditorGUI.indentLevel -= 1;
            if (atlas.bins.Length > 0)
            {
                var titleRect = EditorGUILayout.GetControlRect(false, EditorStyles.toolbar.fixedHeight);
                var controlId = GUIUtility.GetControlID(FocusType.Passive);
                var eventType = Event.current.GetTypeForControl(controlId);
                if (eventType == EventType.Repaint)
                {
                    EditorStyles.toolbar.Draw(titleRect, GUIContent.none, controlId);
                }
                var binNames   = Array.ConvertAll(atlas.bins, i => PackUtil.GetDisplayName(i));
                var binIndexes = new int[binNames.Length];
                for (int i = 0; i < binNames.Length; i++)
                {
                    binIndexes[i] = i;
                }
                mSelectedBin = EditorGUI.IntPopup(new Rect(10, titleRect.y, titleRect.width - 10, titleRect.height), "Preview Bin", mSelectedBin, binNames, binIndexes, EditorStyles.toolbarPopup);
                mSelectedBin = Mathf.Clamp(mSelectedBin, 0, atlas.bins.Length - 1);
                EditorGUILayout.Space();
                var bin         = atlas.bins[mSelectedBin];
                var previewRect = EditorGUILayout.GetControlRect(false, 512);
                previewRect.width  = Mathf.Min(previewRect.width, (float)bin.main.width / bin.main.height * previewRect.height);
                previewRect.height = (float)bin.main.height / bin.main.width * previewRect.width;
                OnPreviewBin(previewRect);
            }
        }
コード例 #9
0
        protected virtual BinRaw[] PackSprites(PackSetting setting, IPackSprite[] sprites)
        {
            var textures    = sprites.Select(sprite => new Packer.Area((int)sprite.rect.width, (int)sprite.rect.height)).ToArray();
            var spriteRaws  = new List <SpriteRaw>();
            var packers     = new List <Packer>();
            var sizeList    = PackConst.AtlasSizeList;
            var maxSize     = setting.maxAtlasSize;
            var padding     = setting.padding;
            var isPOT       = forcePowerOf2 || setting.isPOT;
            var forceSquare = this.forceSquare || setting.forceSquare;
            var index       = 0;

            while (index < textures.Length)
            {
                var         texArea = textures[index];
                Packer.Rect texRect = null;
                for (int i = 0; i < packers.Count; i++)
                {
                    var packer = packers[i];
                    while (true)
                    {
                        if (packer.Push(texArea, out texRect))
                        {
                            spriteRaws.Add(new SpriteRaw()
                            {
                                bin  = i,
                                rect = new Rect(texRect.x, texRect.y, texRect.width, texRect.height),
                            });
                            break;
                        }
                        var width  = packer.bin.width;
                        var height = packer.bin.height;
                        if (forceSquare)
                        {
                            width  *= 2;
                            height *= 2;
                        }
                        else
                        {
                            if (width > height)
                            {
                                height *= 2;
                            }
                            else
                            {
                                width *= 2;
                            }
                        }
                        if (width > maxSize || height > maxSize)
                        {
                            break;
                        }
                        packer.Extend(new Packer.Bin(width, height));
                    }
                    if (texRect != null)
                    {
                        break;
                    }
                }
                if (texRect == null)
                {
                    packers.Add(new Packer(Packer.Algorithm.AdvancedHorizontalSkyline,
                                           new Packer.Bin(sizeList[0], sizeList[0]), padding));
                }
                else
                {
                    index += 1;
                }
            }

            var bins = new BinRaw[packers.Count];

            for (int i = 0; i < packers.Count; i++)
            {
                bins[i]      = new BinRaw();
                bins[i].size = !isPOT && !forceSquare ?
                               Vector2.zero : new Vector2(packers[i].bin.width, packers[i].bin.height);
            }
            if (!isPOT && !forceSquare)
            {
                for (int i = 0; i < spriteRaws.Count; i++)
                {
                    var sprite = spriteRaws[i];
                    var bin    = bins[sprite.bin];
                    bin.size = new Vector2(
                        Mathf.Max(bin.size.x, sprite.rect.xMax),
                        Mathf.Max(bin.size.y, sprite.rect.yMax));
                }
                if (forceMultiplyOf4)
                {
                    foreach (var bin in bins)
                    {
                        bin.size = new Vector2(
                            Mathf.CeilToInt(bin.size.x / 4) * 4,
                            Mathf.CeilToInt(bin.size.y / 4) * 4);
                    }
                }
            }

            for (int i = 0; i < sprites.Length; i++)
            {
                var sprite    = sprites[i];
                var spriteRaw = spriteRaws[i];
                spriteRaw.name   = sprite.name.Replace("\\", "/");
                spriteRaw.border = sprite.border;
                spriteRaw.pivot  = sprite.pivot;
                var rect   = spriteRaw.rect;
                var binRaw = bins[spriteRaw.bin];
                binRaw.sprites = binRaw.sprites ?? new SpriteRaw[0];
                Array.Resize(ref binRaw.sprites, binRaw.sprites.Length + 1);
                binRaw.sprites[binRaw.sprites.Length - 1] = spriteRaw;
                var main   = binRaw.main;
                var add    = binRaw.addition;
                var colors = sprite.Read();
                if (main == null)
                {
                    main = PackUtil.CreateBlankTexture((int)binRaw.size.x, (int)binRaw.size.y,
                                                       !alphaSplit && transparency ? TextureFormat.RGBA32 : TextureFormat.RGB24);
                    main.hideFlags = HideFlags.DontUnloadUnusedAsset;
                    binRaw.main    = main;
                }
                main.SetPixels(
                    (int)rect.x, (int)rect.y,
                    (int)rect.width, (int)rect.height,
                    colors);
                if (alphaSplit && transparency)
                {
                    if (add == null)
                    {
                        add             = PackUtil.CreateBlankTexture((int)binRaw.size.x, (int)binRaw.size.y, TextureFormat.RGB24);
                        add.hideFlags   = HideFlags.DontUnloadUnusedAsset;
                        binRaw.addition = add;
                    }
                    for (int c = 0; c < colors.Length; c++)
                    {
                        colors[c] = new Color(colors[c].a, 0, 0);
                    }
                    add.SetPixels(
                        (int)rect.x, (int)rect.y,
                        (int)rect.width, (int)rect.height,
                        colors);
                }
            }

            return(bins);
        }
コード例 #10
0
 public void Setup(PackSetting setting, IPackSprite[] sprites, bool transparency)
 {
     mSetting      = setting;
     mSprites      = sprites;
     mTransparency = transparency;
 }
コード例 #11
0
ファイル: AtlasPacker.cs プロジェクト: SylarLi/AtlaS
        public static AtlasRaw Repack(AtlasRaw atlasRaw, IPackSprite[] textures = null, PackSetting setting = null)
        {
            EditorUtility.DisplayProgressBar("", "repack atlas...", 0.5f);
            textures = textures ?? PackAtlasSprite.ListSprites(atlasRaw);
            setting  = setting ?? new PackSetting(atlasRaw.maxSize, atlasRaw.padding, atlasRaw.isPOT, atlasRaw.forceSquare);
            var atlasPath = AssetDatabase.GetAssetPath(atlasRaw);

            atlasRaw = new PackAtlas(setting, atlasPath, textures).GenerateAtlas();
            EditorUtility.ClearProgressBar();
            if (atlasRaw == null)
            {
                Debug.LogError("Pack failed.");
                return(null);
            }
            RefreshUI();
            return(atlasRaw);
        }