Search Unity

Unable to access scene path from AssetReference in 1.16.1

Discussion in 'Addressables' started by Michael-Ryan, Oct 2, 2020.

  1. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    My project has ScriptableObjects that have references to multiple scenes, each of which is serialized as a
    AssetReference
    type. Prior to Addressables 1.16.1, I have been able to get the path of the asset with the following code, however in 1.16.1, my code fails to return a location for any
    AssetReference
    that is assignable from
    SceneAsset
    using the
    AssetReference.RuntimeKey
    .

    My Extension Method:
    Code (CSharp):
    1. public static string Path(this AssetReference assetReference)
    2. {
    3.    if (assetReference.RuntimeKeyIsValid() == false)
    4.    {
    5.       Debug.LogError("AssetReference RuntimeKey is invalid.");
    6.       return string.Empty;
    7.    }
    8.  
    9.    var resourceLocator = Addressables.ResourceLocators.First();
    10.    if ((resourceLocator.Locate(assetReference.RuntimeKey, null, out var locations) == false)
    11.        || (locations.Count == 0))
    12.    {
    13.       Debug.LogError($"Unable to locate AssetReference using its RuntimeKey: {assetReference.RuntimeKey.Bold()}");
    14.  
    15.       return string.Empty;
    16.    }
    17.  
    18.    if (locations.Count > 1)
    19.    {
    20.       Debug.LogWarning("Multiple assets were located using the AssetReference.");
    21.    }
    22.  
    23.    return locations[0].InternalId;
    24. }
    Using Addressables 1.15.1, the above method would return the path at line #23, whereas with 1.16.1, the method returns at line #15 after logging the error. The
    IResourceLocation.InternalId
    matches the asset path that I'm looking for.

    Comparing the 1.15.1 and 1.16.1 packages, the cause of the change appears to be located in
    AddressableAssetSettingsLocator.GatherEntryLocations()
    .

    In 1.15.1, a
    AddressableAssetEntry
    object that is associated with a scene (
    e.Scene == true
    ) and is assignable from
    SceneAsset
    or is of type
    SceneInstance
    would be used, and the associated asset would be located and returned.

    However, in 1.16.1, that same scene object must be of type
    SceneInstance
    , otherwise the function fails to locate the asset.

    1.15.1 - Code Block from GatherEntryLocations():
    Code (CSharp):
    1. if (type == null || type.IsAssignableFrom(e.MainAssetType) || (type == typeof(SceneInstance) && e.IsScene))
    2. {
    3.     var locType = e.IsScene ? typeof(SceneProvider).FullName : typeof(AssetDatabaseProvider).FullName;
    4.     locations.Add(new ResourceLocationBase(e.address, e.AssetPath, locType, e.MainAssetType));
    5. }
    6. else
    7. {
    8.     ObjectIdentifier[] ids = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(new GUID(e.guid), EditorUserBuildSettings.activeBuildTarget);
    9.     if (ids.Length > 1)
    10.     {
    11.          foreach (var t in AddressableAssetEntry.GatherSubObjectTypes(ids, e.guid))
    12.          {
    13.             if (type.IsAssignableFrom(t))
    14.                 locations.Add(new ResourceLocationBase(e.address, e.AssetPath, typeof(AssetDatabaseProvider).FullName, t));
    15.         }
    16.     }
    17. }
    18. return false;
    1.16.1 - Code Block from GatherEntryLocations():
    Code (CSharp):
    1. if (e.IsScene)
    2. {
    3.     if (type == typeof(SceneInstance))
    4.         locations.Add(new ResourceLocationBase(e.address, e.AssetPath, typeof(SceneProvider).FullName, typeof(SceneInstance)));
    5. }
    6. else if (type == null || type.IsAssignableFrom(e.MainAssetType))
    7. {
    8.     locations.Add(new ResourceLocationBase(e.address, e.AssetPath, typeof(AssetDatabaseProvider).FullName, e.MainAssetType));
    9. }
    10. else
    11. {
    12.     ObjectIdentifier[] ids = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(new GUID(e.guid), EditorUserBuildSettings.activeBuildTarget);
    13.     if (ids.Length > 1)
    14.     {
    15.         foreach (var t in AddressableAssetEntry.GatherSubObjectTypes(ids, e.guid))
    16.         {
    17.             if (type.IsAssignableFrom(t))
    18.                 locations.Add(new ResourceLocationBase(e.address, e.AssetPath, typeof(AssetDatabaseProvider).FullName, t));
    19.         }
    20.     }
    21. }
    22. return false;
    I don't know if the change to exclude
    SceneAsset
    objects here was intentional or an oversight. It seems to be intentional.

    Not understanding why this change was made makes me wonder if I should be going about this in some other way. Should I be storing serialized
    AssetReference
    fields in ScriptableObjects? If so, how can I get access to the
    IResourceLocation.InternalId
    from the
    AssetReference
    address or key now that
    SceneAsset
    types are ignored in
    AddressableAssetSettingsLocator.GatherEntryLocations()
    ?

    Please advise.
     
    Last edited: Oct 3, 2020
  2. davidla_unity

    davidla_unity

    Unity Technologies

    Joined:
    Nov 17, 2016
    Posts:
    763
    Hm, interesting. Let me see what I can find out. Likely this is just a bug introduced by a refactoring of our code.
     
    Greyborn likes this.
  3. davidla_unity

    davidla_unity

    Unity Technologies

    Joined:
    Nov 17, 2016
    Posts:
    763
    Hey, sorry for the delay. This looks like it's fixed in 1.16.13. It may have been fixed sooner than that. If you're still having issues please submit a bug with a repro project.

    I apologize for any inconvenience this caused.
     
    Greyborn and cmahoneydal like this.
  4. Greyborn

    Greyborn

    Joined:
    May 26, 2016
    Posts:
    61
  5. davidla_unity

    davidla_unity

    Unity Technologies

    Joined:
    Nov 17, 2016
    Posts:
    763
    Right, yeah, I see that... that's unfortunate. @Greyborn I think the fix that @Michael-Ryan suggested in the other thread is a valid fix. Hopefully we can get an official fix in soon. I know I sound like a broken record but it really helps out if a bug report gets filed about the SBP issue.

    If you use that fix from the other thread on 1.16.15 does this scene path/AssetReference issue still manifest?
     
  6. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    @DavidUnity3d, I'm on the Greyborn team. My SBP fix does seem to allow the Addressable to be built again.

    There still appears to be a slow down (40-70 second hang one one frame) after loading an addressable scene at runtime in the editor, but I'm assuming that's a separate issue. I haven't looked into the cause, but the profiler appears to indicate that garbage collection associated with the load is being performed for the entire delay (i.e., 70,000 ms). There is no noticeable freeze when loading scenes when using Addressables 1.16.10.

    Regarding the scene path/AssetReference issue, I've since changed the code that was relying on the scene path, and the method in quest is no longer being called. I will test it out when I get the chance, though. Thanks for following up.