update mini game

This commit is contained in:
何冠峰
2025-07-17 21:23:34 +08:00
parent c2fb7c3cbb
commit ac7ee16017
16 changed files with 612 additions and 423 deletions

View File

@@ -1,16 +1,30 @@
#if UNITY_WEBGL && DOUYINMINIGAME #if UNITY_WEBGL && DOUYINMINIGAME
using UnityEngine; using UnityEngine;
using UnityEngine.Networking;
using YooAsset; using YooAsset;
internal class TTFSDownloadFileOperation : DefaultDownloadFileOperation internal class TTFSDownloadFileOperation : FSDownloadFileOperation
{ {
private TiktokFileSystem _fileSystem; protected enum ESteps
{
None,
CreateRequest,
CheckRequest,
TryAgain,
Done,
}
private readonly TiktokFileSystem _fileSystem;
private readonly DownloadFileOptions _options;
private UnityWebCacheRequestOperation _unityWebCacheRequestOp;
private int _requestCount = 0;
private float _tryAgainTimer;
private int _failedTryAgain;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
internal TTFSDownloadFileOperation(TiktokFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options) internal TTFSDownloadFileOperation(TiktokFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle)
{ {
_fileSystem = fileSystem; _fileSystem = fileSystem;
_options = options;
} }
internal override void InternalStart() internal override void InternalStart()
{ {
@@ -21,81 +35,75 @@ internal class TTFSDownloadFileOperation : DefaultDownloadFileOperation
// 创建下载器 // 创建下载器
if (_steps == ESteps.CreateRequest) if (_steps == ESteps.CreateRequest)
{ {
// 获取请求地址 string url = GetRequestURL();
_requestURL = GetRequestURL(); _unityWebCacheRequestOp = new UnityWebCacheRequestOperation(url);
_unityWebCacheRequestOp.StartOperation();
// 重置变量
ResetRequestFiled();
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest; _steps = ESteps.CheckRequest;
} }
// 检测下载结果 // 检测下载结果
if (_steps == ESteps.CheckRequest) if (_steps == ESteps.CheckRequest)
{ {
DownloadProgress = _webRequest.downloadProgress; Progress = _unityWebCacheRequestOp.Progress;
DownloadedBytes = (long)_webRequest.downloadedBytes; DownloadProgress = _unityWebCacheRequestOp.DownloadProgress;
Progress = DownloadProgress; DownloadedBytes = (long)_unityWebCacheRequestOp.DownloadedBytes;
if (_webRequest.isDone == false) if (_unityWebCacheRequestOp.IsDone == false)
{
CheckRequestTimeout();
return; return;
}
// 检查网络错误 if (_unityWebCacheRequestOp.Status == EOperationStatus.Succeed)
if (CheckRequestResult())
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Succeed; Status = EOperationStatus.Succeed;
//TODO 需要验证抖音插件请求器的下载进度
DownloadProgress = 1f;
DownloadedBytes = Bundle.FileSize;
Progress = 1f;
} }
else else
{
if (_failedTryAgain > 0)
{ {
_steps = ESteps.TryAgain; _steps = ESteps.TryAgain;
YooLogger.Warning($"Failed download : {_unityWebCacheRequestOp.URL} Try again !");
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _unityWebCacheRequestOp.Error;
YooLogger.Error(Error);
}
} }
// 注意:最终释放请求器
DisposeWebRequest();
} }
// 重新尝试下载 // 重新尝试下载
if (_steps == ESteps.TryAgain) if (_steps == ESteps.TryAgain)
{ {
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime; _tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f) if (_tryAgainTimer > 1f)
{ {
FailedTryAgain--; _tryAgainTimer = 0f;
_failedTryAgain--;
Progress = 0f;
DownloadProgress = 0f;
DownloadedBytes = 0;
_steps = ESteps.CreateRequest; _steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
} }
} }
} }
private void CreateWebRequest() /// <summary>
/// 获取网络请求地址
/// </summary>
private string GetRequestURL()
{ {
//TODO : 抖音小游戏没有找到预下载方法 // 轮流返回请求地址
_webRequest = UnityWebRequest.Get(_requestURL); _requestCount++;
_webRequest.disposeDownloadHandlerOnDispose = true; if (_requestCount % 2 == 0)
_webRequest.SendWebRequest(); return _options.FallbackURL;
} else
private void DisposeWebRequest() return _options.MainURL;
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
} }
} }
#endif #endif

