← Files UnityARCHIVED FILE
skills/manage-sprite-atlas/resources/queryspritesefficiently.cs
6.25 KB · Oct 3, 2026 · 06:34 UTC
// [UNITY-SKILL:SPRITEATLAS]
using UnityEngine;
using UnityEngine.U2D;
using System.Collections.Generic;
using UnityEditor.U2D;
/// <summary>
/// Demonstrates efficient querying of sprites from SpriteAtlases.
/// Avoids expensive operations and unnecessary allocations.
/// </summary>
public static class QuerySpritesEfficientlyExample
{
/// <summary>
/// Gets all sprites from an atlas efficiently.
/// Uses the V2 GetPackables() method on runtime SpriteAtlas.
/// </summary>
public static Sprite[] GetSpritesFromAtlas(SpriteAtlas atlas)
{
if (atlas == null)
{
Debug.LogError("Cannot query: atlas is null");
return new Sprite[0];
}
// Use GetPackables() - this is the V2 way
Object[] packables = atlas.GetPackables();
// Filter to get only sprites
var sprites = new List<Sprite>();
for (int i = 0; i < packables.Length; i++)
{
if (packables[i] is Sprite sprite)
{
sprites.Add(sprite);
}
}
return sprites.ToArray();
}
/// <summary>
/// Gets a sprite by name from an atlas efficiently.
/// Avoids iterating through all sprites on each call by caching the results.
/// </summary>
public static Sprite GetSpriteFromAtlas(SpriteAtlas atlas, string spriteName)
{
if (atlas == null)
{
Debug.LogError("Cannot query: atlas is null");
return null;
}
if (string.IsNullOrEmpty(spriteName))
{
Debug.LogWarning("Cannot query: sprite name is null or empty");
return null;
}
// Get all sprites once
Sprite[] sprites = GetSpritesFromAtlas(atlas);
// Find matching sprite
for (int i = 0; i < sprites.Length; i++)
{
if (sprites[i].name == spriteName)
{
return sprites[i];
}
}
Debug.LogWarning($"Sprite '{spriteName}' not found in atlas: {atlas.name}");
return null;
}
/// <summary>
/// Queries multiple sprites by name from an atlas.
/// More efficient than calling GetSpriteFromAtlas multiple times
/// when you need to query many sprites at once.
/// </summary>
public static Sprite[] GetSpritesFromAtlas(SpriteAtlas atlas, string[] spriteNames)
{
if (atlas == null || spriteNames == null || spriteNames.Length == 0)
return new Sprite[0];
// Get all sprites once
Sprite[] allSprites = GetSpritesFromAtlas(atlas);
// Create lookup dictionary for efficient searching
var spriteLookup = new Dictionary<string, Sprite>();
for (int i = 0; i < allSprites.Length; i++)
{
spriteLookup[allSprites[i].name] = allSprites[i];
}
// Query requested sprites
var result = new List<Sprite>(spriteNames.Length);
for (int i = 0; i < spriteNames.Length; i++)
{
if (spriteLookup.TryGetValue(spriteNames[i], out Sprite foundSprite))
{
result.Add(foundSprite);
}
else
{
Debug.LogWarning($"Sprite '{spriteNames[i]}' not found in atlas: {atlas.name}");
}
}
return result.ToArray();
}
/// <summary>
/// Checks if an atlas contains a specific sprite by name.
/// </summary>
public static bool ContainsSprite(SpriteAtlas atlas, string spriteName)
{
if (atlas == null || string.IsNullOrEmpty(spriteName))
return false;
Sprite[] sprites = GetSpritesFromAtlas(atlas);
for (int i = 0; i < sprites.Length; i++)
{
if (sprites[i].name == spriteName)
return true;
}
return false;
}
/// <summary>
/// Gets the count of sprites in an atlas without loading all sprites.
/// </summary>
public static int GetSpriteCount(SpriteAtlas atlas)
{
if (atlas == null)
return 0;
Object[] packables = atlas.GetPackables();
int count = 0;
for (int i = 0; i < packables.Length; i++)
{
if (packables[i] is Sprite)
count++;
}
return count;
}
}
/// <summary>
/// Component that demonstrates efficient sprite querying.
/// Caches queries for repeated access.
/// </summary>
public class EfficientSpriteQuery : MonoBehaviour
{
[SerializeField] private SpriteAtlas _atlas;
private Dictionary<string, Sprite> _spriteCache;
private bool _cacheInitialized = false;
/// <summary>
/// Initializes the cache with all sprites from the atlas.
/// Call this once at startup for efficient repeated queries.
/// </summary>
public void InitializeCache()
{
if (_atlas == null)
return;
Sprite[] sprites = QuerySpritesEfficientlyExample.GetSpritesFromAtlas(_atlas);
_spriteCache = new Dictionary<string, Sprite>(sprites.Length);
for (int i = 0; i < sprites.Length; i++)
{
_spriteCache[sprites[i].name] = sprites[i];
}
_cacheInitialized = true;
Debug.Log($"Cached {sprites.Length} sprites from atlas: {_atlas.name}");
}
/// <summary>
/// Gets a sprite by name using the cached lookup.
/// Much faster than querying the atlas directly for each call.
/// </summary>
public Sprite GetCachedSprite(string name)
{
if (!_cacheInitialized)
{
InitializeCache();
}
if (_spriteCache.TryGetValue(name, out Sprite sprite))
{
return sprite;
}
Debug.LogWarning($"Sprite '{name}' not found in cached atlas");
return null;
}
/// <summary>
/// Gets a sprite by name, with optional cache initialization.
/// </summary>
public Sprite GetSprite(string name, bool initializeIfNeeded = true)
{
if (!_cacheInitialized && initializeIfNeeded)
{
InitializeCache();
}
if (_spriteCache != null && _spriteCache.TryGetValue(name, out Sprite sprite))
{
return sprite;
}
// Fallback to direct query if cache not available
return QuerySpritesEfficientlyExample.GetSpriteFromAtlas(_atlas, name);
}
}
SHA-256: faa0b3cb5c65b84c6842cb5ee75e04ee064d47ff57180514b22f95eaa56142d3