Search Unity

Resolved OutOfRangeException when building bundles with Unity 2018.4.27 and Addressables 1.16.15

Discussion in 'Addressables' started by Michael-Ryan, Dec 14, 2020.

Thread Status:
Not open for further replies.
  1. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    My project is using Unity 2018.4.27 with Addressables 1.16.15 and Scriptable Build Pipeline 1.15.1.

    Whenever addressable bundles are being built with 1.16.15, the following exception occurs. This exception did not occur when building the same addressable bundles on 1.16.10 or earlier.

    Code (CSharp):
    1. Build Task GenerateBundleCommands failed with exception:
    2. Index was out of range. Must be non-negative and less than the size of the collection.
    3. Parameter name: index
    4.   at System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) [0x00029] in <e1319b7195c343e79b385cd3aa43f5dc>:0
    5.   at System.ThrowHelper.ThrowArgumentOutOfRangeException () [0x00000] in <e1319b7195c343e79b385cd3aa43f5dc>:0
    6.   at System.Collections.Generic.List`1[T].get_Item (System.Int32 index) [0x00009] in <e1319b7195c343e79b385cd3aa43f5dc>:0
    7.   at UnityEditor.Build.Pipeline.Tasks.GenerateBundleCommands.GetSortedSceneObjectIdentifiers (System.Collections.Generic.List`1[T] objects) [0x00017] in D:\Greyborn\Projects\Luna [switch]\LunaGame\Library\PackageCache\com.unity.scriptablebuildpipeline@1.15.1\Editor\Tasks\GenerateBundleCommands.cs:189
    8.   at UnityEditor.Build.Pipeline.Tasks.GenerateBundleCommands.CreateSceneBundleCommand (System.String bundleName, System.String internalName, UnityEditor.GUID scene, System.Collections.Generic.List`1[T] bundledScenes, System.Collections.Generic.Dictionary`2[TKey,TValue] assetToMainFile) [0x00013] in D:\Greyborn\Projects\Luna [switch]\LunaGame\Library\PackageCache\com.unity.scriptablebuildpipeline@1.15.1\Editor\Tasks\GenerateBundleCommands.cs:201
    9.   at UnityEditor.Build.Pipeline.Tasks.GenerateBundleCommands.Run () [0x000f1] in D:\Greyborn\Projects\Luna [switch]\LunaGame\Library\PackageCache\com.unity.scriptablebuildpipeline@1.15.1\Editor\Tasks\GenerateBundleCommands.cs:74
    10.   at UnityEditor.Build.Pipeline.BuildTasksRunner.Run (System.Collections.Generic.IList`1[T] pipeline, UnityEditor.Build.Pipeline.Interfaces.IBuildContext context) [0x000ca] in D:\Greyborn\Projects\Luna [switch]\LunaGame\Library\PackageCache\com.unity.scriptablebuildpipeline@1.15.1\Editor\Shared\BuildTasksRunner.cs:56
    11. UnityEditor.AddressableAssets.Build.DataBuilders.BuildScriptPackedMode:DoBuild(AddressablesDataBuilderInput, AddressableAssetsBuildContext)
    While examining the "Scriptable Build Pipeline 1.15.1" package code, the
    GetSortedSceneObjectIdentifiers(fileObjects)
    method is only called in the
    #if !UNITY_2019_1_OR_NEWER
    condition. According to the code comment, this is because "ContentBuildInterface.PrepareScene was not returning stable sorted references, causing a indeterminism and loading errors in some cases. Add correct sorting here until patch lands to fix the API."

    It seems like the purpose of
    static List<ObjectIdentifier> GetSortedSceneObjectIdentifiers(List<ObjectIdentifier> objects)
    is to simply sort the list of objects based on the object's type. That method, however, appears to have bug.

    Code (CSharp):
    1. static List<ObjectIdentifier> GetSortedSceneObjectIdentifiers(List<ObjectIdentifier> objects)
    2. {
    3.     var types = new List<Type>(BuildCacheUtility.GetTypeForObjects(objects));
    4.     var sortedObjects = new List<SortObject>();
    5.     for (int i = 0; i < objects.Count; i++)
    6.         sortedObjects.Add(new SortObject { sortIndex = GetSortIndex(types[i]), objectId = objects[i] });
    7.     return sortedObjects.OrderBy(x => x.sortIndex).Select(x => x.objectId).ToList();
    8. }
    The call to
    BuildCacheUtility.GetTypeForObjects(objects)
    returns a sorted array of distinct types found among
    objects
    . The
    for
    loop then iterates over the
    objects
    list and uses the same
    i
    index to access elements of
    types
    . It seems like in most cases, this will fail for two reasons: the pre-sorted
    types
    array is no longer in sync with the
    objects
    list used to determine the types, and the
    types
    array is likely to be significantly smaller than
    objects
    , due to it only containing distinct values, which is the cause of
    OutOfRangeException
    .

    The purpose of
    GetSortedSceneObjectIdentifiers
    is to return a stable sorted list of references, and I'd like to make sure this is happening as intended. It seems like the
    GetSortedSceneObjectIdentifiers
    method should be something like this:

    Code (CSharp):
    1. static List<ObjectIdentifier> GetSortedSceneObjectIdentifiers(List<ObjectIdentifier> objects)
    2. {
    3.     var sortedObjects = new List<SortObject>();
    4.     for (int i = 0; i < objects.Count; i++)
    5.     {
    6.         var objectId = objects[i];
    7.         var type = BuildCacheUtility.GetTypeForObject(objectId)[0];
    8.         sortedObjects.Add(new SortObject { sortIndex = GetSortIndex(type), objectId = objectId });
    9.     }
    10.     return sortedObjects.OrderBy(x => x.sortIndex).Select(x => x.objectId).ToList();
    11. }
    Addressable bundles successfully build with the modified method. Is this a proper fix?

    -----

    I'd also like to add that while the addressable bundles do build, we're seeing a 40+ second delay between an addressable scene being loaded and the moment when Unity renders the scene. The game appears to lock up for a few frames (with one frame showing 60,000 to 72,000 milliseconds in the profiler) while it performs some object garbage collection associated with the load. This delay does not occur when building with the 1.16.10 addressables release.

    This issue may be unrelated to the code issue above, but I thought it might be worth mentioning here.
     
    Last edited: Dec 14, 2020
    cwennchen likes this.
  2. Greyborn

    Greyborn

    Joined:
    May 26, 2016
    Posts:
    61
    Any chance we can get an update on this. It seems that the latest 1.16.x builds (post .10) have not been tested against 2018 LTS? Thank you in advance for guidance on this issue.
     
  3. TreyK-47

    TreyK-47

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    1,820
  4. davidla_unity

    davidla_unity

    Unity Technologies

    Joined:
    Nov 17, 2016
    Posts:
    763
    Hey all, yeah please file a bug for this so the SBP team can look at it. They'll have to get a fix in for that and in a new version of SBP.
    @Michael-Ryan that looks good to me but @Ryanc_unity would be able to tell for sure.
     
  5. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    Thanks, @TreyK-47 and @DavidUnity3d.

    Reported the issue: (Case 1303926) OutOfRangeException when building bundles with Unity 2018.4.27 and Addressables 1.16.15
     
    TreyK-47, dzamani and Peter77 like this.
  6. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,609
    We also just tried updating Addressables from 1.13.1 to 1.16.16 using Unity 2018.4.27, however we experience the same problem as mentioned in this thread.

    Not a single Addressables update since 1.13.1 worked here. Very unprofessional from you guys, this really has to improve.

    Code (CSharp):
    1. Build Task GenerateBundleCommands failed with exception:
    2. Index was out of range. Must be non-negative and less than the size of the collection.
    3. Parameter name: index
    4.   at System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) [0x00029] in <e1319b7195c343e79b385cd3aa43f5dc>:0
    5.   at System.ThrowHelper.ThrowArgumentOutOfRangeException () [0x00000] in <e1319b7195c343e79b385cd3aa43f5dc>:0
    6.   at System.Collections.Generic.List`1[T].get_Item (System.Int32 index) [0x00009] in <e1319b7195c343e79b385cd3aa43f5dc>:0
    7.   at UnityEditor.Build.Pipeline.Tasks.GenerateBundleCommands.GetSortedSceneObjectIdentifiers (System.Collections.Generic.List`1[T] objects) [0x00017] in D:\Work\untamed_alpha7\unity\Library\PackageCache\com.unity.scriptablebuildpipeline@1.15.2\Editor\Tasks\GenerateBundleCommands.cs:189
    8.   at UnityEditor.Build.Pipeline.Tasks.GenerateBundleCommands.CreateSceneBundleCommand (System.String bundleName, System.String internalName, UnityEditor.GUID scene, System.Collections.Generic.List`1[T] bundledScenes, System.Collections.Generic.Dictionary`2[TKey,TValue] assetToMainFile) [0x00013] in D:\Work\untamed_alpha7\unity\Library\PackageCache\com.unity.scriptablebuildpipeline@1.15.2\Editor\Tasks\GenerateBundleCommands.cs:201
    9.   at UnityEditor.Build.Pipeline.Tasks.GenerateBundleCommands.Run () [0x000f1] in D:\Work\untamed_alpha7\unity\Library\PackageCache\com.unity.scriptablebuildpipeline@1.15.2\Editor\Tasks\GenerateBundleCommands.cs:74
    10.   at UnityEditor.Build.Pipeline.BuildTasksRunner.Run (System.Collections.Generic.IList`1[T] pipeline, UnityEditor.Build.Pipeline.Interfaces.IBuildContext context) [0x000ca] in D:\Work\untamed_alpha7\unity\Library\PackageCache\com.unity.scriptablebuildpipeline@1.15.2\Editor\Shared\BuildTasksRunner.cs:56
    11. UnityEditor.AddressableAssets.Settings.AddressableAssetSettings:BuildPlayerContent()
    Code (CSharp):
    1. SBP ErrorException
    2. UnityEditor.AddressableAssets.Settings.AddressableAssetSettings:BuildPlayerContent()
     
  7. JesseSTG

    JesseSTG

    Joined:
    Jan 10, 2019
    Posts:
    236
  8. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    Sorry for the late reply. We reverted to 1.16.10 shortly after reporting the issue, since that was a stable version for us.

    We recently tested Unity 2018.4.36 with Addressables 1.18.15 and Scriptable Build Pipeline 1.19.1 and we were able to successfully build addressables.

    I took a look at the SBP source where I previously identified the source of the exception and it looks like the code has changed since SBP 1.16.15. Where it used to call BuildCacheUtility.GetTypeForObjects(objects) inside SBP > GenerateBundleCommands.cs > GetSortedSceneObjectIdentifiers(), it now calls BuildCacheUtility.GetMainTypeForObjects(objects) in 1.19.1.

    While the older method call would return a list of distinct objects that ended up shorter than expected and resulted in a "Index was out of range" exception, the new method call doesn't appear to do this.

    We'll test things a bit further, but as of now, the issue seems to be resolved.
     
    JesseSTG likes this.
Thread Status:
Not open for further replies.