Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question How to unload and reload sprites into memory?

Discussion in 'Scripting' started by karderos, Jul 14, 2023.

  1. karderos

    karderos

    Joined:
    Mar 28, 2023
    Posts:
    376
    Lets say I have a sprite on my project folder. Technically a texture2d? size(100mb)

    And on my scene I have a reference to it assigned on the inspector:
    Code (CSharp):
    1. public Sprite s;//assigned in inspector
    This should mean that if I am that scene with this reference then the sprite is loaded and is occupiying 100mb of ram, right?

    Now I can do:

    Code (CSharp):
    1. s = null;
    2.  
    3. Resources.UnloadUnusedAssets();
    This should clear the 100mb sprite from memory?

    But now, how can I get the sprite back since I no longer have a reference to it?

    Let me know if there is any loophole in the previous logic.

    Also how would it impact if the sprite in question was packed in an atlas?

    Thanks for the help
     
  2. ijmmai

    ijmmai

    Joined:
    Jun 9, 2023
    Posts:
    188
    If you create a prefab of the sprite, drag that prefab into the script in the editor, you can instantiate and delete it whenever you want. But what you probably should look into is Addressable Assets.
     
  3. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
  4. karderos

    karderos

    Joined:
    Mar 28, 2023
    Posts:
    376
    so no way to access the assets that are already packed into the build? the resources folder exists outside of the build
     
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Well you nulled out your reference to it, so how do you expect to find it again? You have to load it dynamically in some fashion, which cone be done through either Resources or Addressables.

    This isn't accurate. Assets in resources just go into their own special asset bundle at build, accessible through the Resources API. They're a part of a build like any other asset, just one you have some degree of granular access to.
     
    Kurt-Dekker likes this.
  6. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,082
    Streaming assets is the folder you want if you need files to be kept outside of a build, but it comes with the major downside that you're now responsible for loading those files in at runtime. Which might not sound like a problem but it is thanks to the fact that most of the code that would handle it in the editor isn't available at runtime.

    There are other headaches involved too like having very specific access requirements on some platforms that are very difficult to find information on thanks to how often the platforms change.
     
    Last edited: Jul 14, 2023
  7. karderos

    karderos

    Joined:
    Mar 28, 2023
    Posts:
    376
    thanks, so unless I store an asset outside the build I cant retrieve it

    So any asset that was compiled normally into the build becomes impossible to retrieve if I clear the reference? its ok if yes

    and theres no way to have a reference to something without it consuming ram?
     
  8. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    Any asset stored in a Resources folder will be included/packed in the build.

    When you do Resources.Load("filename") Unity will simply load the file into memory and return a reference to it.

    The resources folder exists as a way of including assets in a build without having to make a reference to them from within a scene. Sometimes developers only want to load assets when necessary as it can be a great way of reducing loading times.

    Keep in mind that loading assets while a game is running can cause stutter, especially if you're loading a large texture or mesh into the GPU. So this is why Unity is biased towards loading meshes and textures at the start of a scene and stuffing them into the GPU.
     
  9. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Addressables has been mentioned twice.
     
    Ryiah, Kurt-Dekker, Sluggy and 2 others like this.
  10. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,057
    Just dropping this as an Addressables example.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.AddressableAssets;
    3. using UnityEngine.Events;
    4. using UnityEngine.ResourceManagement.AsyncOperations;
    5.  
    6. public class AddressableSpriteAssetLoader : MonoBehaviour
    7. {
    8.     [SerializeField]
    9.     private AssetReferenceSprite SpriteAssetReference;
    10.  
    11.     [SerializeField]
    12.     private UnityEvent<Sprite> SpriteLoaded;
    13.    
    14.  
    15.     public Sprite SpriteAsset { get; private set; }
    16.  
    17.     private void OnEnable() => Load();
    18.  
    19.     private void OnDisable() => Unload();
    20.  
    21.     private void OnAssetLoadCompleted(AsyncOperationHandle<Sprite> handle)
    22.     {
    23.         SpriteAsset = handle.Result;
    24.         SpriteLoaded.Invoke(SpriteAsset);
    25.     }
    26.  
    27.     public void Load()
    28.     {
    29.         // Check if already loaded
    30.         if (SpriteAsset != null)
    31.             return;
    32.  
    33.         SpriteAssetReference.LoadAssetAsync().Completed += OnAssetLoadCompleted;
    34.     }
    35.  
    36.     public void Unload()
    37.     {
    38.         // Check if already unloaded
    39.         if (SpriteAsset == null)
    40.             return;
    41.        
    42.         Addressables.Release(SpriteAsset);
    43.     }
    44. }
     
    Sluggy, Ryiah and spiney199 like this.