Does Generate Bundle Packing get randomly stuck half way for anyone else

Unity 2019.3.f10
Addressables 1.9.3 and 1.10.

I get it about 50% of the time

I should probably mention I have all my assets as addressables, and they were all in one group (just all the scenes added to that group)

I made about 30 more groups and dragged folders in to each group so I got each character mesh and textures and anims as its own group.

Since doing that the Build gets stuck about 50% of the time, regardless of clean build or not.

I have just had to simplify my groups in the hope of possibly submitting this game to sony/nintendo/MS in a few weeks

Check if there’s more than 1 asset with the same address. You might also want to try Assets->Reimport All.

Yes, it gets stuck for me as well. Addressables 1.8.5 with Unity 2019.3.15f1. It didn’t happen when I had fewer assets in the system but I saw it once I added more.

Edit
I found I could debug GenerateBundlePacking.cs and add logs to it. I found it didn’t freeze but is instead unusably slow.

It seems to spend a great deal of time here, on the order of minutes per asset

// Second pass: Remove References also included by non-circular Referenced Assets
            foreach (var referencedAsset in referencedAssets)
            {
                var circularRef = referencedAsset.referencedObjects.Select(x => x.guid).Contains(asset);
                if (circularRef)
                    continue;

                references.RemoveAll(x => referencedAsset.referencedObjects.Contains(x));
            }

I think the issue is that referencedAsset.referencedObjects is a list instead of a HashSet, so the Select() and Contains() functions are very slow

Also
It looks like some of the other files have
public IProgressTracker ProgressTracker;

This would provide a lot of benefit as the user otherwise thinks Unity has locked up, and there is in fact no way to tell if it did lock up. I’m not sure how to add it though

Edit 2
After waiting a while longer it did in fact lock up somewhere in ValidAssetBundle or PackAssetBundle. I didn’t have enough logging to say where exactly but I added a breakpoint in every loop and none hit within 30 minutes

I modified FilterReferencesForAsset in GenerateBundlePacking.cs, now Generate Bundle Packing takes seconds instead of hours / days / infinite

90% sure it’s correct. I wasn’t sure if I should combine ObjectIdentifier lists with duplicate GUID AssetLoadInfo. Since the original code uses a HashSet which just discards duplicates, I did the same thing. Also wasn’t sure if ObjectIdentifier.guid is valid to use for equality checks in RemoveAll, assuming it is valid because then I can use the key lookup in the dictionary

List<GUID> FilterReferencesForAsset(GUID asset, List<ObjectIdentifier> references, HashSet<ObjectIdentifier> previousSceneObjects = null)
        {
            // AssetLoadInfo has List<ObjectIdentifier> referencedObjects;
            // Use Dictionary<GUID, List<ObjectIdentifier>> to represent referencedObjects with the same GUID
            var referencedAssets = new Dictionary<AssetLoadInfo, Dictionary<GUID, List<ObjectIdentifier>>>();

            // First pass: Remove Default Resources and Includes for Assets assigned to Bundles
            for (int i = references.Count - 1; i >= 0; --i)
            {
                var reference = references[i];
                if (reference.filePath.Equals(CommonStrings.UnityDefaultResourcePath, StringComparison.OrdinalIgnoreCase))
                {
                    references.RemoveAt(i);
                    continue; // TODO: Fix this so we can pull these in
                }

                AssetLoadInfo referenceInfo;
                if (m_DependencyData.AssetInfo.TryGetValue(reference.guid, out referenceInfo))
                {
                    references.RemoveAt(i);

                    // KevinJ: OLD
                    // referencedAssets.Add(referenceInfo);

                    // KevinJ: NEW
                    Dictionary<GUID, List<ObjectIdentifier>> referencedObjectsAsDictionary;
                    if (referencedAssets.TryGetValue(referenceInfo, out referencedObjectsAsDictionary) == false)
                    {
                        referencedObjectsAsDictionary = new Dictionary<GUID, List<ObjectIdentifier>>();
                        referencedAssets.Add(referenceInfo, referencedObjectsAsDictionary);

                        foreach (var referenceObject in referenceInfo.referencedObjects)
                        {
                            List<ObjectIdentifier> guidConflicts;
                            if (referencedObjectsAsDictionary.TryGetValue(referenceObject.guid, out guidConflicts))
                            {
                                guidConflicts.Add(referenceObject);
                            }
                            else
                            {
                                guidConflicts = new List<ObjectIdentifier>();
                                guidConflicts.Add(referenceObject);
                                referencedObjectsAsDictionary.Add(referenceObject.guid, guidConflicts);
                            }
                        }
                    }
                    continue;
                }
            }

            // Second pass: Remove References also included by non-circular Referenced Assets
            foreach (var referencedAsset in referencedAssets)
            {
                // OLD:
                /*
                var circularRef = referencedAsset.referencedObjects.Select(x => x.guid).Contains(asset);
                if (circularRef)
                    continue;

                references.RemoveAll(x => referencedAsset.referencedObjects.Contains(x));
                */

                // New:
                Dictionary<GUID, List<ObjectIdentifier>> referencedObjectsAsDictionary = referencedAsset.Value;
                bool circularRef = referencedObjectsAsDictionary.ContainsKey(asset);
                if (circularRef)
                    continue;

                references.RemoveAll(x => referencedObjectsAsDictionary.ContainsKey(x.guid));
            }

            // Final pass: Remove References also included by circular Referenced Assets if Asset's GUID is higher than Referenced Asset's GUID
            foreach (var referencedAsset in referencedAssets)
            {
                // OLD:
                /*
                var circularRef = referencedAsset.referencedObjects.Select(x => x.guid).Contains(asset);
                if (!circularRef)
                    continue;

                if (asset < referencedAsset.asset)
                    continue;

                references.RemoveAll(x => referencedAsset.referencedObjects.Contains(x));
                */

                Dictionary<GUID, List<ObjectIdentifier>> referencedObjectsAsDictionary = referencedAsset.Value;
                bool circularRef = referencedObjectsAsDictionary.ContainsKey(asset);
                if (!circularRef)
                    continue;

                if (asset < referencedAsset.Key.asset)
                    continue;

                references.RemoveAll(x => referencedObjectsAsDictionary.ContainsKey(x.guid));
            }

            // Special path for scenes, they can use data from previous sharedAssets in the same bundle
            if (!previousSceneObjects.IsNullOrEmpty())
                references.RemoveAll(previousSceneObjects.Contains);


            // NEW
            // Write modifications
            foreach (var referencedAsset in referencedAssets)
            {
                referencedAsset.Key.referencedObjects.Clear();

                Dictionary<GUID, List<ObjectIdentifier>> referencedObjectsAsDictionary = referencedAsset.Value;
                foreach (var guidToObjectList in referencedObjectsAsDictionary)
                {
                    referencedAsset.Key.referencedObjects.AddRange(guidToObjectList.Value);
                }
            }

            // OLD
            // return referencedAssets.Select(x => x.asset).ToList();

            // NEW
            List<GUID> output = new List<GUID>();
            foreach (var referencedAsset in referencedAssets)
                output.Add(referencedAsset.Key.asset);
            return output;
        }

Not sure if anyone from Unity watches this forum, but if this code works for you feel free to use it.