Unity Sprite Memory Usage Is Huge

Hi there,

Can anyone let me know how to reduce the memory size properly for my sprites on my UI. As right now it accounts for 227.8MB of ram usage in my game and the total Ram usage is only 340.05MB so the sprites are taking up a huge amount of space. It is that bad, that when we load our next scene async it crashes on apple devices.

What is the correct process of doing this, Our UI Designer doesn’t want to make all the UI Power Of 2, Should he or is there another solution to this?

We are developing for IOS & Android

  1. you really got to use power of 2, or at least pack non-power-of-2 sprites into power-of-2 atlases. This allows to use nice compression for your sprites. All sprites must be compressed as much as possible. Use RGB instead of RGBA where possible. Ensure there are no mipmaps (if this is acceptable) - this will reduce size by extra 33%

  1. Create a manager singleton, that loads the sprite from Resources, and provides it to anyone who requested. Instead of using references to sprites, query the manager when needed.

  1. Make that loading asyncronous. In other words, let the manager output a sprite through a callback, not immediatelly.

  1. Make the mechanism that allows the manager to reclaim the Sprite, telling the users to stop referencing it (perhaps, when your custom memory-limit is reached). Afterwards, the manager can destroy and unload the reclaimed sprite from memory. This can be done via the following:

public class ManagedSprite{
     public Sprite sprite;
     public System.Action _onStopReferencingSprite;
}

class Manager{
     
    public void RequestSprite(System.Action<ManagedSprite> OnSpriteLoaded){  
            //...load sprite async, maybe via some coroutine...
            //invoke OnSpriteLoaded once done.
    }
   
    void internal_ReclaimSprite(ManagedSprite ms){
          ms._onStopReferencingSprite?.Invoke();//tell everyone to stop referencing our sprite
          Destroy(ms.sprite);
          ms.sprite = null; //<-- stop referencing, so it can be Garbage Collected.
          ms._onStopReferencingSprite = null;
          Resources.UnloadUnusedAssets();
    }
}//end Manager


class SomeUser{
     [SerializeField]  Image myImg; 

     void foo(){
           Manager.instance.RequestSprite(  OnSpriteRdy  );
     }

     //called several frames after, when the sprite is finally loaded
     void OnSpriteRdy( ManagedSprite ms){
            ms._onStopReferencingSprite += OnStopReferencingSprite;
            _img.sprite = ms.sprite;  //use the actual sprite, as needed.
     }

     //called for us when the Manager wants to take away the sprite from us.
     void OnStopReferencingSprite(){
            _sprite = null;  //<-- stop referencing the previously provided sprite, so it can be Garbage Collected after destroy.
           _img.sprite = null;//ensure image forgets about it too.
     }

}