docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    Synchronous loading

    Synchronous Addressables APIs help to mirror Unity asset loading workflows. AsyncOperationHandles have a method called WaitForCompletion() that forces the asynchronous operation to complete and return the Result of the operation.

    The result of WaitForCompletion is the Result of the asynchronous operation it's called on. If the operation fails, this returns default(TObject).

    You can get a default(TObject) for a result when the operation doesn't fail. Asynchronous operations that auto release their AsyncOperationHandle instances on completion are such cases. Addressables.InitializeAsync and any API with a autoReleaseHandle parameter set to true return default(TObject) even if the operations succeeded.

    Performance considerations

    Calling WaitForCompletion might have performance implications on your runtime when compared to Resources.Load or Instantiate calls directly. If the AssetBundle is local or has been downloaded before and cached, these performance hits are small.

    All active asset load operations are completed when WaitForCompletion is called on any asset load operation, because of how Unity handles asynchronous operations. To avoid unexpected stalls, use WaitForCompletion when you known the current operation count, and the you want all active operations to complete synchronously.

    Don't call WaitForCompletion on an operation that's going to fetch and download a remote AssetBundle.

    Synchronous loading example

    void Start()
    {
        //Basic use case of forcing a synchronous load of a GameObject
        var op = Addressables.LoadAssetAsync<GameObject>("myGameObjectKey");
        GameObject go = op.WaitForCompletion();
    
        //Do work...
    
        Addressables.Release(op);
    }
    

    Deadlocks caused by scene limitations

    Unity can't complete scene loading synchronously. Calling WaitForCompletion on an operation returned from Addressables.LoadSceneAsync doesn't completely load the scene, even if activateOnLoad is set to true. It waits for dependencies and assets to complete but the scene activation must be done asynchronously.

    This can be done using the sceneHandle, or by the AsyncOperation from ActivateAsync on the SceneInstance:

    IEnumerator LoadScene(string myScene)
    {
        var sceneHandle = Addressables.LoadSceneAsync(myScene, LoadSceneMode.Additive);
        SceneInstance sceneInstance = sceneHandle.WaitForCompletion();
        yield return sceneInstance.ActivateAsync();
    
        //Do work... the scene is now complete and integrated
    }
    

    Unity can't unload a scene synchronously. Calling WaitForCompleted on a scene unload doesn't unload the scene or any assets, and a warning is logged to the Console.

    Because of limitations with scene integration on the main thread through the SceneManager API, you can lock the Unity Editor or Player when calling WaitForCompletion to load scenes. This issue happens when loading two scenes in succession, with the second scene load request having WaitForCompletion called from its AsyncOperationHandle.

    Scene loading takes extra frames to fully integrate on the main thread, and WaitForCompletion locks the main thread, so you might have a situation where Addressables has been informed by the SceneManager that the first scene is fully loaded, even though it hasn't finished all operations. At this point, the scene is fully loaded, but the SceneManager attempts to call UnloadUnusedAssets, on the main thread, if the scene was loaded in Single mode. Then, the second scene load request locks the main thread with WaitForCompletion, but can't begin loading because SceneManager requires the UnloadUnusedAssets to complete before the next scene can begin loading.

    To avoid this deadlock, either load successive scenes asynchronously, or add a delay between scene load requests.

    Another issue is calling WaitForCompletion on an asynchronous operation during Awake when a scene is not yet fully loaded. This can block the main thread and prevent other asynchronous operations (i.e. unloading a bundle) in progress from completing. To avoid this deadlock, call WaitForCompletion during Start instead.

    Note that Addressables has a callback registered to SceneManager.sceneUnloaded that will release any unloaded addressable scenes. This can trigger scene bundle unloading if no other scenes from the bundle are loaded.

    Custom operations

    Addressables supports custom AsyncOperation instances which support unique implementations of InvokeWaitForCompletion. This method can be overridden to implement custom synchronous operations.

    Custom operations work with ChainOperation and GroupsOperation instances. If you want to complete chained operations synchronously, make your custom operations implement InvokeWaitForCompletion and create a ChainOperation using your custom operations. Similarly, GroupOperations are well suited to make a collection of AsyncOperations, including custom operations, complete together.

    Both ChainOperation and GroupOperation have their own implementations of InvokeWaitForCompletion that relies on the InvokeWaitForCompletion implementations of the operations they depend on.

    WebGL support

    WebGL doesn't support WaitForCompletion. On WebGL, a web request loads all files. On other platforms, a web request gets started on a background thread and the main thread spins in a tight loop while waiting for the web request to finish. This is how Addressables does it for WaitForCompletion when a web request is used.

    Because WebGL is single-threaded, the tight loop blocks the web request and the operation is never allowed to finish. If a web request finishes the same frame it was created, then WaitForCompletion wouldn't have any issue. However, this isn't guaranteed.

    In This Article
    Back to top
    Copyright © 2024 Unity Technologies — Trademarks and terms of use
    • Legal
    • Privacy Policy
    • Cookie Policy
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)