View File

@@ -1,6 +1,5 @@
#if UNITY_WEBGL && DOUYINMINIGAME #if UNITY_WEBGL && DOUYINMINIGAME
using UnityEngine; using UnityEngine;
using UnityEngine.Networking;
using YooAsset; using YooAsset;
internal class TTFSLoadBundleOperation : FSLoadBundleOperation internal class TTFSLoadBundleOperation : FSLoadBundleOperation
@@ -14,7 +13,7 @@ internal class TTFSLoadBundleOperation : FSLoadBundleOperation
private readonly TiktokFileSystem _fileSystem; private readonly TiktokFileSystem _fileSystem;
private readonly PackageBundle _bundle; private readonly PackageBundle _bundle;
private DownloadAssetBundleOperation _downloadAssetBundleOp; private LoadWebAssetBundleOperation _loadWebAssetBundleOp;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
internal TTFSLoadBundleOperation(TiktokFileSystem fileSystem, PackageBundle bundle) internal TTFSLoadBundleOperation(TiktokFileSystem fileSystem, PackageBundle bundle)
@@ -33,54 +32,46 @@ internal class TTFSLoadBundleOperation : FSLoadBundleOperation
if (_steps == ESteps.DownloadAssetBundle) if (_steps == ESteps.DownloadAssetBundle)
{ {
if (_downloadAssetBundleOp == null) if (_loadWebAssetBundleOp == null)
{ {
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60); string mainRUL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
options.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); ; string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
options.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName); DownloadFileOptions options = new DownloadFileOptions(int.MaxValue);
options.SetURL(mainRUL, fallbackURL);
if (_bundle.Encrypted) if (_bundle.Encrypted)
{ {
_downloadAssetBundleOp = new DownloadEncryptAssetBundleOperation(false, _fileSystem.DecryptionServices, _bundle, options); _loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(_bundle, options, _fileSystem.DecryptionServices);
_downloadAssetBundleOp.StartOperation(); _loadWebAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp); AddChildOperation(_loadWebAssetBundleOp);
} }
else else
{ {
_downloadAssetBundleOp = new DownloadTiktokAssetBundleOperation(_bundle, options); _loadWebAssetBundleOp = new LoadTiktokAssetBundleOperation(_bundle, options);
_downloadAssetBundleOp.StartOperation(); _loadWebAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp); AddChildOperation(_loadWebAssetBundleOp);
} }
} }
_downloadAssetBundleOp.UpdateOperation(); _loadWebAssetBundleOp.UpdateOperation();
DownloadProgress = _downloadAssetBundleOp.DownloadProgress; DownloadProgress = _loadWebAssetBundleOp.DownloadProgress;
DownloadedBytes = (long)_downloadAssetBundleOp.DownloadedBytes; DownloadedBytes = (long)_loadWebAssetBundleOp.DownloadedBytes;
Progress = DownloadProgress; Progress = DownloadProgress;
if (_downloadAssetBundleOp.IsDone == false) if (_loadWebAssetBundleOp.IsDone == false)
return; return;
if (_downloadAssetBundleOp.Status == EOperationStatus.Succeed) if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeed)
{
var assetBundle = _downloadAssetBundleOp.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(DownloadAssetBundleOperation)} loaded asset bundle is null !";
}
else
{ {
var assetBundle = _loadWebAssetBundleOp.Result;
_steps = ESteps.Done; _steps = ESteps.Done;
Result = new TTAssetBundleResult(_fileSystem, _bundle, assetBundle); Result = new TTAssetBundleResult(_fileSystem, _bundle, assetBundle);
Status = EOperationStatus.Succeed; Status = EOperationStatus.Succeed;
} }
}
else else
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Failed; Status = EOperationStatus.Failed;
Error = _downloadAssetBundleOp.Error; Error = _loadWebAssetBundleOp.Error;
} }
} }
} }

