Unity SpriteAtlas V2
Provides editor-safe procedural knowledge for scripting atlases in Unity projects. V2 enforces strict separation between editor authoring and runtime access.
⚠️ Critical V2 Principle:
SpriteAtlasis runtime-only.SpriteAtlasAssetis editor-only. Never mix contexts. Always use V2.
🚨 CRITICAL: Required Checks and User Inputs Before Implementation
ALWAYS perform these checks and ask these questions BEFORE generating any code:
Read the shipped resources before writing code (REQUIRED)
This skill ships working C# under resources/, and the atlas code that goes wrong is almost always
code written without reading it first. Open the files for the path you are taking, then write.
| Taking this path | Read first |
|---|---|
| Any atlas work at all | resources/authoringvsruntime.cs, references/common-errors.md |
| Prebuild generation (the default) | resources/spriteatlasprebuildgenerator.cs, resources/enablespritepacking.cs, resources/savespriteatlasasset.cs |
| Option B, Addressables late-binding | resources/buildaddressablespostprocess.cs, resources/spriteatlaslatebinding.cs, resources/handlelatebinding.cs |
| Anything that might use an older API | resources/deprecatedmethods.cs, resources/dontscriptspriteatlasineditor.cs, resources/dontpackinruntimebuilds.cs |
resources/ holds 38 files in all, covering custom packers, variants, platform settings, and
runtime access. Browse the directory when your task is not in the table above rather than inventing
an approach. Reaching for the API from memory instead of reading these is the single most common
cause of an atlas that imports cleanly and then does nothing at runtime.
0. Check for Existing Scripts (REQUIRED FIRST STEP)
BEFORE generating any code, scan the project for existing SpriteAtlas scripts generated by this skill.
Search for files containing the identifier: // [UNITY-SKILL:SPRITEATLAS]
If existing scripts are found, ALWAYS ask the user with this format:
"I found existing SpriteAtlas scripts in your project:
Prebuild Generator:
Assets/Editor/SpriteAtlas/SpriteAtlasPrebuildGenerator.csAddressables Builder:
Assets/Editor/SpriteAtlas/BuildAddressablesPostprocess.csRuntime Loader:
Assets/Scripts/SpriteAtlas/SpriteAtlasLateBinding.csWhat would you like to do?"
Then present options:
Option A: Update existing scripts (Recommended if requirements changed)
- Regenerates scripts at existing paths
- Preserves file locations
- Updates to latest version
- ⚠️ May overwrite custom modifications
Option B: Create new scripts with different names
- Generates alongside existing scripts
- Allows multiple atlas configurations
- Original scripts remain unchanged
- You'll need to specify new names/paths
Option C: Abort (keep existing unchanged)
- No code generation
- No changes to project
- Use this if you want to keep current setup
User Choice Handling:
- If A chosen: Regenerate at existing paths, increment version to 2.0.1+
- If B chosen: Ask for new script names (e.g., "SpriteAtlasPrebuild_Custom.cs"), then generate
- If C chosen: Stop immediately, inform user no changes were made
1. Delivery Mechanism (REQUIRED)
Ask: "How do you want to deliver the sprite atlases?"
Option A: Built-in Data (Immediate Loading)
- Atlases are included in the build and loaded immediately
- Set
includeInBuild = true - Suitable for: Core UI, main gameplay sprites, always-needed assets
- Pros: Simple, no additional packages, instant access
- Cons: Increases initial build size, cannot update without new build
Option B: Late-Binding via Addressables (On-Demand Loading)
- Atlases are NOT included in build, loaded on-demand via Addressables
- Set
includeInBuild = false - Create Addressables entries for each atlas
- Add addressable setup as prebuild step
- 🚨 REQUIRED: Build Addressables content as build step
- 🚨 REQUIRED: Create late-binding runtime loader script
- Suitable for: DLC content, optional features, large assets, downloadable content
- Pros: Smaller initial build, can update independently, on-demand loading
- Cons: Requires Addressables package, async loading, network dependency
| Use Case | Recommended |
|---|---|
| Core UI sprites that are always visible | Option A: Built-in |
| Tutorial or onboarding sprites | Option A: Built-in |
| Level-specific sprites (100+ levels) | Option B: Addressables |
| DLC or seasonal content | Option B: Addressables |
| Localized UI sprites (multiple languages) | Option B: Addressables |
| Character skins or cosmetics | Option B: Addressables |
2. SpritePacker Mode (REQUIRED)
Enable Sprite Packer mode before creating atlases, then read the setting back and confirm it took.
Use the code in resources/enablespritepacking.cs; it sets
EditorSettings.spritePackerMode and configures the importer's packing settings.
This is the step that decides whether the atlas you produce is real. Disabled is the zero value of
SpritePackerMode, so any project where nobody has set it carries packing Disabled, and an atlas
created while it is Disabled still imports, still shows up as an asset, and still looks finished, but
can never pack. Unity says so in the Inspector: "Sprite Atlas packing is disabled". Nothing else in
the workflow fails, so an atlas shipped this way reads as a success. Do not assume a project is
already configured: read the value.
So do not treat "I set it" as done. After setting it, read EditorSettings.spritePackerMode back,
confirm it is not Disabled, and report the value you actually read. If you cannot read it back,
say so rather than assuming the write landed.
DO NOT edit meta files DIRECTLY.
🚨 CRITICAL: Default Approach is Prebuild Generation
ALWAYS use IPreprocessBuildWithReport to automatically generate or update SpriteAtlases during the build pipeline. This is the DEFAULT and REQUIRED approach unless the user EXPLICITLY requests manual authoring.
❌ DO NOT Create Manual Menu Item Scripts
NEVER create scripts with [MenuItem] attributes for atlas generation unless explicitly requested. The prebuild approach eliminates the need for manual clicks. Only use manual authoring for: Hand-optimized layouts, specific sprite arrangements, or editor preview requirements. See Advanced: Manual Authoring.
🚨 CRITICAL: Sprite Source Location Restriction
ONLY add sprites from the project's Assets folder. NEVER add sprites from Unity built-in assets, packages, or external locations. Unity built-in assets cannot be packed into SpriteAtlas, and package assets may cause import/dependency issues.
Critical V2 Architecture
| Context | Component | Purpose | Allowed Usage |
|---|---|---|---|
| Editor Authoring | SpriteAtlasAsset |
Add/remove sprites/folders; store metadata | ✅ Editor scripts only |
| Editor Settings | SpriteAtlasImporter |
Configure texture, packing, platform settings | ✅ Editor scripts only |
| Editor Packing | SpriteAtlasUtility.PackAtlases() |
Optional editor preview packing (not for build) | ⚠️ Only for preview; atlases auto-pack at build |
| Runtime | SpriteAtlas |
Query packed sprites (read-only) | ✅ Runtime scripts only |
| Runtime Loading | SpriteAtlasManager |
Dynamic loading callbacks | ✅ Runtime scripts only |
Forbidden Cross-Context Usage (Common Error Sources)
| ❌ Invalid Pattern | ✅ Correct Pattern |
|---|---|
new SpriteAtlas() in editor code |
Use SpriteAtlasAsset + SpriteAtlasImporter |
AssetDatabase.LoadAssetAtPath<SpriteAtlas>(...) in editor |
Use SpriteAtlasAsset.Load(...) |
SpriteAtlasAsset.GetPackables() in editor |
Use SpriteAtlas.GetPackables() |
Modifying SpriteAtlas in editor scripts |
Modify SpriteAtlasAsset → reimport → use SpriteAtlasImporter |
| Create variants from original packable objects (sprites/folders) | Creating variants from a Master runtime SpriteAtlas |
NEVER script against SpriteAtlas in editor code — it is only for runtime use in V2 except for GetPackables.
Core V2 Workflow (Reference Only - Use Prebuild Instead)
🚨 IMPORTANT: This workflow is shown for reference only. ALWAYS implement this inside
IPreprocessBuildWithReport.OnPreprocessBuild()rather than in manual scripts. See Quick Start.
Prerequisites
- Unity 6000.3 or later
- Basic understanding of Unity's asset import pipeline
- Familiarity with editor scripting for atlas authoring
Quick Start: Automated Prebuild Generation (DEFAULT APPROACH)
Overview
This is the PRIMARY and DEFAULT way to create SpriteAtlases. Implement IPreprocessBuildWithReport to automatically generate or update SpriteAtlases before each build based on categorization rules. No manual menu clicks required.
Workflow Steps
Step 1: Ask User for Delivery Mechanism
Before generating code, ask: "How do you want to deliver the sprite atlases: (A) Built-in data or (B) Late-binding via Addressables?"
Step 2: Create Prebuild Script
Create this script in an Editor folder. Customize based on user's delivery choice:
Option A: Built-in Data (Immediate Loading)
Built-in Data (Immediate Loading)
Option B: Late-Binding via Addressables (On-Demand Loading)
🚨 CRITICAL ENFORCEMENT: When user chooses Addressables, you MUST generate ALL THREE scripts below. Never generate just one or two - all three are required for Addressables delivery to work.
Required Scripts (ALL THREE MANDATORY):
- Prebuild script (IPreprocessBuildWithReport) - Generates atlases, creates Addressables entries
- Build Addressables script (IPostprocessBuildWithReport) - Builds Addressables content bundles
- Late-binding runtime loader (MonoBehaviour) - Handles on-demand loading at runtime
See references/addressables-delivery.md for complete implementation.
Complete Workflow
User Request
↓
Step 0: Check for existing scripts with [UNITY-SKILL:SPRITEATLAS] identifier
↓
├─ Found existing scripts?
│ ↓ YES
│ Ask user: Update existing / Create new / Abort
│ ↓
│ Handle user choice
│
└─ NO existing scripts or user chose "Create new"
↓
Ask "Built-in data or Addressables?"
↓
├─ Option A: Built-in
│ ↓
│ Generate 1 script: Prebuild generator (includeInBuild=true)
│
└─ Option B: Addressables
↓
Generate 3 scripts:
1. Prebuild: Generate atlases + create Addressables entries (includeInBuild=false)
2. Postprocess: Build Addressables bundles
3. Runtime: Late-binding loader component
Step 3: Customize Categorization Rules
Edit the OnPreprocessBuild method to match your project's sprite organization. Choose one or combine multiple strategies:
| Strategy | When to Use | Implementation |
|---|---|---|
| Folder-based | Sprites organized by folder structure | GenerateAtlasByFolder("Assets/Art/UI", "Assets/Atlases/UI.spriteatlasv2") |
| Naming convention | Sprites follow naming patterns | GenerateAtlasByNaming("Assets/Art", "icon_", "Assets/Atlases/Icons.spriteatlasv2") |
| Asset labels | Sprites tagged with labels | |
| Scene-based | Sprites used in specific scenes | Query scene references |
Step 4: Build Your Project
Atlases are automatically generated/updated during build. No manual menu clicks required. This is why prebuild is the default approach.
For Built-in Data (Option A):
- Atlases are included in build
- Ready for immediate use at runtime
For Addressables (Option B) - Additional Required Steps:
You MUST generate THREE scripts (not just one):
- Prebuild script (IPreprocessBuildWithReport) - Generates atlases and creates Addressables entries automatically
- Build Addressables script (IPostprocessBuildWithReport) - Builds Addressables content bundles
- Late-binding runtime loader (MonoBehaviour) - Handles on-demand loading via SpriteAtlasManager
The build process will:
- Generate atlases (prebuild step)
- Create addressable entries automatically
- Build addressables content bundles (postprocess step)
- At runtime: Late-binding loader automatically loads atlases when sprites are first accessed
Common Categorization Patterns
By Folder Structure:
GenerateAtlasByFolder("Assets/Art/UI/Buttons", "Assets/Atlases/UI_Buttons.spriteatlasv2");
GenerateAtlasByFolder("Assets/Art/UI/Icons", "Assets/Atlases/UI_Icons.spriteatlasv2");
GenerateAtlasByFolder("Assets/Art/Characters/Player", "Assets/Atlases/Player.spriteatlasv2");
By Naming Convention:
GenerateAtlasByNaming("Assets/Art", "icon_", "Assets/Atlases/Icons.spriteatlasv2");
GenerateAtlasByNaming("Assets/Art", "bg_", "Assets/Atlases/Backgrounds.spriteatlasv2");
Variant Generation in Prebuild
Generate variant atlases for different resolutions.
Advanced: Manual Authoring (NOT Default - Use Only When Explicitly Requested)
⚠️ WARNING: Manual authoring is NOT the default approach. Only use these patterns when the user EXPLICITLY requests manual control or editor preview during development.
🚨 DEFAULT APPROACH: Use prebuild generation with
IPreprocessBuildWithReportinstead. See Quick Start.
Manual authoring is appropriate ONLY for:
- Hand-optimized sprite layouts where exact positioning matters
- Custom sprite ordering requirements
- Editor preview during authoring workflow
- Explicitly requested by user
DO NOT use manual authoring when:
- User asks to "create sprite atlas" (use prebuild)
- User asks to "optimize sprites" (use prebuild)
- User asks for automated workflow (use prebuild)
- No specific manual control requirement mentioned
For complete manual authoring patterns including master atlas creation, variant creation, and runtime loading, see references/manual-authoring.md.
Key Requirements (V2-Specific)
- 🚨 ALWAYS check for existing scripts FIRST: Before generating code, scan for scripts with
[UNITY-SKILL:SPRITEATLAS]identifier and prompt user to update or create new - 🚨 ALWAYS tag generated scripts: Include skill identifier at the top of every generated script for future detection
- 🚨 ALWAYS ask for delivery mechanism: Ask user "Built-in data or Addressables?" before generating code
- 🚨 ALWAYS enable Sprite Packer mode: Set
EditorSettings.spritePackerMode = SpritePackerMode.SpriteAtlasV2in prebuild script - 🚨 ALWAYS use prebuild generation: Implement
IPreprocessBuildWithReportas the DEFAULT approach for creating atlases - 🚨 ONLY add sprites from Assets/ folder: Never add sprites from Packages, built-in assets, or external locations
- 🚨 For Addressables delivery, ALWAYS generate THREE scripts:
- Prebuild atlas generator with Addressables setup
IPostprocessBuildWithReportto build Addressables content- Late-binding runtime loader script (extends
SpriteAtlasManager)
- Set includeInBuild correctly:
truefor built-in data,falsefor Addressables - Two-Step Editor Pattern: Create with
SpriteAtlasAsset→ Save → Import → Configure viaSpriteAtlasImporter→ SaveAndReimport() - Never use
SpriteAtlasin editor code — exceptSpriteAtlas.GetPackables()instance method on a loaded runtime atlas - Variants reference master: Use
SetMasterAtlas(SpriteAtlas)with runtime instance loaded viaAssetDatabase.LoadAssetAtPath<SpriteAtlas>() - Platform format assignment: Use
format = TextureImporterFormat.ASTC_6x6directly (no cast) - File extension: V2 atlases use
.spriteatlasv2(not.spriteatlas) SpriteAtlasUtility.PackAtlases()is optional: Only for editor preview; build-time packing is automatic
For common errors and invalid patterns, see references/common-errors.md.
Detailed Reference
- Addressables Delivery: references/addressables-delivery.md - Complete late-binding setup with Addressables
- Manual Authoring: references/manual-authoring.md - Manual patterns (NOT default - use only when explicitly requested)
- Common Errors: references/common-errors.md - Invalid patterns and API corrections
- API Reference: references/api.md - Complete V2 class documentation
- Custom Packing: references/custom-packing.md -
ScriptablePackerimplementation - Best Practices: references/best-practices.md - Optimization and common pitfalls
Namespaces
Editor Scripts:
using UnityEditor; // AssetImporter, AssetDatabase
using UnityEditor.U2D; // SpriteAtlasAsset, SpriteAtlasImporter, SpriteAtlasUtility
using UnityEngine; // Runtime types (e.g., TextureImporterFormat)
using UnityEngine.U2D; // SpriteAtlas
Runtime Scripts:
using UnityEngine; // Core Unity types
using UnityEngine.U2D; // SpriteAtlas, SpriteAtlasManager