Is there any simple way to create a SpriteAtlas asset from code? I know i could "hack" it by calling something like: Code (CSharp): EditorApplication.ExecuteMenuItem("Assets/Create/Sprite Atlas"); What i'd like to do, is create an automatic "migration" from the older sprite packer atlases to the new system. The way it would work - for each existing (legacy) sprite atlas, it will create a new sprite atlas asset and migrate all textures into it automatically. Is there anything that does this automatically right now? if not, i'd like to create such a system. i believe the only part that's missing is the ability to create a new sprite atlas asset.
This is not available yet. We will be exposing some of the API related to this at a later date. I can't provide when at this time.
Hi Johaness, well can you at least when clicking that plus button for adding new sprite add there menu item "Add Selected Sprites". Which would add all selected sprites from project tab? It would be really helpful until we have full editor api for adding sprites from scripts which we desperately need. Thank you, Marek.
Please check here : https://docs.unity3d.com/2018.2/Documentation/ScriptReference/U2D.SpriteAtlasExtensions.html for more info on SpriteAtlas API additions (2018.2)
@Venkify Do you know why this approach was choosen, instead of having a SpriteAtlasImporter and the appropiate callbacks? It seems like this is just another way to do the same thing, which is rather inconsistent. The same for creating one, why cant we just use AssetDatabase.CreateAsset like any other asset?
Hi ,you can read my code https://github.com/hanbim520/Unity2017AutoCreateSpriteAtlas.git i finished what your wanted
@Venkify Are there any updates or documentation on how to Create a SpriteAtlas through code in the editor?
@W_M_Reszke @Ben-BearFish @liortal Here is a simple sample to demonstrate API to create SpriteAtlas via code. MenuItem: [Assets/SpriteAtlas Migrate] creates a spriteAtlas for each tag for all sprites that has the tag. MenuItem" [Assets/Create SpriteAtlas for selected Sprites.] creates a spriteatlas for selected sprites. Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEngine.U2D; using UnityEditor.U2D; public class SpriteAtlasConverter { private static bool GetTagIfTexture(string Path, ref Dictionary<string, List<string>> dict) { Object[] data = AssetDatabase.LoadAllAssetsAtPath(Path); foreach (Object o in data) { Texture2D s = o as Texture2D; if (s != null) { TextureImporter ti= AssetImporter.GetAtPath(Path) as TextureImporter; List<string> spritesWithTag; if (!dict.ContainsKey(Path)) { spritesWithTag = new List<string>(); dict[ti.spritePackingTag] = spritesWithTag; } else { spritesWithTag = dict[ti.spritePackingTag]; } spritesWithTag.Add(Path); return true; } } return false; } private static Texture2D GetTexture(string Path) { Object[] data = AssetDatabase.LoadAllAssetsAtPath(Path); foreach (Object o in data) { Texture2D s = (Texture2D)o; if (s != null) return s; } return null; } private static bool CacheSpriteAtlasSprites(string Path, ref SortedSet<string> SpritesInAtlas) { Object[] data = AssetDatabase.LoadAllAssetsAtPath(Path); foreach (Object o in data) { SpriteAtlas sa = o as SpriteAtlas; if (sa != null) { Sprite[] sprites = new Sprite[sa.spriteCount]; sa.GetSprites(sprites); foreach (Sprite sprite in sprites) { SpritesInAtlas.Add(AssetDatabase.GetAssetPath(sprite)); } } return true; } return false; } [MenuItem("Assets/Create SpriteAtlas for selected Sprites.")] public static void CreateAtlasForSelectedSprites() { SpriteAtlas sa = new SpriteAtlas(); AssetDatabase.CreateAsset(sa, "Assets/sample.spriteatlas"); foreach (var obj in Selection.objects) { Object o = obj as Sprite; if (o != null) SpriteAtlasExtensions.Add(sa, new Object[] { o }); } AssetDatabase.SaveAssets(); } [MenuItem("Assets/SpriteAtlas Migrate")] public static void SpriteAtlasMigrator() { List<string> TexturesList = new List<string>(); List<string> SpriteAtlasList = new List<string>(); Dictionary<string, List<string>> spriteTagMap = new Dictionary<string, List<string>>(); SortedSet<string> SpritesInAtlas = new SortedSet<string>(); foreach (string s in AssetDatabase.GetAllAssetPaths()) { if (s.StartsWith("Packages") || s.StartsWith("ProjectSettings") || s.Contains("scene")) continue; bool hasSprite = GetTagIfTexture(s, ref spriteTagMap); if (hasSprite) { TexturesList.Add(s); } else if (s.Contains("spriteatlas")) { bool hasSpriteAtlas = CacheSpriteAtlasSprites(s, ref SpritesInAtlas); if (hasSpriteAtlas) SpriteAtlasList.Add(s); } } foreach (KeyValuePair<string, List<string>> tag in spriteTagMap) { bool found = SpriteAtlasList.Contains(tag.Key); if (!found) { string atlasPath = "Assets/" + tag.Key + ".spriteatlas"; SpriteAtlas sa = new SpriteAtlas(); AssetDatabase.CreateAsset(sa, atlasPath); sa.name = tag.Key; List<string> ss = tag.Value; foreach (string s in ss) { Object o = GetTexture(s); SpriteAtlasExtensions.Add(sa, new Object[] { o }); } AssetDatabase.SaveAssets(); } } } }
Thanks. We are considering SpriteAtlasImporter style workflow which would also make it cache-server friendly. Will post this thread once we have an update.
@Venkify thanks for that sample I actually had a migration script for a while now, that i wanted to share with the community. One thing i did not yet complete is mapping textures by their settings to the corresponding SpriteAtlas. Previously (using Sprite Packer), you could assign any texture with a tag, and Unity would create different atlases grouped by their settings (e.g: texture format, etc). In the newer SpriteAtlas, you simply assign textures to the new asset and configure the settings you want there. When migrating, your code does not check for these settings and will basically group all textures together under the same SpriteAtlas asset. i am not sure this is 100% equivalent of the previous behaviour. Also, there are other flags (e.g: include in build) that are not set. Lastly, my example uses AssetDatabase.StartAssetEditing() .... AssetDatabase.StopAssetEditing() for speeding up the process.
Well, is it happening? It is so weird that you chose to come up with a completely different API, especially when it doesn't play nicely with the cache server. When will the packable API be added to the atlas importer, instead of relying on the helper class?
SpriteAtlas V2 supposedly supports the Accelerator. The danger with necroing threads is that you end up reading about old things that were bad, and then dogpiling an old complaint when fixes has been made in the four years between the last post and your post.
this thread is now the number 1 google hit when trying to figure out how to make a sprite atlas via an editor script. what is the right way to do this in 2024? for my purposes, I want to create a sprite atlas from a folder of sprites via editor script. ideally so I end up with something where the folder is listed in the 'Objects for packing' list in the inspector for the atlas I don't need to keep manually updating the atlas