Search Unity

Feedback Expose AsyncOperationHandle in AssetReference

Discussion in 'Addressables' started by phobos2077, Apr 10, 2020.

  1. phobos2077

    phobos2077

    Joined:
    Feb 10, 2018
    Posts:
    350
    AssetReference class has an m_Operation field which is initialized when LoadAsset is called. You can check if this internal operation is valid using IsValid() and if it's completed using IsDone property. That's great but what I really miss is the ability to await on the asset loading Task.

    Now the only way to do it would be to put the returned handle from LoadAsset in some variable and then use it later, which is not convenient. Why do we need to bother adding more variables if the AssetReference itself already has this handle, just doesn't allow to use it directly?

    My use case explained:
    I have a list of AssetReferences in a class. There is a Preload() method that calls LoadAssetAsync for all references in a list so they get loaded. However there's another method that needs to use the loaded assets but it could be called independently of Preload(). Assets could be still loading or Preload() could not have been called at all. Regardless, this method should be able to (asynchronously) get the loaded asset and use it.

    That's what I wanted to do:

    Code (CSharp):
    1.  
    2. private async void UseAsset(AssetReference assetRef)
    3. {
    4.     if (!assetRef.IsValid())
    5.     {
    6.         assetRef.LoadAssetAsync();
    7.     }
    8.     _someComponent.asset = await assetRef.OperationHandle.Task;
    9. }
    But there is no OperationHandle property. Is it possible to add in a future versions?

    On a side note, I find it weird that if you call LoadAssyncAsync multiple times for the same AssetReference, the internal m_Operation is overwritten. So now there's no way to call ReleaseAsset on the original operation. Memory wasted? Seems the natural way would be to just return existing m_Operation if it's Valid. That would also solve my original issue.

    All these limitations tell me I need to write my own version of AssetReference class, but I would also have to duplicate a lot of useful code, most importantly the custom property drawer for it. It would be better if the built-in version would be feature-complete and robust instead.
     
    Last edited: Apr 10, 2020
    JesOb likes this.
  2. phobos2077

    phobos2077

    Joined:
    Feb 10, 2018
    Posts:
    350
    Here is the kind of wrapper I have to use to get the desired behavior:
    Code (CSharp):
    1.  
    2.  
    3.         [Serializable]
    4.         public class AssetReferenceWrapper : IDisposable
    5.         {
    6.             private AssetReference _assetRef;
    7.          
    8.             [NonSerialized]
    9.             private AsyncOperationHandle _loadHandle;
    10.  
    11.             public void PreLoad()
    12.             {
    13.                 if (!_loadHandle.IsValid())
    14.                 {
    15.                     if (!_assetRef.RuntimeKeyIsValid())
    16.                     {
    17.                         Debug.LogError("Asset reference is invalid!");
    18.                         return;
    19.                     }
    20.                     _loadHandle = _assetRef.LoadAssetAsync();
    21.                 }
    22.             }
    23.  
    24.             public Task<Object> GetAssetAsync()
    25.             {
    26.                 PreLoad();
    27.                 return _loadHandle.IsValid()
    28.                     ? _loadHandle.Task
    29.                     : Task.FromResult<Object>(null);
    30.             }
    31.  
    32.             public void Dispose()
    33.             {
    34.                 if (_assetRef.IsValid())
    35.                 {
    36.                     _assetRef.ReleaseAsset();
    37.                 }
    38.  
    39.                 _loadHandle = default;
    40.             }
    41.         }
    I really wish I could just have this functionality built in.
     
  3. TreyK-47

    TreyK-47

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    1,820
    Thanks for the feedback! I'll kick this over to the team for them to review!
     
    phobos2077 likes this.
  4. TreyK-47

    TreyK-47

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    1,820
    I connected with the team, and they are creating a ticket to check this out.
     
    phobos2077 likes this.