# 3. Sprite Library and Resolver Swap
Part of [[2D Animation and Sprite Tools]]. Prev: [[2. Skinning Editor and Sprite Skin]]. Next: [[4. PSD Importer and Character Prefabs]].
A **Sprite Library Asset** groups sprites into **Categories** and **Labels**. A **Sprite Library** component points a hierarchy at one asset. A **Sprite Resolver** on a `SpriteRenderer` picks the sprite for a category/label and assigns it. This is official 15.1 behaviour: "By setting the SpriteResolver's Category and Label value, it will request for a Sprite from a SpriteLibrary Component... If a SpriteRenderer is present in the same GameObject, the SpriteResolver will update the SpriteRenderer's Sprite reference."
## 3.1 Create the asset
1. **Assets > Create > 2D > Sprite Library Asset**.
2. Add a category (`Body`, `Head`, `Weapon`) and labels (`ShirtA`, `ShirtB`, `Sword`, `Axe`).
3. Assign a sprite to each label.
4. Optional: select the asset, then **Assets > Create > 2D > Sprite Library Asset Variant** to inherit categories and override only some labels (a palettized shirt, a unique hat). Variants are the Prototype pattern - do not duplicate the whole library for one change.
The 15.x Sprite Library Asset manual also describes dragging PSD/PSB imports into the library with layer groups as categories when "Use Layer Group" is enabled - useful once part 4 is working. Confirm the checkbox label in 15.1 if it has moved.
## 3.2 Scene components
- Put **Sprite Library** on the character root (or any parent of the resolvers). Assign the asset.
- On each swappable renderer: **Sprite Resolver**. Pick the starting category and label in the Inspector.
- The resolver must be able to find a `SpriteLibrary` on itself or a parent (official: `spriteLibrary` property returns the library it resolves from).
## 3.3 Runtime API (15.1.0)
```csharp
using UnityEngine;
using UnityEngine.U2D.Animation;
/// <summary>
/// Swaps a Sprite Resolver category/label. Returns the official bool from SetCategoryAndLabel.
/// NOT compiled in Unity.
/// </summary>
public sealed class OutfitSwitcher : MonoBehaviour
{
[SerializeField] SpriteResolver bodyResolver;
[SerializeField] string category = "Body";
[SerializeField] string[] labels = { "ShirtA", "ShirtB" };
[SerializeField] int index;
public bool Wear(string label)
{
if (bodyResolver == null) return false;
bool ok = bodyResolver.SetCategoryAndLabel(category, label);
if (!ok)
Debug.LogWarning(
quot;{name}: no sprite for {category}/{label}.", this);
return ok;
}
public void Cycle()
{
if (labels == null || labels.Length == 0) return;
index = (index + 1) % labels.Length;
Wear(labels[index]);
}
public void LogCurrent()
{
if (bodyResolver == null) return;
Debug.Log(quot;{bodyResolver.GetCategory()}/{bodyResolver.GetLabel()}");
}
}
```
`SetCategoryAndLabel(string category, string label)` returns **true** if the category and label were successfully set. `GetCategory` / `GetLabel` read back. `ResolveSpriteToSpriteRenderer()` applies the current selection to the `SpriteRenderer` and returns whether it succeeded - useful if you changed the library asset at runtime and need a push.
You can also drive category/label from **Animation clips** (the resolver is designed to be keyable / previewable - it implements `IAnimationPreviewable`). A "draw sword" clip can set `Weapon` / `Sword` on a frame. Prefer that for choreography; use `SetCategoryAndLabel` for systemic loadout ([[4.Equipment Items and Classes]] can call `Wear` when an item is equipped).
## 3.4 Exercise
Build a library with `Weapon` / `Sword` and `Weapon` / `Axe`. Put a resolver on a hand sprite. Call `Wear("Axe")` from a test key and confirm the renderer changes. Call `Wear("Nope")` and confirm the method returns false and the sprite stays.
## Sources
- Sprite Library Asset: https://docs.unity3d.com/Packages/[email protected]/manual/SLAsset.html
- `SpriteResolver` 15.1.0: https://docs.unity3d.com/Packages/[email protected]/api/UnityEngine.U2D.Animation.SpriteResolver.html
- `SpriteLibrary` 15.1.0: https://docs.unity3d.com/Packages/[email protected]/api/UnityEngine.U2D.Animation.SpriteLibrary.html