AsyncOperationHandle<SceneInstance> aoScene = sceneStarfall.LoadSceneAsync();
aoScene.Completed += result => Trace.Log($"Scene {aoScene.Result.Scene.name} successfully loaded.");
while(!aoScene.IsDone)
{
Debug.Log($"Percent Completed {aoScene.PercentComplete} {aoScene.GetDownloadStatus().DownloadedBytes} {aoScene.GetDownloadStatus().TotalBytes} {aoScene.GetDownloadStatus().Percent}");
yield return null;
}
PercentComplete, will go in 3 steps, since I have 3 bundles to download
Download Status always stay at 0 for TotalBytes, Downloaded, Percent
Are those two method still broken, as seen in many post, or I am doing something wrong?
Unity 2020.2.7f1
Addressable 1.16.16
I’ll bounce this off of the team for some insight.
Still not working with 1.17.13
Ok maybe I am wrong but here is what I found
Under AssetBundleProvider.cs Function BeginOperation you do
else if (ResourceManagerConfig.ShouldPathUseWebRequest(path))
{
var req = CreateWebRequest(m_ProvideHandle.Location);
req.disposeDownloadHandlerOnDispose = false;
if (!WebRequestQueue.ShouldQueueNextRequest)
{
m_RequestOperation = req.SendWebRequest();
if (m_RequestOperation.isDone)
WebRequestOperationCompleted(m_RequestOperation);
else
m_RequestOperation.completed += WebRequestOperationCompleted;
}
else
{
m_WebRequestQueueOperation = WebRequestQueue.QueueRequest(req);
if (m_WebRequestQueueOperation.IsDone)
{
m_RequestOperation = m_WebRequestQueueOperation.Result;
if (m_RequestOperation.isDone)
WebRequestOperationCompleted(m_RequestOperation);
else
m_RequestOperation.completed += WebRequestOperationCompleted;
}
else
{
m_WebRequestQueueOperation.OnComplete += asyncOp =>
{
m_RequestOperation = asyncOp;
m_RequestOperation.completed += WebRequestOperationCompleted;
};
}
}
}
and under the same file
DownloadStatus GetDownloadStatus()
{
if (m_Options == null)
return default;
var status = new DownloadStatus() { TotalBytes = m_BytesToDownload, IsDone = PercentComplete() >= 1f };
if (m_BytesToDownload > 0)
{
if (m_WebRequestQueueOperation != null && string.IsNullOrEmpty(m_WebRequestQueueOperation.m_WebRequest.error))
m_DownloadedBytes = (long)(m_WebRequestQueueOperation.m_WebRequest.downloadedBytes);
}
status.DownloadedBytes = m_DownloadedBytes;
return status;
}
So you calculate the byteProgress base on m_WebRequestQueueOperation but that variable is set only in BeginOperation, and only if queue… if not you never assign it, therefore all downloaded bytes stay at 0.
Keeping to look… see if I find a way…
Inside GetDownloadStatus, I can get Downloaded byte from m_RequestOperation, however they are private field so not accessible without a change
Ok… I found a solution that work for me… I modify the GetDownloadStatus in AssetBundleProvider to
float PercentComplete() { return m_RequestOperation != null ? m_RequestOperation.progress : 0.0f; }
DownloadStatus GetDownloadStatus()
{
if (m_Options == null)
return default;
var status = new DownloadStatus() { TotalBytes = m_BytesToDownload, IsDone = PercentComplete() >= 1f };
if (m_BytesToDownload > 0)
{
if (m_WebRequestQueueOperation != null && string.IsNullOrEmpty(m_WebRequestQueueOperation.m_WebRequest.error))
m_DownloadedBytes = (long)(m_WebRequestQueueOperation.m_WebRequest.downloadedBytes);
else if (m_RequestOperation != null && string.IsNullOrEmpty((m_RequestOperation as UnityWebRequestAsyncOperation).webRequest.error))
m_DownloadedBytes = (long)(m_RequestOperation as UnityWebRequestAsyncOperation).webRequest.downloadedBytes;
}
status.DownloadedBytes = m_DownloadedBytes;
return status;
}
Two line added and now both the ASyncOperationHandle.Progress work and the DownloadStatus…
Hi @Morphus74
Apologies for the delay.
Last Friday, I tried to replicate your exact use case but it seemed to work on my end so I was about to ask you for more details.
However, what you found seem to be correct at first sight : the downloaded bytes should be retrieved from m_RequestOperation when the request is not queued. Thanks for sharing your findings. I’ll merge these changes after investigating a little more. They should be included in the next release.
Glad it now works correctly for you. As always, don’t hesitate if there’s anything else.
For others reading this, note that there are some cases where the DownloadStatus will have 0 for the TotalBytes, Downloaded and Percent :
- when the catalog is first retrieved in the initialization operation
- when asset bundles are retrieved from the cache instead of being downloaded
Hi @oliviergc
Happy to see that my analysis was right 
If you can, please have a look to Bug - Scene LoadAsync with custom AssetBundleProvider not working - Unity Forum
This is an other “easy” case I think that is forcing me to use my own fork of addressable
1 Like
any one still having problems wioth download status here is the solution , make sure you have latest package for addressables, here is my working script:
private IEnumerator C_DownloadGameT(string gameName)
{
AsyncOperationHandle<long> firstCheck = Addressables.GetDownloadSizeAsync(gameName);
yield return firstCheck;
while (!firstCheck.IsDone)
{
}
if (firstCheck.Status == AsyncOperationStatus.Failed)
{
StartCoroutine(C_DownloadGameT(gameName));
}
if(firstCheck.Status == AsyncOperationStatus.Succeeded)
{
DownloadSize = firstCheck.Result;
realSize =(float)Math.Round(DownloadSize / 1000000f,2);
}
if (firstCheck.Result > 0)
{
GameManager.Instance.GameState = GameState.downloading;
AsyncOperationHandle handleCatalog = Addressables.DownloadDependenciesAsync(gameName);
while (!handleCatalog.GetDownloadStatus().IsDone)
{
GameManager.Instance.UI.Slider.value += (handleCatalog.GetDownloadStatus().Percent *100)/ DownloadSize;
GameManager.Instance.UI.TotalText.text = ((float)Math.Round(handleCatalog.GetDownloadStatus().DownloadedBytes/1000000f,2)).ToString() + "/" +realSize.ToString()+"MB";
yield return null;
}
if (handleCatalog.Status == AsyncOperationStatus.Failed)
{
// show internet error quit unity
}
if (handleCatalog.Status == AsyncOperationStatus.Succeeded)
{
LoadGameT(gameName);
}
}
else
{
LoadGameT(gameName);
}
yield return 0;
}
GetDownloadStatus() was they key function
It work only if you have QUEUEWebRequest, not if you have DirectRequest