View File

@@ -1,126 +0,0 @@
#if UNITY_WEBGL && DOUYINMINIGAME
using UnityEngine;
using TTSDK;
namespace YooAsset
{
internal class DownloadTiktokAssetBundleOperation : DownloadAssetBundleOperation
{
private ESteps _steps = ESteps.None;
internal DownloadTiktokAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
}
internal override void InternalStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 重置变量
ResetRequestFiled();
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
//TODO 需要验证抖音插件请求器的下载进度
//CheckRequestTimeout();
return;
}
// 检查网络错误
if (CheckRequestResult())
{
var downloadHanlder = (DownloadHandlerTTAssetBundle)_webRequest.downloadHandler;
AssetBundle assetBundle = downloadHanlder.assetBundle;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Download handler asset bundle object is null !";
}
else
{
_steps = ESteps.Done;
Result = assetBundle;
Status = EOperationStatus.Succeed;
//TODO 需要验证抖音插件请求器的下载进度
DownloadProgress = 1f;
DownloadedBytes = Bundle.FileSize;
Progress = 1f;
}
}
else
{
_steps = ESteps.TryAgain;
}
// 注意:最终释放请求器
DisposeWebRequest();
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
FailedTryAgain--;
_steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
}
}
}
internal override void InternalAbort()
{
_steps = ESteps.Done;
DisposeWebRequest();
}
private void CreateWebRequest()
{
_webRequest = TTAssetBundle.GetAssetBundle(_requestURL);
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
}
}
#endif

View File

@@ -0,0 +1,114 @@
#if UNITY_WEBGL && DOUYINMINIGAME
using UnityEngine;
namespace YooAsset
{
internal class LoadTiktokAssetBundleOperation : LoadWebAssetBundleOperation
{
protected enum ESteps
{
None,
CreateRequest,
CheckRequest,
TryAgain,
Done,
}
private readonly PackageBundle _bundle;
private readonly DownloadFileOptions _options;
private UnityTiktokAssetBundleRequestOperation _unityTiktokAssetBundleRequestOp;
private int _requestCount = 0;
private float _tryAgainTimer;
private int _failedTryAgain;
private ESteps _steps = ESteps.None;
internal LoadTiktokAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options)
{
_bundle = bundle;
_options = options;
}
internal override void InternalStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
string url = GetRequestURL();
_unityTiktokAssetBundleRequestOp = new UnityTiktokAssetBundleRequestOperation(_bundle, url);
_unityTiktokAssetBundleRequestOp.StartOperation();
AddChildOperation(_unityTiktokAssetBundleRequestOp);
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
_unityTiktokAssetBundleRequestOp.UpdateOperation();
Progress = _unityTiktokAssetBundleRequestOp.Progress;
DownloadProgress = _unityTiktokAssetBundleRequestOp.DownloadProgress;
DownloadedBytes = (long)_unityTiktokAssetBundleRequestOp.DownloadedBytes;
if (_unityTiktokAssetBundleRequestOp.IsDone == false)
return;
if (_unityTiktokAssetBundleRequestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
Result = _unityTiktokAssetBundleRequestOp.Result;
}
else
{
if (_failedTryAgain > 0)
{
_steps = ESteps.TryAgain;
YooLogger.Warning($"Failed download : {_unityTiktokAssetBundleRequestOp.URL} Try again !");
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _unityTiktokAssetBundleRequestOp.Error;
YooLogger.Error(Error);
}
}
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
_tryAgainTimer = 0f;
_failedTryAgain--;
Progress = 0f;
DownloadProgress = 0f;
DownloadedBytes = 0;
_steps = ESteps.CreateRequest;
}
}
}
/// <summary>
/// 获取网络请求地址
/// </summary>
private string GetRequestURL()
{
// 轮流返回请求地址
_requestCount++;
if (_requestCount % 2 == 0)
return _options.FallbackURL;
else
return _options.MainURL;
}
}
}
#endif

View File

