Question about Loading and unloading scene with addressable

Hello, there is some things I’m not sure to understand about addressables.

When I use Addressables.LoadSceneAsync, it load my scene from remote (I use Unity CCD).

I don’t know what is the best way to avoid redownloading from remote my scene everytime I load it. Can I only download it from remote the first time, and the other times just load it? If I call twice Addressables.LoadSceneAsync, will the second time be from cache ? Or, would I need to keep myself a list of all the handles in dictionnary and check first if it exists?

Also, when I want to unload the scene, should I use SceneManager.UnloadScene or Addressables.UnloadSceneAsync ?

Thank you

Addressable asset bundles are indeed cached locally. It uses the Caching API that is built into Unity. So your players should only have to download the bundle once and then it will use the version from the cache from then on.

I would recommend using Addressables.UnloadSceneAsync to unload the scene.

1 Like

Okay thank you, that’s very clear!

If I request an asset reference again that is still downloading, it throws an error because it didn’t finish downloading and I made a new request. What is the recommended way to check that an asset is still being downloaded before requesting a load ?

What version of Addressables and Unity are you using?

Generally speaking Addressables only allows one request to go through and all future requests to download are dependent on that original request. So if the first try fails and it retries all other requests that are waiting on that asset bundle to download should continue waiting.

I’m on Unity 6000.0.25f1 with Addressables 2.2.2

If I use LoadAssetAsync() twice with the same AssetReferenceGameobject, I get the error

Attempting to load AssetReference that has already been loaded. Handle is exposed through getter OperationHandle

I can call it twice and avoid the error by doing this, but I’m not sure if it should be necessary :

private readonly Dictionary<string, AsyncOperationHandle<GameObject>> _loadedAssetReferenceGameObject = new();
    
   public void GetAsset(AssetReferenceGameObject assetReferenceGameObject, Action<GameObject> onCompleted)
    {
        if(_loadedAssetReferenceGameObject.TryGetValue(assetReferenceGameObject.AssetGUID, out AsyncOperationHandle<GameObject> handle))
        {
            if (handle.Status == AsyncOperationStatus.Succeeded)
            {
                Debug.Log("Asset is already loaded");
                onCompleted?.Invoke(handle.Result);
            }
            else
            {
                Debug.Log("GetAsset was called before, still loading");
                handle.Completed += operationHandle =>
                {
                    onCompleted?.Invoke(operationHandle.Result);
                };
            }
        }
        else
        {
            Debug.Log("Load Asset");
            LoadAsyncOperationHandle(assetReferenceGameObject, onCompleted);
        }
    }

    private void LoadAsyncOperationHandle(AssetReferenceGameObject assetReferenceGameObject, Action<GameObject> onCompleted)
    {
        AsyncOperationHandle<GameObject> handle = assetReferenceGameObject.LoadAssetAsync();
        _loadedAssetReferenceGameObject.TryAdd(assetReferenceGameObject.AssetGUID, handle);
        
        handle.Completed += operationHandle =>
        {
            onCompleted?.Invoke(operationHandle.Result);
        };
    }

    public void ReleaseAsset(AssetReferenceGameObject assetReferenceGameObject)
    {
        if (_loadedAssetReferenceGameObject.TryGetValue(assetReferenceGameObject.AssetGUID, out AsyncOperationHandle<GameObject> handle))
        {
            handle.Release();
        }
    }

I believe that issue has been fixed in Addressables 2.3.1. You can upgrade in the Package Manager by using “Add Packabe by Name”, using “com.unity.addressables” as the name and 2.3.1 as the package version. Let us know how it goes.

I think I found out why :

It’s not throwing errors if I double call it like this :

Addressables.LoadAssetAsync(assetReference);
Addressables.LoadAssetAsync(assetReference);

There was the error if I was double loading it like this :

assetReference.LoadAssetAsync();
assetReference.LoadAssetAsync();

I thought the latter one was just an helper function, but it’s actually different?

It is. It’s calling Addressables.LoadAssetAsync, but the asset reference holds onto the operation handle for you. So to clear out that handle and load it again you’d need to do something like this:

assetReference.LoadAssetAsync();
// this clears out the stored handle
assetReference.ReleaseAsset();
assetReference.LoadAssetAsync();

Or you could just get the internal operation itself to check on the status:

assetReference.LoadAssetAsync()
Debug.Log(assetReference.OperationHandle.IsDone);
1 Like

hi, Everyone,

@timtunity3d

We’re facing a persistent issue on iOS related to additive scene loading using Addressables, and I’d really appreciate inputs from anyone who has dealt with something similar.

Scenario

Our app has one default scene. Additional scenes are loaded on demand using Addressables.
Each activity performs the following sequence:

  1. Unload the previously loaded additive scene (loaded via Addressables).
  2. Set the default scene as the Active Scene.
  3. Load a new scene additively from Addressables.
  4. Set the newly loaded scene as the Active Scene.

All the above steps run through a flow that uses async + Task.

What We’ve Already Tried

  • Switched from Tasks to Coroutines.
  • Used async void instead of Task-returning methods.
  • Added custom waiting loops with timeout + exception handling.
  • Added await Awaitable.MainThreadAsync() before activating the scene.
  • Forced GC.Collect() before and after loading/unloading scenes.
  • Called Resources.UnloadUnusedAssets() before and after the process.
  • Verified through Memory Profiler — memory is released correctly and cleanup is normal.

Where the Issue Appears

  • Only on iOS.
  • Only in Release builds (i.e., when Debug.unityLogger.logEnabled = false).
  • Debug builds work perfectly on both iOS and Android.

What I’m Looking For

  • Has anyone faced a similar issue where Addressable scenes behave differently in iOS Release mode?
  • Any known workarounds, timing edge cases, or Addressables quirks specific to iOS?
  • Anything else I should check that typically breaks only in release builds (stripping, IL2CPP optimizations, async scheduling differences, etc.)?

Any suggestions or past experiences would be extremely helpful. Thank you!