Tool for generating Sprite Libraries?

Is there a tool / plugin that can automatically generate Sprite Library assets, or a way to simply drag and drop a sprite sheet into a copy of an existing Sprite Library to replace all of its entries?

All of my game’s characters use Sprite Libraries so that they can share a reusable Animator and corresponding Animations. This is a big time save, as each character has 64 4-frame animations, meaning each sprite sheet has 256 individual sprites.

The problem, is that I currently still need to drag and drop each individual frame into its corresponding slot for every single character’s Sprite Library. 256 drags and drops per character, even if you’re doing one player and three enemies, that’s 1,024 drag and drops. Just think about how many times I would have to repeat the action for the full game! It’s the most boring thing to sit and do.

It’s rules based though, and the sheets are consistent sizes with each action on consistent frames, they’re already sliced, so surely I can automate it? I tried building a tool using the below code, but it didn’t work.

using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEngine.U2D.Animation;

public class SpriteLibraryCreator : EditorWindow
{
    private SpriteLibraryAsset spriteLibraryAsset;
    private Texture2D spriteSheet;

    // Hardcoded categories and frame ranges with 256 frames
    private List<CategoryFrameRange> categoryFrameRanges = new List<CategoryFrameRange>
    {
        new CategoryFrameRange { categoryName = "Idle D", startFrame = 0, endFrame = 3 },
        new CategoryFrameRange { categoryName = "Idle R", startFrame = 4, endFrame = 7 },
//This goes on for a while, so have truncated here.
        new CategoryFrameRange { categoryName = "Reload ULM", startFrame = 248, endFrame = 251 },
        new CategoryFrameRange { categoryName = "Reload URM", startFrame = 252, endFrame = 255 }
    };

    [MenuItem("Tools/Sprite Library Creator")]
    public static void ShowWindow()
    {
        GetWindow<SpriteLibraryCreator>("Sprite Library Creator");
    }

    private void OnGUI()
    {
        GUILayout.Label("Create Sprite Library", EditorStyles.boldLabel);

        spriteLibraryAsset = (SpriteLibraryAsset)EditorGUILayout.ObjectField("Sprite Library Asset", spriteLibraryAsset, typeof(SpriteLibraryAsset), false);
        spriteSheet = (Texture2D)EditorGUILayout.ObjectField("Sprite Sheet", spriteSheet, typeof(Texture2D), false);

        if (GUILayout.Button("Create Library"))
        {
            CreateSpriteLibrary();
        }
    }

    private void CreateSpriteLibrary()
    {
        if (spriteLibraryAsset == null || spriteSheet == null)
        {
            Debug.LogError("Please assign a Sprite Library Asset and a Sprite Sheet.");
            return;
        }

        string path = AssetDatabase.GetAssetPath(spriteSheet);
        Object[] sprites = AssetDatabase.LoadAllAssetRepresentationsAtPath(path);

        if (sprites == null || sprites.Length == 0)
        {
            Debug.LogError("No sprites found in the selected sprite sheet.");
            return;
        }

        foreach (var categoryFrameRange in categoryFrameRanges)
        {
            SpriteLibraryUtility.AddCategoryLabel(spriteLibraryAsset, categoryFrameRange.categoryName);

            for (int i = categoryFrameRange.startFrame; i <= categoryFrameRange.endFrame; i++)
            {
                if (i < sprites.Length && sprites[i] is Sprite sprite)
                {
                    string spriteName = sprite.name;
                    SpriteLibraryUtility.AddSpriteToCategory(spriteLibraryAsset, categoryFrameRange.categoryName, spriteName, sprite);
                }
                else
                {
                    Debug.LogWarning($"Frame {i} is out of range for sprite sheet {spriteSheet.name}");
                }
            }
        }

        EditorUtility.SetDirty(spriteLibraryAsset);
        AssetDatabase.SaveAssets();

        Debug.Log("Sprite Library created successfully!");
    }
}

public static class SpriteLibraryUtility
{
    public static void AddCategoryLabel(SpriteLibraryAsset library, string category)
    {
        if (!library.GetCategoryNames().Contains(category))
        {
            library.AddCategoryLabel(null, category, null);
        }
    }

    public static void AddSpriteToCategory(SpriteLibraryAsset library, string category, string label, Sprite sprite)
    {
        if (library.GetSprite(category, label) == null)
        {
            library.AddCategoryLabel(sprite, category, label);
        }
    }
}

[System.Serializable]
public class CategoryFrameRange
{
    public string categoryName;
    public int startFrame;
    public int endFrame;
}

After some digging, I found this quote by a Unity staff member, “Currently we do not support creating or modifying a Sprite Library Asset during edit time. SpriteLibraryAsset.AddCategoryLabel is there so that you can add a Sprite into the SpriteLibraryAsset during runtime.” In this thread: Create SpriteLibraryAsset by Scripts

I can’t be the first person to have this fairly basic need and there must be a way to make a tool to automate this, surely? Can anyone help?


9855573--1419249--spriteLibraryToolHelp2.jpg

In case someone comes across this in future and wonders if it was resolved - yes!

I downloaded a tool called Spriternator, which seems almost custom-made for my use case and can automate making Sprite Library assets, so long as your sprite sheets follow the same format / organisation. You can get it here: SpriterNator: Batch Sprite Animation and Library Tool for Unity by Christine

I then paired that with this YouTube tutorial on using Sprite Libraries to create a reusable Animator that can be shared across multiple Game Objects:

I don’t know why Unity doesn’t seem to have something like Spriternator as standard out of the box, but thankfully, the community came through!

oddly I was thinking how sad it is theres no pixel editor for unity :P there are assets on the store for making sheets etc, but not found a pixel editor

I make all of my sprites in Asesprite, which is very reasonably priced and the best pixel art tool I've ever used.

`
it does look nice, but as i hate 2d games and making them, im kinda loathed to pay :stuck_out_tongue: cos i dont want to be here, im forcing myself to to do 2d because i dont normally

I actually managed to build Aseprite from github source a few years back… wasn’t too hard, a couple google searches and it worked.

thats fair, i just looked at the website with trial and pay…

It kind of feels like this thread has gone off track. TLDR; I wanted to be able to reuse animators and sprite libraries across multiple sprite sheets and I found a way to do just that via the Spriternator tool and a YouTube tutorial on shared animators.