@@ -0,0 +1,95 @@
#if UNITY_WEBGL && DOUYINMINIGAME
using UnityEngine.Networking;
using UnityEngine;
using TTSDK;
namespace YooAsset
{
internal class UnityTiktokAssetBundleRequestOperation : UnityWebRequestOperation
{
protected enum ESteps
{
None,
CreateRequest,
Download,
Done,
}
private readonly PackageBundle _packageBundle;
private UnityWebRequestAsyncOperation _requestOperation;
private ESteps _steps = ESteps.None;
/// <summary>
/// 请求结果
/// </summary>
public AssetBundle Result { private set; get; }
internal UnityTiktokAssetBundleRequestOperation(PackageBundle bundle, string url) : base(url)
{
_packageBundle = bundle;
}
internal override void InternalStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CreateRequest)
{
CreateWebRequest();
_steps = ESteps.Download;
}
if (_steps == ESteps.Download)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = _requestOperation.progress;
if (_requestOperation.isDone == false)
return;
if (CheckRequestResult())
{
var downloadHanlder = (DownloadHandlerTTAssetBundle)_webRequest.downloadHandler;
AssetBundle assetBundle = downloadHanlder.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;
//TODO 需要验证抖音插件请求器的下载进度
DownloadProgress = 1f;
DownloadedBytes = _packageBundle.FileSize;
Progress = 1f;
}
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
}
// 注意:最终释放请求器
DisposeRequest();
}
}
private void CreateWebRequest()
{
_webRequest = TTAssetBundle.GetAssetBundle(_requestURL);
_webRequest.disposeDownloadHandlerOnDispose = true;
_requestOperation = _webRequest.SendWebRequest();
}
}
}
#endif

View File

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

View File

@@ -136,8 +136,9 @@ internal class TiktokFileSystem : IFileSystem
} }
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{ {
options.MainURL = RemoteServices.GetRemoteMainURL(bundle.FileName); string mainURL = RemoteServices.GetRemoteMainURL(bundle.FileName);
options.FallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName); string fallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName);
options.SetURL(mainURL, fallbackURL);
var operation = new TTFSDownloadFileOperation(this, bundle, options); var operation = new TTFSDownloadFileOperation(this, bundle, options);
return operation; return operation;
} }

View File

