SpriteAtlasExtensions are broken

,

SpriteAtlasExtensions seem completely broken, do they work for anyone? I have tested this with Unity 2022.2.X and 2023.1.0. I am using atlas V2 (always enabled).

// all SpriteAtlasExtensions are broken. here are some examples using SetIsVariant.
// they should be fixed, and full functionality (including packable editing and fetching) should be moved to the asset importer.
// this would also make it play nicely with the cache server.
// however I'd be happy if even the existing functionality worked.
var atlasPath = "Assets/Path/To/Atlas.spriteatlasv2";

// SpriteAtlasExtensions.SetIsVariant(SpriteAtlas):
// nothing happens
var atlas = AssetDatabase.LoadAssetAtPath<UnityEngine.U2D.SpriteAtlas>(atlasPath);
atlas.SetIsVariant(false);
EditorUtility.SetDirty(atlas);

// serialized properties:
// the object in memory seems to be edited as if I load it from the asset database it does have the new value.
// however, the new value is never persisted to the asset file.
// so there is some really bad magic going on with sprite atlases, as you can't even write to them via serialized properties.
using var serializedObject = new SerializedObject(atlas);
using var isVariantProperty = serializedObject.FindProperty("m_IsVariant");
isVariantProperty.boolValue = true;
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(serializedObject.targetObject);

// SpriteAtlasExtensions.SetIsVariant(SpriteAtlasAsset):
// nothing happens
var editorAtlas = UnityEditor.U2D.SpriteAtlasAsset.Load(atlasPath);
editorAtlas.SetIsVariant(true);
EditorUtility.SetDirty(editorAtlas);

// save
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
AssetDatabase.ImportAsset(atlasPath);
1 Like

Hello, the first 2 cases are as expected.
In the first case, when using Sprite Atlas V2, SpriteAtlasAsset.Load() should be used instead of AssetDatabase.LoadAssetAtPath().
In the second case, Sprite Atlas V2 is not supported as a SerializedObject
The third case using SpriteAtlasAsset.Load() should work, however its recommended to use

AssetDatabase.Refresh();```
instead of
```EditorUtility.SetDirty();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();```

[More info](https://docs.unity3d.com/ScriptReference/U2D.SpriteAtlasAsset.html) on the SpriteAtlasAsset APIs
1 Like

I have the same feeling, all my old code for SpriteAtlas V1 does not work for V2 anymore. So then I switched to use SpriteAtlasAsset, but there I can’f find any method to get the current packables. But I can get them via the old SpriteAtlasExtensions code.

Next, when I add/remove packables via SpriteAtlasAsset and call SpriteAtlasAsset.Save afterwards, nothing is changed on my asset on disc. It all feels very weird and inconsistent.

Anyone know how to modify SpriteAtlas V2 properly via code?

Please check here :
Unity - Scripting API: SpriteAtlasAsset (unity3d.com)
Unity - Scripting API: U2D.SpriteAtlasAsset.Add (unity3d.com)

2 Likes

I ended up having to use both SpriteAtlas and SpriteAtlasAsset:

private void ReplaceAtlasPackables(string atlasPath, params Object[] packables) {
    // Load Atlas
    var atlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>(atlasPath);
    if (atlas) {
        var oldPackables = atlas.GetPackables();
        
        // Load Atlas Asset
        var atlasAsset = SpriteAtlasAsset.Load(atlasPath);
        if (atlasAsset) {
            // Clear existing packables 
            atlasAsset.Remove(oldPackables);
            
            // Add new packables
            atlasAsset.Add(packables);
            
            // Save Atlas Asset
            SpriteAtlasAsset.Save(atlasAsset, atlasPath);
        }
    }
}
3 Likes