Unity · · 2 min read

Quickly update your Sprite Atlas in Unity

Here is a simple tool you can use to automate the process.

Quickly update your Sprite Atlas in Unity

I was surprised to learn that Unity doesn't have a quick way of updating the contents of a sprite atlas. The standard workflow of adding each sprite by hand is tedious to say the least!

Here is a simple tool you can use to automate the process. Just create a new cs file in your project's Editor folder and include the code below. This works fine in Unity 6. I haven't tried any older versions.

Once built, you should get a new menu option under Tools - Sprite Atlas Updater. If you select it, you'll see this dialog box:

Drag the Sprite Atlas you want to update into the first field and drag a folder of images into the second field, press Update Atlas and the atlas will be repacked!


using UnityEditor;
using UnityEditor.U2D;
using UnityEngine;
using UnityEngine.U2D;
using Object = UnityEngine.Object;

namespace ArchitectOfRuin
{
    public class SpriteAtlasUpdater : EditorWindow
    {
        private DefaultAsset folder;
        private string assetPath;
        private SpriteAtlas atlasToUpdate;

        private void OnGUI()
        {
            atlasToUpdate = (SpriteAtlas) EditorGUILayout.ObjectField(
                "Sprite Atlas",
                atlasToUpdate,
                typeof(SpriteAtlas),
                false);
                
            assetPath = AssetDatabase.GetAssetPath(atlasToUpdate);
            
            folder = (DefaultAsset) EditorGUILayout.ObjectField(
                "Sprites Folder",
                folder,
                typeof(DefaultAsset),
                false);

            if (GUILayout.Button("Update Atlas"))
                UpdateAtlas();
        }

        [MenuItem("Tools/Sprite Atlas Updater")]
        public static void ShowWindow()
        {
            GetWindow<SpriteAtlasUpdater>("Sprite Atlas Updater");
        }

        private void UpdateAtlas()
        {
            if (assetPath.Length == 0)
            {
                Debug.LogError("No asset path specified.");
                return;
            }

            if (!folder)
            {
                Debug.LogError("No folder assigned.");
                return;
            }

            // Add the .spriteatlasv2 extension if it's missing.
            if (!assetPath.EndsWith(".spriteatlasv2"))
                assetPath += ".spriteatlasv2";

            var spriteAtlas = new SpriteAtlas();

            // Find all the sprites in the folder.
            var folderPath = AssetDatabase.GetAssetPath(folder);
            var guids = AssetDatabase.FindAssets(
                "t:Sprite",
                new[] { folderPath });
                
            if (guids.Length == 0)
            {
                Debug.LogWarning($"No sprites found in {folderPath}.");
                return;
            }

            // Load the sprites as objects for packing.
            var objectsForPacking = new Object[guids.Length];
            for (var i = 0; i < guids.Length; i++)
            {
                var spritePath = AssetDatabase.GUIDToAssetPath(guids[i]);
                var sprite = AssetDatabase.LoadAssetAtPath<Sprite>(spritePath);
                if (sprite)
                {
                    objectsForPacking[i] = sprite;
                }
            }

            ReplaceAtlasPackables(assetPath, objectsForPacking);
            AssetDatabase.Refresh();
            Debug.Log($"Updated '{spriteAtlas.name}' with {objectsForPacking.Length} sprites from '{folderPath}'.");
        }

        private static void ReplaceAtlasPackables(
            string atlasPath, 
            params Object[] sprites) 
        {
            // Load the sprite atlas.
            var atlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>(atlasPath);
            if (!atlas)
                return;

            // Load the sprite atlas asset.
            var atlasAsset = SpriteAtlasAsset.Load(atlasPath);
            if (!atlasAsset)
                return;

            // Clear any existing sprites.
            var oldSPrites = atlas.GetPackables();
            atlasAsset.Remove(oldSPrites);

            // Add the new sprites.
            atlasAsset.Add(sprites);

            // Save the sprite atlas asset.
            SpriteAtlasAsset.Save(atlasAsset, atlasPath);
        }
    }
}