@@ -1,17 +1,30 @@
#if UNITY_WEBGL && WEIXINMINIGAME #if UNITY_WEBGL && WEIXINMINIGAME
using UnityEngine; using UnityEngine;
using UnityEngine.Networking;
using YooAsset; using YooAsset;
using WeChatWASM;
internal class WXFSDownloadFileOperation : DefaultDownloadFileOperation internal class WXFSDownloadFileOperation : FSDownloadFileOperation
{ {
private WechatFileSystem _fileSystem; protected enum ESteps
{
None,
CreateRequest,
CheckRequest,
TryAgain,
Done,
}
private readonly WechatFileSystem _fileSystem;
private readonly DownloadFileOptions _options;
private UnityWebCacheRequestOperation _unityWebCacheRequestOp;
private int _requestCount = 0;
private float _tryAgainTimer;
private int _failedTryAgain;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
internal WXFSDownloadFileOperation(WechatFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options) internal WXFSDownloadFileOperation(WechatFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle)
{ {
_fileSystem = fileSystem; _fileSystem = fileSystem;
_options = options;
} }
internal override void InternalStart() internal override void InternalStart()
{ {
@@ -22,34 +35,25 @@ internal class WXFSDownloadFileOperation : DefaultDownloadFileOperation
// 创建下载器 // 创建下载器
if (_steps == ESteps.CreateRequest) if (_steps == ESteps.CreateRequest)
{ {
// 获取请求地址 string url = GetRequestURL();
_requestURL = GetRequestURL(); _unityWebCacheRequestOp = new UnityWebCacheRequestOperation(url);
_unityWebCacheRequestOp.SetRequestHeader("wechatminigame-preload", "1");
// 重置变量 _unityWebCacheRequestOp.StartOperation();
ResetRequestFiled(); AddChildOperation(_unityWebCacheRequestOp);
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest; _steps = ESteps.CheckRequest;
} }
// 检测下载结果 // 检测下载结果
if (_steps == ESteps.CheckRequest) if (_steps == ESteps.CheckRequest)
{ {
DownloadProgress = _webRequest.downloadProgress; _unityWebCacheRequestOp.UpdateOperation();
DownloadedBytes = (long)_webRequest.downloadedBytes; Progress = _unityWebCacheRequestOp.Progress;
Progress = DownloadProgress; DownloadProgress = _unityWebCacheRequestOp.DownloadProgress;
if (_webRequest.isDone == false) DownloadedBytes = (long)_unityWebCacheRequestOp.DownloadedBytes;
{ if (_unityWebCacheRequestOp.IsDone == false)
//TODO 由于微信小游戏插件的问题,暂时不能判定超时!
// Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108#
//CheckRequestTimeout();
return; return;
}
// 检查网络错误 if (_unityWebCacheRequestOp.Status == EOperationStatus.Succeed)
if (CheckRequestResult())
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Succeed; Status = EOperationStatus.Succeed;
@@ -61,50 +65,49 @@ internal class WXFSDownloadFileOperation : DefaultDownloadFileOperation
Progress = 1f; Progress = 1f;
} }
else else
{
if (_failedTryAgain > 0)
{ {
_steps = ESteps.TryAgain; _steps = ESteps.TryAgain;
YooLogger.Warning($"Failed download : {_unityWebCacheRequestOp.URL} Try again !");
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _unityWebCacheRequestOp.Error;
YooLogger.Error(Error);
}
} }
// 注意:最终释放请求器
DisposeWebRequest();
} }
// 重新尝试下载 // 重新尝试下载
if (_steps == ESteps.TryAgain) if (_steps == ESteps.TryAgain)
{ {
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime; _tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f) if (_tryAgainTimer > 1f)
{ {
FailedTryAgain--; _tryAgainTimer = 0f;
_failedTryAgain--;
Progress = 0f;
DownloadProgress = 0f;
DownloadedBytes = 0;
_steps = ESteps.CreateRequest; _steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
} }
} }
} }
private void CreateWebRequest() /// <summary>
/// 获取网络请求地址
/// </summary>
private string GetRequestURL()
{ {
_webRequest = UnityWebRequest.Get(_requestURL); // 轮流返回请求地址
_webRequest.SetRequestHeader("wechatminigame-preload", "1"); _requestCount++;
_webRequest.disposeDownloadHandlerOnDispose = true; if (_requestCount % 2 == 0)
_webRequest.SendWebRequest(); return _options.FallbackURL;
} else
private void DisposeWebRequest() return _options.MainURL;
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
} }
} }
#endif #endif

View File

