Search Unity

What is the best practice to unload a SpriteAtlas?

Discussion in '2D' started by the-forty-seven, Sep 5, 2019.

  1. the-forty-seven

    the-forty-seven

    Joined:
    Nov 12, 2014
    Posts:
    8
    Hi,

    I load SpriteAtlases from the AssetBundle when the SpriteAtlasManager.atlasRequested has been raised.

    But I don't know when I should unload the loaded atlases. How can I catch the proper time when the atlas is no longer used?

    My custom code is like belows.

    Thanks in advance.

    Code (CSharp):
    1.  
    2.  
    3. Dictionary<string, SpriteAtlas> _atlases;
    4.     void Start()
    5.     {
    6.         _atlases = new Dictionary<string, SpriteAtlas>();
    7.         SpriteAtlasManager.atlasRequested += AtlasRequested;
    8.     }
    9.  
    10.     void AtlasRequested(string tag, Action<SpriteAtlas> callback)
    11.     {
    12.         StartCoroutine(CoLoadAtlas(tag, callback));
    13.     }
    14.  
    15.     IEnumerator CoLoadAtlas(string tag, Action<SpriteAtlas> callback)
    16.     {
    17.         if (!_atlases.ContainsKey(tag))
    18.         {
    19.             // load atlas from AssetBundles
    20.             AtlasLoadOperation req = LoadAtlasAsync(tag);
    21.             yield return req;
    22.             _atlases.Add(tag, req.Atlas);
    23.         }
    24.  
    25.         callback(_atlases[tag]);
    26.     }
    27.  
    28.     // When should I call this?
    29.     void UnloadAtlas(string tag)
    30.     {
    31.         if (_atlases.ContainsKey(tag))
    32.         {
    33.             Resources.UnloadAsset(_atlases[tag]);
    34.             _atlases.Remove(tag);
    35.         }
    36.     }
    37.  
     
  2. AnthonyReddan

    AnthonyReddan

    Joined:
    Feb 27, 2018
    Posts:
    39
    Bumping because I'd also like to know.
     
  3. Venkify

    Venkify

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    644
    Unloading SpriteAtlas may not unload all textures included in the Atlas as Sprites using the textures might still reference them on runtime. We will consider adding an API to unload explicitly (which will also unload associated textures) but this will result in sprites that are using them not being rendered.

    Current workaround is to unload the SpriteAtlas and explicitly also unload all the associated textures. Thanks.
     
  4. C_Buller

    C_Buller

    Joined:
    Jun 3, 2015
    Posts:
    1
    Bumping this because I'm running into the same issue.

    It doesn't seem like you've fully answered the question @Venkify - OP didn't ask how to unload, rather how they would know when to unload.

    Using the SpriteAtlasManager.atlasRequested event means we're putting trust in Unity to inform us when an atlas is required - is there no way of it similarly informing us that it's no longer required?

    Has there been any progress on that unload API?
     
  5. Venkify

    Venkify

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    644
    Like all other Unity assets (Texture2D, Mesh etc..) there is not automatic way to detect whether an Asset is required or not especially when Assets are only instantiated when referenced.

    Note that you can use Unity - Scripting API: Resources.UnloadUnusedAssets (unity3d.com) to unload any unused assets to regain memory. As mentioned in doc "An asset is deemed to be unused if it isn't reached after walking the whole game object hierarchy, including script components. Static variables are also examined." Since this might be CPU intensive, please use only when required (like test for memory usage etc..)