using UnityEngine; using UnityEditor; using System.IO; using System.Collections.Generic; public class SimpleAtlasPacker : EditorWindow { private DefaultAsset spritesFolder; private int cellSize = 64; private int columns = 4; private int padding = 2; private string atlasName = "Buttons_Atlas"; [MenuItem("Tools/Simple Atlas Packer")] public static void ShowWindow() { GetWindow(typeof(SimpleAtlasPacker)); } void OnGUI() { GUILayout.Label("Simple Atlas Packer", EditorStyles.boldLabel); spritesFolder = (DefaultAsset)EditorGUILayout.ObjectField("Sprites Folder", spritesFolder, typeof(DefaultAsset), false); cellSize = EditorGUILayout.IntField("Cell Size", cellSize); columns = EditorGUILayout.IntField("Columns", columns); padding = EditorGUILayout.IntField("Padding", padding); atlasName = EditorGUILayout.TextField("Atlas Name", atlasName); if (GUILayout.Button("Generate Atlas")) { if (spritesFolder != null) { string folderPath = AssetDatabase.GetAssetPath(spritesFolder); GenerateAtlas(folderPath); } else { Debug.LogWarning("Please select a folder with sprites!"); } } } void GenerateAtlas(string folderPath) { string[] guids = AssetDatabase.FindAssets("t:Texture2D", new[] { folderPath }); List textures = new List(); foreach (string guid in guids) { string assetPath = AssetDatabase.GUIDToAssetPath(guid); Texture2D tex = AssetDatabase.LoadAssetAtPath(assetPath); if (tex != null) textures.Add(tex); } if (textures.Count == 0) { Debug.LogWarning("No textures found in folder!"); return; } int rows = Mathf.CeilToInt((float)textures.Count / columns); int width = columns * (cellSize + padding) - padding; int height = rows * (cellSize + padding) - padding; Texture2D atlas = new Texture2D(width, height, TextureFormat.RGBA32, false); Color32[] fillColor = new Color32[width * height]; for (int i = 0; i < fillColor.Length; i++) fillColor[i] = new Color32(0, 0, 0, 0); atlas.SetPixels32(fillColor); Dictionary> jsonFrames = new Dictionary>(); for (int i = 0; i < textures.Count; i++) { int col = i % columns; int row = i / columns; int x = col * (cellSize + padding); int y = height - (row + 1) * (cellSize + padding) + padding; Texture2D tex = textures[i]; Texture2D resized = ResizeTexture(tex, cellSize, cellSize); atlas.SetPixels(x, y, cellSize, cellSize, resized.GetPixels()); var frame = new Dictionary { {"x", x}, {"y", y}, {"w", cellSize}, {"h", cellSize} }; jsonFrames[Path.GetFileName(AssetDatabase.GetAssetPath(textures[i]))] = new Dictionary(frame); } atlas.Apply(); // Save Atlas PNG byte[] pngData = atlas.EncodeToPNG(); string atlasPath = $"Assets/{atlasName}.png"; File.WriteAllBytes(atlasPath, pngData); AssetDatabase.Refresh(); // Save JSON string json = "{\n \"frames\": {\n"; int count = 0; foreach (var kv in jsonFrames) { json += $" \"{kv.Key}\": {{ \"frame\": {{\"x\":{kv.Value["x"]},\"y\":{kv.Value["y"]},\"w\":{kv.Value["w"]},\"h\":{kv.Value["h"]}}} }}"; count++; if (count < jsonFrames.Count) json += ",\n"; else json += "\n"; } json += " },\n \"meta\": { \"app\": \"SimpleAtlasPacker\" }\n}"; File.WriteAllText($"Assets/{atlasName}.json", json); AssetDatabase.Refresh(); // Set sprite import settings TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(atlasPath); importer.textureType = TextureImporterType.Sprite; importer.spriteImportMode = SpriteImportMode.Multiple; importer.SaveAndReimport(); Debug.Log(" Atlas and JSON generated!"); } Texture2D ResizeTexture(Texture2D source, int width, int height) { RenderTexture rt = RenderTexture.GetTemporary(width, height); Graphics.Blit(source, rt); RenderTexture.active = rt; Texture2D result = new Texture2D(width, height); result.ReadPixels(new Rect(0, 0, width, height), 0, 0); result.Apply(); RenderTexture.active = null; RenderTexture.ReleaseTemporary(rt); return result; } }