@@ -12,7 +12,7 @@ internal class WXFSLoadBundleOperation : FSLoadBundleOperation
private readonly WechatFileSystem _fileSystem; private readonly WechatFileSystem _fileSystem;
private readonly PackageBundle _bundle; private readonly PackageBundle _bundle;
private DownloadAssetBundleOperation _downloadAssetBundleOp; private LoadWebAssetBundleOperation _loadWebAssetBundleOp;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
internal WXFSLoadBundleOperation(WechatFileSystem fileSystem, PackageBundle bundle) internal WXFSLoadBundleOperation(WechatFileSystem fileSystem, PackageBundle bundle)
@@ -31,54 +31,46 @@ internal class WXFSLoadBundleOperation : FSLoadBundleOperation
if (_steps == ESteps.DownloadAssetBundle) if (_steps == ESteps.DownloadAssetBundle)
{ {
if (_downloadAssetBundleOp == null) if (_loadWebAssetBundleOp == null)
{ {
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60); string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
options.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); ; string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
options.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName); DownloadFileOptions options = new DownloadFileOptions(int.MaxValue);
options.SetURL(mainURL, fallbackURL);
if (_bundle.Encrypted) if (_bundle.Encrypted)
{ {
_downloadAssetBundleOp = new DownloadEncryptAssetBundleOperation(false, _fileSystem.DecryptionServices, _bundle, options); _loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(_bundle, options, _fileSystem.DecryptionServices);
_downloadAssetBundleOp.StartOperation(); _loadWebAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp); AddChildOperation(_loadWebAssetBundleOp);
} }
else else
{ {
_downloadAssetBundleOp = new DownloadWechatAssetBundleOperation(_bundle, options); _loadWebAssetBundleOp = new LoadWechatAssetBundleOperation(_bundle, options);
_downloadAssetBundleOp.StartOperation(); _loadWebAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp); AddChildOperation(_loadWebAssetBundleOp);
} }
} }
_downloadAssetBundleOp.UpdateOperation(); _loadWebAssetBundleOp.UpdateOperation();
DownloadProgress = _downloadAssetBundleOp.DownloadProgress; DownloadProgress = _loadWebAssetBundleOp.DownloadProgress;
DownloadedBytes = (long)_downloadAssetBundleOp.DownloadedBytes; DownloadedBytes = (long)_loadWebAssetBundleOp.DownloadedBytes;
Progress = DownloadProgress; Progress = DownloadProgress;
if (_downloadAssetBundleOp.IsDone == false) if (_loadWebAssetBundleOp.IsDone == false)
return; return;
if (_downloadAssetBundleOp.Status == EOperationStatus.Succeed) if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeed)
{
var assetBundle = _downloadAssetBundleOp.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(DownloadAssetBundleOperation)} loaded asset bundle is null !";
}
else
{ {
var assetBundle = _loadWebAssetBundleOp.Result;
_steps = ESteps.Done; _steps = ESteps.Done;
Result = new WXAssetBundleResult(_fileSystem, _bundle, assetBundle); Result = new WXAssetBundleResult(_fileSystem, _bundle, assetBundle);
Status = EOperationStatus.Succeed; Status = EOperationStatus.Succeed;
} }
}
else else
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Failed; Status = EOperationStatus.Failed;
Error = _downloadAssetBundleOp.Error; Error = _loadWebAssetBundleOp.Error;
} }
} }
} }

View File

@@ -1,128 +0,0 @@
#if UNITY_WEBGL && WEIXINMINIGAME
using UnityEngine;
using WeChatWASM;
namespace YooAsset
{
internal class DownloadWechatAssetBundleOperation : DownloadAssetBundleOperation
{
private ESteps _steps = ESteps.None;
internal DownloadWechatAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
}
internal override void InternalStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 重置变量
ResetRequestFiled();
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
//TODO 由于微信小游戏插件的问题,暂时不能判定超时!
// Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108#
//CheckRequestTimeout();
return;
}
// 检查网络错误
if (CheckRequestResult())
{
var downloadHanlder = (DownloadHandlerWXAssetBundle)_webRequest.downloadHandler;
AssetBundle assetBundle = downloadHanlder.assetBundle;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Download handler asset bundle object is null !";
}
else
{
_steps = ESteps.Done;
Result = assetBundle;
Status = EOperationStatus.Succeed;
//TODO 解决微信小游戏插件问题
// Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108#
DownloadProgress = 1f;
DownloadedBytes = Bundle.FileSize;
Progress = 1f;
}
}
else
{
_steps = ESteps.TryAgain;
}
// 注意:最终释放请求器
DisposeWebRequest();
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
FailedTryAgain--;
_steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
}
}
}
internal override void InternalAbort()
{
_steps = ESteps.Done;
DisposeWebRequest();
}
private void CreateWebRequest()
{
_webRequest = WXAssetBundle.GetAssetBundle(_requestURL);
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
}
}
#endif

View File

