A find a fix solution. The bug is in AsyncOperationHandle GetDownloadSizeAsync(IEnumerable keys) function inside AddressablesImpl.cs. To test this solution, I copy the package addressables inside Library\PackageCache and put it in folder packages to create my local package. And remove the package addressables linked via Package Manager.
At allLocations.Distinct is not remove similar entries so the same entry is computed many times.
// old code
long size = 0;
foreach (IResourceLocation location in allLocations.Distinct())
{
var sizeData = location.Data as ILocationSizeData;
if (sizeData != null)
size += sizeData.ComputeSize(location, ResourceManager);
}
I try to use a for to fill a HashSet, but works in similar way of allLocations.Distinct()
The solution was to use a Dictionary using a key.
// new code
Dictionary<string, IResourceLocation> distinticSet = new Dictionary<string, IResourceLocation>();
foreach (IResourceLocation location in allLocations)
{
if (!distinticSet.ContainsKey(location.PrimaryKey))
distinticSet.Add(location.PrimaryKey, location);
}
long size = 0;
foreach (var entry in distinticSet)
{
var location = entry.Value;
var sizeData = location.Data as ILocationSizeData;
if (sizeData != null)
size += sizeData.ComputeSize(location, ResourceManager);
}
Distinct should work, but it’s possible that the elements in allLocations are each separate instances. So the “normal” comparison would fail. Though the Distinct method can actually take a IEqualityComparer which controls how the elements are compared. Since you want to compare the "PrimaryKey"s you can use a class like this:
public class IResourceLocationComparer : IEqualityComparer<IResourceLocation>
{
public static readonly IResourceLocationComparer inst = new IResourceLocationComparer();
public bool Equals(IResourceLocation x, IResourceLocation y)
{
return x.PrimaryKey == y.PrimaryKey;
}
public int GetHashCode(IResourceLocation obj)
{
return obj.PrimaryKey.GetHashCode();
}
}
and it could be used like this:
foreach (IResourceLocation location in allLocations.Distinct(IResourceLocationComparer.inst))
{
// ...
Though that’s just an assumption. I haven’t looked into the concrete implementations of the addressables.
Well, there is no direct way to suggest code changes. The best bet is to file a bug report in Unity (Help → Report a Bug). There you can explain the issue and attach the current project for them to have a look at. It’s best when you provide a minimal project that reproduces the issue. You may also add a link to this thread in the report.
long size = 0;
foreach (IResourceLocation location in allLocations.Distinct(IResourceLocationComparer.inst))
{
var sizeData = location.Data as ILocationSizeData;
if (sizeData != null)
size += sizeData.ComputeSize(location, ResourceManager);
}
But we have to remove the async before Equals:
public class IResourceLocationComparer : IEqualityComparer<IResourceLocation>
{
public static readonly IResourceLocationComparer inst = new IResourceLocationComparer();
public bool Equals(IResourceLocation x, IResourceLocation y)
{
return x.PrimaryKey == y.PrimaryKey;
}
public int GetHashCode(IResourceLocation obj)
{
return obj.PrimaryKey.GetHashCode();
}
}