Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question about Addressables.InternalIdTransformFunc

Discussion in 'Addressables' started by delexaet, Feb 26, 2021.

  1. delexaet

    delexaet

    Joined:
    Apr 14, 2016
    Posts:
    39
    Hey,

    We need to at runtime be able to change the url of the bundles for potentially each/every bundle. I saw on https://docs.unity3d.com/Packages/com.unity.addressables@1.16/manual/TransformInternalId.html that we can use Addressables.InternalIdTransformFunc to do that.

    However there is a problem as that only seems to trigger when we call Addressables.LoadAssetAsync however it does *NOT* trigger when we call Addressables.DownloadDependenciesAsync. This is a problem since we must download all the bundles before hand for better user experience.

    Any suggestions/feedback here would be appreciated. Thanks
     
  2. delexaet

    delexaet

    Joined:
    Apr 14, 2016
    Posts:
    39
    bumping for visibility. also extra info, this is observed on 2020.2.1 with Addressables package 1.16.16
     
  3. TreyK-47

    TreyK-47

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    1,796
    I'll flag with the team for some guidance!
     
  4. delexaet

    delexaet

    Joined:
    Apr 14, 2016
    Posts:
    39
    @TreyK-47 FYI I'm not sure exactly what happened but all of a sudden, the Addressables.InternalIdTransformFunc was triggering on Addressables.DownloadDependenciesAsync again.

    I don't remember doing anything different but after 1-2 days of trying to debug/create a workaround, it all of a sudden started to work again. Very strange... but what I can say for sure is, at one point in my project, this was working then stopped working and now working again.
     
  5. davidla_unity

    davidla_unity

    Unity Technologies

    Joined:
    Nov 17, 2016
    Posts:
    736
    That's... bizarre. The transform func is part of the AssetBundleProvider so it should always trigger whenever an AssetBundle is being requested. I'm glad it's working for you now but I'm baffled that it randomly wasn't working. Perhaps there was a race condition in assigning the TransformIdFunc and when you call the DownloadDepsAsync? I have no idea. If it stops working again please do let us know and feel free to file a bug with a repro project (if you can).
     
  6. delexaet

    delexaet

    Joined:
    Apr 14, 2016
    Posts:
    39
    Hey,

    Just an update. So I figured out why I was seeing the behavior I was seeing and it all makes sense now. I was simply in the wrong "Play Mode" in addressable settings. ie when I saw the wrong behavior with InternalIdTransformFunc, it was because I was in "Fastest" mode.

    I guess between the days when it did/did not work, I forgot that I had switched from one mode to another for other reasons. Anyways just wanted to give you an update and basically say it was user error :p
     
    TreyK-47 likes this.
  7. paulgullettMR

    paulgullettMR

    Joined:
    Jun 23, 2019
    Posts:
    13
    @davidla_unity I have this working with unsigned URLs, which is great. Can I add to this by asking about how I might go about this if I have my AWS signed URL generation done server-side?

    I need to StartCoroutine to talk to the server to get the signed URL and find a mechanism of returning the string to the TransformFunc delegate, which of course expects a synchronous response to the assignment of location.InternalId

    I can't see a way of asking Addressables for a list of what it is about to load, which may be the other way around it, so you could pre-generate the signed URLs.

    I don't want to do AWS SDK .Net on the client as it complicates AWS key rotation and is generally less secure.

    Any thoughts, or have I missed something.
     
  8. paulgullettMR

    paulgullettMR

    Joined:
    Jun 23, 2019
    Posts:
    13
    Having asked the question, I ended up making this work by asking Addressables what it was about to load using LoadResourceLocationsAsync and then went and found the dependencies. With a list of dependencies, I send that to the server and run through getting the signed URLs with a time limit of say a minute. This ends up being more efficient than doing it for each file.

    I then stick these in a dictionary and use that in the TransformFunc delegate.

    I can't help feeling that I am re-inventing the wheel though.
     
  9. elfasito

    elfasito

    Joined:
    Jul 4, 2017
    Posts:
    51
    @paulgullettMR hey paul, I can ask you for show some of you code solution?.
    im messed up with how to generate the signed keys of the specific bundles what I want to download.
     
  10. unity_Y7qaE5sxsgKTQA

    unity_Y7qaE5sxsgKTQA

    Joined:
    Apr 14, 2022
    Posts:
    1
    Hello @davidla_unity, I'm working on unity 2020.3.24f1 and addressable 1.19.15. After I used Addressables.InternalIdTransformFunc to change the URL, I tried to call Addressables.DownloadDependenciesAsync function and it works on the fastest and the advanced mode but does not work in the *requires built groups* mode. The URL in the error log still is the old one.
     
  11. DeanX

    DeanX

    Joined:
    Mar 1, 2016
    Posts:
    4
    @delexaet Can you please tell me how you are changing the url for every asset.
    I'm trying to load scene bundles but I keep getting this error :

    Exception of type 'UnityEngine.AddressableAssets.InvalidKeyException' was thrown.


    string TransformFunc(IResourceLocation location)
    {
    string baseURL = location.InternalId;
    string newLoadingPath = "https://downloadurl/scene.bundle";

    return location.InternalId.Replace(baseURL, newLoadingPath);
    }

    (newLoadingPath - has the real loading path and bundle names in my code)

    If use the url in the profile and don't try to change anything it works fine. I have made a copy of the assets on both the url in the profile and the new path, just for testing.
     
  12. delexaet

    delexaet

    Joined:
    Apr 14, 2016
    Posts:
    39
    @DeanX Here's how I do it

    Code (CSharp):
    1.         [RuntimeInitializeOnLoadMethod]
    2.         static void SetInternalIdTransform()
    3.         {
    4.             Addressables.InternalIdTransformFunc = CustomizeURL;
    5.         }
    6.  
    7.         static string CustomizeURL(IResourceLocation location)
    8.         {
    9.             string filename = Path.GetFileName(location.InternalId);
    10.             var updatedURL = $"<ENTER SOME URL HERE>/{filename}";
    11.             return updatedURL;
    12.         }
    13.  
    I guess for you, your updatedURL would be
    var updatedURL = $"https://downloadurl/{filename}";
     
  13. DeanX

    DeanX

    Joined:
    Mar 1, 2016
    Posts:
    4
    @delexaet Are you looking for the bundle file when you look for 'fileName'?

    It looks like the download is happening but I'm still getting the
    Exception of type 'UnityEngine.AddressableAssets.InvalidKeyException' was thrown. error

    I have a scene called 'MainHouse' that is in the Asset bundle but it looks like the key cannot be found.
     
  14. delexaet

    delexaet

    Joined:
    Apr 14, 2016
    Posts:
    39
    well this is going to be called for every single addressable call where it's downloading/loading an addressable. so it all you have to change is the <Enter some url here> section with your specific.

    So if the url to MainHouse.bundle is "https://downloadurl/MainHouse.bundle", you simply want to set

    Code (CSharp):
    1. var updatedURL = $"https://downloadurl/{filename}";
    You shouldn't have to touch anything else and then next time you call download or load through addressables, it should all work.