← Files UnityARCHIVED FILE
skills/manage-sprite-atlas/resources/sizeoptimizedpacker.cs
2.73 KB · Oct 2, 2026 · 00:33 UTC
// [UNITY-SKILL:SPRITEATLAS]
using UnityEditor.U2D;
using UnityEngine;
using Unity.Collections;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// Size-optimized sprite packer that places larger sprites first.
/// Uses a simple bin-packing approach to minimize atlas space usage.
/// </summary>
public class SizeOptimizedPacker : ScriptablePacker
{
/// <summary>Maximum atlas size (width and height) in pixels</summary>
public int atlasSize = 2048;
/// <summary>Padding between sprites in pixels</summary>
public int padding = 4;
/// <summary>
/// Packs sprites with larger ones first for better space utilization.
/// Sorts sprites by area (width * height) and places them using first-fit bin packing.
/// </summary>
public override bool Pack(SpriteAtlasPackingSettings config,
SpriteAtlasTextureSettings setting,
PackerData input)
{
NativeArray<SpriteData> sprites = input.spriteData;
NativeArray<TextureData> textures = input.textureData;
// Create sorted list by area (largest first)
var sortedIndices = new List<int>();
for (int i = 0; i < sprites.Length; i++)
{
sortedIndices.Add(i);
}
sortedIndices = sortedIndices
.OrderByDescending(i =>
{
var sprite = sprites[i];
return sprite.rect.width * sprite.rect.height;
})
.ToList();
// Simple bin packing
int currentX = padding;
int currentY = padding;
int maxHeightInRow = 0;
foreach (int idx in sortedIndices)
{
SpriteData sprite = sprites[idx];
int spriteWidth = sprite.rect.width;
int spriteHeight = sprite.rect.height;
// Check if we need a new row
if (currentX + spriteWidth + padding > atlasSize)
{
currentX = padding;
currentY += maxHeightInRow + padding;
maxHeightInRow = 0;
}
// Check if atlas is full
if (currentY + spriteHeight + padding > atlasSize)
{
Debug.LogError("Atlas size exceeded. Increase atlas size or reduce sprite count.");
return false;
}
// Set output
sprite.output.x = currentX;
sprite.output.y = currentY;
sprite.output.page = 0;
sprite.output.rot = PackTransform.None;
// Update position for next sprite
currentX += spriteWidth + padding;
maxHeightInRow = Mathf.Max(maxHeightInRow, spriteHeight);
sprites[idx] = sprite;
}
return true;
}
}
SHA-256: ce09001c8ff1f596322fe609a54142fff67cda600f861ecaf0d36555659ca99e