Search Unity

Is it possible to pass parameter to .Completed function?

Discussion in 'Addressables' started by mailfromthewilds, May 17, 2020.

  1. mailfromthewilds

    mailfromthewilds

    Joined:
    Jan 31, 2020
    Posts:
    217
    Something like this:
    Code (CSharp):
    1.  
    2. Addressables.InstantiateAsync("Assets/0 Addressables/Prefabs/Sprite.prefab").Completed += CompletedInstantiateInventory("string param");
    3.  
    ive been trying to do this for a while but I always get one error or another. I need to pass parameter there
     
  2. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    586
    You don't need to pass a parameter since C# supports variable closures in anonymous functions. Just use whatever you need inside the callback and the compiler will take care of the rest.
    Of course, there's extra GC associated with closures, but I don't think the addressables team is worried about that when it pales in comparison to a full asset load.
     
  3. mailfromthewilds

    mailfromthewilds

    Joined:
    Jan 31, 2020
    Posts:
    217
    im sorry but i dont understand you. "variable closures in anonymous functions" what?
     
  4. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    586
  5. suiboli

    suiboli

    Joined:
    Mar 27, 2020
    Posts:
    11
    While I was using closure variable capture in anonymously functions for months, I am trying to simplified my code by using one method with switch cases by giving parameters passed from
    AssetReference.Completed
    action. Is this plausible?
     
  6. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    586
    I'm not sure what you mean, could you provide some pseudo code to illustrate your idea?
     
  7. suiboli

    suiboli

    Joined:
    Mar 27, 2020
    Posts:
    11
    I figured out that if I wanna pass one more parameter with
    .Completed
    has to be
    Action<T,T1>
    . But it doesn't.

    To make my code cleaner, I wanna do the following.
    Code (CSharp):
    1. enum LoadType : short
    2. {
    3.     Download,
    4.     Load,
    5.     Instantiate,
    6. }
    7.  
    8. void downlaod(string scene)
    9. {
    10.     DownloadDependenciesAsync().Completed += OnCompleted;
    11.     StartCoroutine(CalculatePercent(handle, LoadType.Download));
    12. }
    13.  
    14. void load(string scene)
    15. {
    16.     LoadSceneAsync().Completed += OnCompleted;
    17.     StartCoroutine(CalculatePercent(handle, LoadType.Load));
    18. }
    The following can't be compiled since
    .Completed
    is
    Action<T>
    instead of
    Action<T,T1>
    .
    Code (CSharp):
    1. void OnCompleted(AsyncOperationHandle handle, LoadType type)
    2. {
    3.     StopCoroutine(CalPercent(handle, type));
    4.     doThings();
    5.     if (type == LoadType.Downlaod)
    6.         load(scene);
    7.     else if (type == LoadType.Load && --SceneCountDown == 0)
    8.         SceneManager.UnloadSceneAsync(SceneManager.GetActiveScene(), options: UnloadSceneOptions.None);
    9. }
    So, using closure variable capture is more plausible. Or implement a new
    .Completed
    Action.
     
    Last edited: Nov 20, 2020
    wethings likes this.
  8. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    586
    So for your example, you could just do the OnCompleted at the end of your Coroutine. But if you want to use the callback, you would have to use a lambda(anonymous function) to do it:

    Code (CSharp):
    1. DownloadDependenciesAsync().Completed += handle => OnCompleted(handle, LoadType.Download);