update download system

重构下载逻辑代码
This commit is contained in:
何冠峰
2025-07-08 16:41:50 +08:00
parent 090e4f4b15
commit 4b8f2e3acc
6 changed files with 245 additions and 31 deletions

View File

@@ -0,0 +1,122 @@
using UnityEngine.Networking;
using UnityEngine;
namespace YooAsset
{
internal class UnityAssetBundleRequestOperation : UnityWebRequestOperation
{
protected enum ESteps
{
None,
CreateRequest,
Download,
Done,
}
private UnityWebRequestAsyncOperation _requestOperation;
private DownloadHandlerAssetBundle _downloadhandler;
private readonly PackageBundle _packageBundle;
private readonly bool _disableUnityWebCache;
private ESteps _steps = ESteps.None;
/// <summary>
/// 请求结果
/// </summary>
public AssetBundle Result { private set; get; }
internal UnityAssetBundleRequestOperation(PackageBundle packageBundle, bool disableUnityWebCache, string url, int timeout = 60) : base(url, timeout)
{
_packageBundle = packageBundle;
_disableUnityWebCache = disableUnityWebCache;
}
internal override void InternalStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CreateRequest)
{
ResetTimeout();
CreateWebRequest();
_steps = ESteps.Download;
}
if (_steps == ESteps.Download)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = _requestOperation.progress;
if (_requestOperation.isDone == false)
{
CheckRequestTimeout();
return;
}
if (CheckRequestResult())
{
AssetBundle assetBundle = _downloadhandler.assetBundle;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"URL : {_requestURL} Download handler asset bundle object is null !";
}
else
{
_steps = ESteps.Done;
Result = assetBundle;
Status = EOperationStatus.Succeed;
}
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
}
// 注意:最终释放请求器
DisposeRequest();
}
}
internal override void InternalAbort()
{
_steps = ESteps.Done;
DisposeRequest();
}
private void CreateWebRequest()
{
_downloadhandler = CreateWebDownloadHandler();
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
_webRequest.downloadHandler = _downloadhandler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_requestOperation = _webRequest.SendWebRequest();
}
private DownloadHandlerAssetBundle CreateWebDownloadHandler()
{
if (_disableUnityWebCache)
{
var downloadhandler = new DownloadHandlerAssetBundle(_requestURL, _packageBundle.UnityCRC);
#if UNITY_2020_3_OR_NEWER
downloadhandler.autoLoadAssetBundle = false;
#endif
return downloadhandler;
}
else
{
// 注意:优先从浏览器缓存里获取文件
// The file hash defining the version of the asset bundle.
Hash128 fileHash = Hash128.Parse(_packageBundle.FileHash);
var downloadhandler = new DownloadHandlerAssetBundle(_requestURL, fileHash, _packageBundle.UnityCRC);
#if UNITY_2020_3_OR_NEWER
downloadhandler.autoLoadAssetBundle = false;
#endif
return downloadhandler;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e01cc308d7179a34281087fafe455b42
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -5,7 +5,17 @@ namespace YooAsset
{
internal class UnityWebDataRequestOperation : UnityWebRequestOperation
{
protected enum ESteps
{
None,
CreateRequest,
Download,
Done,
}
private UnityWebRequestAsyncOperation _requestOperation;
private bool _checkTimeout = true;
private ESteps _steps = ESteps.None;
/// <summary>
/// 请求结果
@@ -27,27 +37,38 @@ namespace YooAsset
if (_steps == ESteps.CreateRequest)
{
_latestDownloadBytes = 0;
_latestDownloadRealtime = Time.realtimeSinceStartup;
ResetTimeout();
CreateWebRequest();
_steps = ESteps.Download;
}
if (_steps == ESteps.Download)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = _requestOperation.progress;
if (_requestOperation.isDone == false)
{
CheckRequestTimeout();
if (_checkTimeout)
CheckRequestTimeout();
return;
}
if (CheckRequestResult())
{
_steps = ESteps.Done;
Result = _webRequest.downloadHandler.data;
Status = EOperationStatus.Succeed;
var fileData = _webRequest.downloadHandler.data;
if (fileData == null || fileData.Length == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"URL : {_requestURL} Download handler data is null or empty !";
}
else
{
_steps = ESteps.Done;
Result = fileData;
Status = EOperationStatus.Succeed;
}
}
else
{
@@ -65,6 +86,14 @@ namespace YooAsset
DisposeRequest();
}
/// <summary>
/// 不检测超时
/// </summary>
public void DontCheckTimeout()
{
_checkTimeout = false;
}
private void CreateWebRequest()
{
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);

View File

@@ -5,8 +5,18 @@ namespace YooAsset
{
internal class UnityWebFileRequestOperation : UnityWebRequestOperation
{
protected enum ESteps
{
None,
CreateRequest,
Download,
Done,
}
private UnityWebRequestAsyncOperation _requestOperation;
private readonly string _fileSavePath;
private ESteps _steps = ESteps.None;
internal UnityWebFileRequestOperation(string url, string fileSavePath, int timeout = 60) : base(url, timeout)
{
@@ -23,15 +33,15 @@ namespace YooAsset
if (_steps == ESteps.CreateRequest)
{
_latestDownloadBytes = 0;
_latestDownloadRealtime = Time.realtimeSinceStartup;
ResetTimeout();
CreateWebRequest();
_steps = ESteps.Download;
}
if (_steps == ESteps.Download)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = _requestOperation.progress;
if (_requestOperation.isDone == false)
{

View File

@@ -1,6 +1,4 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using UnityEngine.Networking;
using UnityEngine;
@@ -8,24 +6,33 @@ namespace YooAsset
{
internal abstract class UnityWebRequestOperation : AsyncOperationBase
{
protected enum ESteps
{
None,
CreateRequest,
Download,
Done,
}
protected UnityWebRequest _webRequest;
protected readonly string _requestURL;
protected ESteps _steps = ESteps.None;
// 超时相关
protected readonly float _timeout;
protected ulong _latestDownloadBytes;
protected float _latestDownloadRealtime;
private readonly float _timeout;
private ulong _latestDownloadBytes;
private float _latestDownloadRealtime;
private bool _isAbort = false;
/// <summary>
/// HTTP返回码
/// </summary>
public long HttpCode { private set; get; }
/// <summary>
/// 当前下载的字节数
/// </summary>
public long DownloadedBytes { protected set; get; }
/// <summary>
/// 当前下载进度0f - 1f
/// </summary>
public float DownloadProgress { protected set; get; }
/// <summary>
/// 请求的URL地址
/// </summary>
public string URL
{
get { return _requestURL; }
@@ -44,20 +51,33 @@ namespace YooAsset
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
/// <summary>
/// 重置超时计时
/// </summary>
protected void ResetTimeout()
{
_latestDownloadBytes = 0;
_latestDownloadRealtime = Time.realtimeSinceStartup;
}
/// <summary>
/// 检测超时
/// </summary>
protected void CheckRequestTimeout()
{
if (_webRequest.isDone)
return;
// 注意:在连续时间段内无新增下载数据及判定为超时
if (_isAbort == false)
{
if ( _latestDownloadBytes != _webRequest.downloadedBytes)
if (_latestDownloadBytes != _webRequest.downloadedBytes)
{
_latestDownloadBytes = _webRequest.downloadedBytes;
_latestDownloadRealtime = Time.realtimeSinceStartup;
@@ -66,6 +86,7 @@ namespace YooAsset
float offset = Time.realtimeSinceStartup - _latestDownloadRealtime;
if (offset > _timeout)
{
YooLogger.Warning($"Web request timeout : {_requestURL}");
_webRequest.Abort();
_isAbort = true;
}
@@ -77,6 +98,8 @@ namespace YooAsset
/// </summary>
protected bool CheckRequestResult()
{
HttpCode = _webRequest.responseCode;
#if UNITY_2020_3_OR_NEWER
if (_webRequest.result != UnityWebRequest.Result.Success)
{

View File

@@ -5,7 +5,16 @@ namespace YooAsset
{
internal class UnityWebTextRequestOperation : UnityWebRequestOperation
{
protected enum ESteps
{
None,
CreateRequest,
Download,
Done,
}
private UnityWebRequestAsyncOperation _requestOperation;
private ESteps _steps = ESteps.None;
/// <summary>
/// 请求结果
@@ -27,15 +36,15 @@ namespace YooAsset
if (_steps == ESteps.CreateRequest)
{
_latestDownloadBytes = 0;
_latestDownloadRealtime = Time.realtimeSinceStartup;
ResetTimeout();
CreateWebRequest();
_steps = ESteps.Download;
}
if (_steps == ESteps.Download)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = _requestOperation.progress;
if (_requestOperation.isDone == false)
{
@@ -45,9 +54,19 @@ namespace YooAsset
if (CheckRequestResult())
{
_steps = ESteps.Done;
Result = _webRequest.downloadHandler.text;
Status = EOperationStatus.Succeed;
var fileText = _webRequest.downloadHandler.text;
if (string.IsNullOrEmpty(fileText))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"URL : {_requestURL} Download handler text is null or empty !";
}
else
{
_steps = ESteps.Done;
Result = fileText;
Status = EOperationStatus.Succeed;
}
}
else
{