public static void RemoveSpriteFromAtlas(string assetPath)
        {
            if (!LoadSettings(out AtlasGeneratorSettings generatorSettings, out AtlasGeneratorAtlasSettings atlasSettings))
            {
                return;
            }

            var dirty = TryGetMatchedRule(assetPath, generatorSettings, out var matchedRule);

            if (!dirty)
            {
                return;
            }

            AtlasGenerator.RemoveFromAtlas(matchedRule, null, assetPath);
            AssetDatabase.SaveAssets();
        }
        public static bool ApplyGenerationRule(
            string assetPath,
            string movedFromAssetPath)
        {
            var dirty             = false;
            var generatorSettings = AtlasGeneratorSettings.Asset;
            var atlasSettings     = AtlasGeneratorAtlasSettings.Asset;

            if (!string.IsNullOrEmpty(movedFromAssetPath) && TryGetMatchedRule(movedFromAssetPath, generatorSettings, out var oldMatchedRule))
            {
                dirty |= AtlasGenerator.RemoveFromAtlas(oldMatchedRule, movedFromAssetPath, assetPath);
            }

            if (TryGetMatchedRule(assetPath, generatorSettings, out var matchedRule))
            {
                var atlas = AtlasGenerator.CreateOrUpdateAtlas(generatorSettings, atlasSettings, matchedRule, assetPath);
                dirty = true;
                Log(LogType.Log, $"Added sprite {assetPath} to atlas {atlas.name}");
            }

            return(dirty);
        }
        public static void ApplyRules(AtlasGeneratorSettings settings)
        {
            var atlasSettings = AtlasGeneratorAtlasSettings.Asset;

            if (atlasSettings == null)
            {
                Debug.LogError($"[{nameof(RuleChangeHandler)}] Atlas settings file not found.");
                return;
            }
            var defaultSettings = atlasSettings.defaultAtlasSettings;

            var dirty = false;

            var packedSprites   = new HashSet <string>();
            var existingAtlases = (settings.generatedAtlases)
                                  .ToList()
                                  .Select(path => LoadAtlas(path, settings))
                                  .Where(atlas => atlas != null)
                                  .ToList();
            var spritesRoot     = string.IsNullOrEmpty(settings.spritesRoot.Trim()) ? "Assets" : settings.spritesRoot.TrimEndPath();
            var existingSprites = AssetEditorTools.GetAssetsPaths <Texture2D>(new string[] { spritesRoot })
                                  .Where(p => settings.rules.Any(rule => rule.Match(p)));

            foreach (var atlas in existingAtlases)
            {
                var packables          = atlas.GetPackables();
                var spritesToRemove    = new List <string>();
                var currentPathToAtlas = AssetDatabase.GetAssetPath(atlas).FixUnityPath();
                foreach (var packable in packables)
                {
                    if (!(packable is Texture2D))
                    {
                        continue;
                    }

                    var spritePath = AssetDatabase.GetAssetPath(packable);
                    spritesToRemove.Add(spritePath);
                    foreach (var rule in settings.rules)
                    {
                        if (!rule.Match(spritePath))
                        {
                            continue;
                        }

                        var pathToAtlas = rule.ParseAtlasReplacement(spritePath);
                        pathToAtlas = rule.GetFullPathToAtlas(pathToAtlas);
                        if (!pathToAtlas.Equals(currentPathToAtlas, StringComparison.InvariantCultureIgnoreCase))
                        {
                            continue;
                        }

                        spritesToRemove.Remove(spritePath);
                        packedSprites.Add(spritePath);

                        var appliedSettings = rule.applyCustomSettings ? rule.atlasSettings : defaultSettings;
                        if ((rule.applyCustomSettings && rule.atlasSettingsApplicationMode == AtlasSettingsApplicationMode.AlwaysOverwriteAtlasSettings) ||
                            (!rule.applyCustomSettings && atlasSettings.atlasSettingseApplicationMode == AtlasSettingsApplicationMode.AlwaysOverwriteAtlasSettings))
                        {
                            if (!atlas.CheckSettings(appliedSettings))
                            {
                                atlas.ApplySettings(appliedSettings);
                                dirty = true;
                            }
                        }

                        break;
                    }
                }
                atlas.RemoveSprites(spritesToRemove.ToArray());
                dirty |= AtlasGenerator.DeleteEmptyAtlas(atlas);
            }

            if (dirty)
            {
                AssetDatabase.SaveAssets();
            }

            var spritesToPack = existingSprites.Except(packedSprites).ToArray();

            if (spritesToPack.Length > 0)
            {
                AtlasGeneratorPostprocessor.PackIntoAtlases(spritesToPack, new string[] { }, new string[] { });
            }

            CheckForCollisions(settings.generatedAtlases);
        }