@@ -0,0 +1,120 @@
#if UNITY_WEBGL && WEIXINMINIGAME
using UnityEngine;
namespace YooAsset
{
internal class LoadWechatAssetBundleOperation : LoadWebAssetBundleOperation
{
protected enum ESteps
{
None,
CreateRequest,
CheckRequest,
TryAgain,
Done,
}
private readonly PackageBundle _bundle;
private readonly DownloadFileOptions _options;
private UnityWechatAssetBundleRequestOperation _unityWechatAssetBundleRequestOp;
private int _requestCount = 0;
private float _tryAgainTimer;
private int _failedTryAgain;
private ESteps _steps = ESteps.None;
internal LoadWechatAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options)
{
_bundle = bundle;
_options = options;
}
internal override void InternalStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
string url = GetRequestURL();
_unityWechatAssetBundleRequestOp = new UnityWechatAssetBundleRequestOperation(_bundle, url);
_unityWechatAssetBundleRequestOp.StartOperation();
AddChildOperation(_unityWechatAssetBundleRequestOp);
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
_unityWechatAssetBundleRequestOp.UpdateOperation();
Progress = _unityWechatAssetBundleRequestOp.Progress;
DownloadProgress = _unityWechatAssetBundleRequestOp.DownloadProgress;
DownloadedBytes = (long)_unityWechatAssetBundleRequestOp.DownloadedBytes;
if (_unityWechatAssetBundleRequestOp.IsDone == false)
return;
if (_unityWechatAssetBundleRequestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
Result = _unityWechatAssetBundleRequestOp.Result;
}
else
{
if (_failedTryAgain > 0)
{
_steps = ESteps.TryAgain;
YooLogger.Warning($"Failed download : {_unityWechatAssetBundleRequestOp.URL} Try again !");
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _unityWechatAssetBundleRequestOp.Error;
YooLogger.Error(Error);
}
}
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
_tryAgainTimer = 0f;
_failedTryAgain--;
Progress = 0f;
DownloadProgress = 0f;
DownloadedBytes = 0;
_steps = ESteps.CreateRequest;
}
}
}
internal override void InternalAbort()
{
_steps = ESteps.Done;
if (_unityWechatAssetBundleRequestOp != null)
_unityWechatAssetBundleRequestOp.AbortOperation();
}
/// <summary>
/// 获取网络请求地址
/// </summary>
protected string GetRequestURL()
{
// 轮流返回请求地址
_requestCount++;
if (_requestCount % 2 == 0)
return _options.FallbackURL;
else
return _options.MainURL;
}
}
}
#endif

View File

@@ -0,0 +1,96 @@
#if UNITY_WEBGL && WEIXINMINIGAME
using UnityEngine.Networking;
using UnityEngine;
using WeChatWASM;
namespace YooAsset
{
internal class UnityWechatAssetBundleRequestOperation : UnityWebRequestOperation
{
protected enum ESteps
{
None,
CreateRequest,
Download,
Done,
}
private readonly PackageBundle _packageBundle;
private UnityWebRequestAsyncOperation _requestOperation;
private ESteps _steps = ESteps.None;
/// <summary>
/// 请求结果
/// </summary>
public AssetBundle Result { private set; get; }
internal UnityWechatAssetBundleRequestOperation(PackageBundle bundle, string url) : base(url)
{
_packageBundle = bundle;
}
internal override void InternalStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CreateRequest)
{
CreateWebRequest();
_steps = ESteps.Download;
}
if (_steps == ESteps.Download)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = _requestOperation.progress;
if (_requestOperation.isDone == false)
return;
if (CheckRequestResult())
{
var downloadHanlder = (DownloadHandlerWXAssetBundle)_webRequest.downloadHandler;
AssetBundle assetBundle = downloadHanlder.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;
//TODO 解决微信小游戏插件问题
// Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108#
DownloadProgress = 1f;
DownloadedBytes = _packageBundle.FileSize;
Progress = 1f;
}
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
}
// 注意:最终释放请求器
DisposeRequest();
}
}
private void CreateWebRequest()
{
_webRequest = WXAssetBundle.GetAssetBundle(_requestURL);
_webRequest.disposeDownloadHandlerOnDispose = true;
_requestOperation = _webRequest.SendWebRequest();
}
}
}
#endif

View File

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

View File

@@ -151,8 +151,9 @@ internal class WechatFileSystem : IFileSystem
} }
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options) public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{ {
options.MainURL = RemoteServices.GetRemoteMainURL(bundle.FileName); string mainURL = RemoteServices.GetRemoteMainURL(bundle.FileName);
options.FallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName); string fallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName);
options.SetURL(mainURL, fallbackURL);
var operation = new WXFSDownloadFileOperation(this, bundle, options); var operation = new WXFSDownloadFileOperation(this, bundle, options);
return operation; return operation;
} }