Search Unity

Multiple load to the same asset

Discussion in 'Addressables' started by Nimdanet, Sep 29, 2021.

  1. Nimdanet

    Nimdanet

    Joined:
    Jan 19, 2013
    Posts:
    38
    Hello everyone!

    I'm new to Addressables. I implemented a system where it loads an Addressable Material and changes the material component of a renderer.

    Basically:

    Code (CSharp):
    1. [SerializeField] private AssetReference m_AssetReference;
    2.  
    3. void Start()
    4. {
    5.    m_AssetReference.LoadAssetAsync<Material>().Completed += (async) =>
    6.    {
    7.       GetComponent<Renderer>().material = async.Result;
    8.    }
    9. }
    My structure is a little more complex than that since I'm using generics and 2 classes: 1 to just load and 1 to change the component and other things. But roughly it's doing the same thing as the code above

    For some reasons I can't change sharedMaterial instead of the material on my project. But I have like 100 renderers on my scene that I should change their material. They load up and use 3 materials. So, for example, 40 objects load materialA and change, 40 objets load materialB and change and 20 objects load materialC and change.

    On my game's splash screen it downloads all necessary objects from Unity's Cloud Content Delivery using Addressables.DownloadDependenciesAsync(label) so when it runs the code above, everything is already local.

    When I run on iOS (iPhone XR) works perfectly fine. When I run on Android (Moto G Play 7) it crashes when it is loading/changing materials, I don't know which of them for sure (crashing on loading or changing). I haven't tested on other Android devices by now.

    My question is: when I call LoadAssetAsync does unity really loads everytime or does it caches the asset? I might have a problem where I'm calling LoadAssetAsync 100 times when I really need was 3.

    Thanks in advance!
     
    Last edited: Sep 29, 2021
  2. LilMako17

    LilMako17

    Joined:
    Apr 10, 2019
    Posts:
    43
    There are 2 version of LoadAssetAsync()
    AssetReference.LoadAssetAsync() which is what you are using, will hold onto the loaded object in in memory inside the AssetReference object. Because of this, LoadAssetAsync will throw an exception if the asset is already loaded. You'll need to check AssetReference.Asset to grab the loaded asset before calling LoadAssetAsync if the case you call it multiple times with the same asset reference before unloading.

    Addressables.LoadAssetAsync() will just return the loaded object in the result, and its up to you to keep it in loaded memory (typically by storing it in a member variable somewhere)

    I'm not sure why you would see different behavior on IOS and Android though, or why it would crash. Maybe out of memory?
     
  3. Nimdanet

    Nimdanet

    Joined:
    Jan 19, 2013
    Posts:
    38
    Okay, thanks a lot for your explaining.

    I'm using AssetReference.LoadAssetAsync()... 100 times... so yeah, probably out of memory crash (that's what I was suspecting because Moto G Play 7 is a much lower end device than iPhone XR).

    I'll make some workaround to never load asset multiple times. If it's already loading, wait for load and use the same loaded asset.

    Thank you once more!
     
  4. phobos2077

    phobos2077

    Joined:
    Feb 10, 2018
    Posts:
    350
    Addressables caches all provide operations by location. This means you can't load the same asset twice, subsequent calls will just return the handle (which is a struct) pointing to the same operation and the same result object.