Compare commits

..

8 Commits

Author SHA1 Message Date
absences 6a985ac0a1
Merge 02250c3352 into f0ed677d86 2024-12-16 10:07:37 +08:00
何冠峰 f0ed677d86 refactor : remove DryRunBuild build mode
移除演练构建模式
2024-12-13 14:32:17 +08:00
何冠峰 4b0c52d2dd fix #404 2024-12-13 14:10:12 +08:00
何冠峰 5f4e1d0b2f update package
scriptablebuildpipeline版本切换为1.21.25
2024-12-13 11:44:55 +08:00
何冠峰 a98a48a58d Update TaskCreateManifest.cs 2024-12-13 11:12:09 +08:00
何冠峰 763054884b fix #387 2024-12-13 11:00:30 +08:00
何冠峰 376088e63c update space shoot 2024-12-13 10:25:56 +08:00
何冠峰 c614ba4705 fix #402 2024-12-13 10:25:16 +08:00
40 changed files with 319 additions and 355 deletions

View File

@ -25,6 +25,9 @@ namespace YooAsset.Editor
var buildParameters = buildParametersContext.Parameters; var buildParameters = buildParametersContext.Parameters;
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
// 检测资源包哈希冲突
CheckBundleHashConflict(buildMapContext);
// 创建新补丁清单 // 创建新补丁清单
PackageManifest manifest = new PackageManifest(); PackageManifest manifest = new PackageManifest();
manifest.FileVersion = YooAssetSettings.ManifestFileVersion; manifest.FileVersion = YooAssetSettings.ManifestFileVersion;
@ -88,6 +91,28 @@ namespace YooAsset.Editor
} }
} }
/// <summary>
/// 检测资源包哈希冲突
/// </summary>
private void CheckBundleHashConflict(BuildMapContext buildMapContext)
{
// 说明:在特殊情况下,例如某些文件加密算法会导致加密后的文件哈希值冲突!
// 说明:二进制完全相同的原生文件也会冲突!
HashSet<string> guids = new HashSet<string>();
foreach (var bundleInfo in buildMapContext.Collection)
{
if (guids.Contains(bundleInfo.PackageFileHash))
{
string message = BuildLogger.GetErrorMessage(ErrorCode.BundleHashConflict, $"Bundle hash conflict : {bundleInfo.BundleName}");
throw new Exception(message);
}
else
{
guids.Add(bundleInfo.PackageFileHash);
}
}
}
/// <summary> /// <summary>
/// 获取资源包的依赖集合 /// 获取资源包的依赖集合
/// </summary> /// </summary>

View File

@ -35,14 +35,12 @@ namespace YooAsset.Editor
throw new Exception(message); throw new Exception(message);
} }
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild) // 检测输出目录
string unityOutputManifestFilePath = $"{pipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}";
if (System.IO.File.Exists(unityOutputManifestFilePath) == false)
{ {
string unityOutputManifestFilePath = $"{pipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}"; string message = BuildLogger.GetErrorMessage(ErrorCode.UnityEngineBuildFatal, $"Not found output {nameof(AssetBundleManifest)} file : {unityOutputManifestFilePath}");
if (System.IO.File.Exists(unityOutputManifestFilePath) == false) throw new Exception(message);
{
string message = BuildLogger.GetErrorMessage(ErrorCode.UnityEngineBuildFatal, $"Not found output {nameof(AssetBundleManifest)} file : {unityOutputManifestFilePath}");
throw new Exception(message);
}
} }
BuildLogger.Log("UnityEngine build success !"); BuildLogger.Log("UnityEngine build success !");

View File

@ -10,7 +10,7 @@ namespace YooAsset.Editor
var buildParameters = context.GetContextObject<BuildParametersContext>(); var buildParameters = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>(); var buildMapContext = context.GetContextObject<BuildMapContext>();
var buildMode = buildParameters.Parameters.BuildMode; var buildMode = buildParameters.Parameters.BuildMode;
if (buildMode != EBuildMode.SimulateBuild && buildMode != EBuildMode.DryRunBuild) if (buildMode != EBuildMode.SimulateBuild)
{ {
CreatePackageCatalog(buildParameters, buildMapContext); CreatePackageCatalog(buildParameters, buildMapContext);
} }

View File

@ -18,7 +18,7 @@ namespace YooAsset.Editor
var buildParametersContext = context.GetContextObject<BuildParametersContext>(); var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var parameters = buildParametersContext.Parameters; var parameters = buildParametersContext.Parameters;
var buildMode = parameters.BuildMode; var buildMode = parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild) if (buildMode == EBuildMode.SimulateBuild)
{ {
return "00000000000000000000000000000000"; //32位 return "00000000000000000000000000000000"; //32位
} }
@ -42,7 +42,7 @@ namespace YooAsset.Editor
var buildParametersContext = context.GetContextObject<BuildParametersContext>(); var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var parameters = buildParametersContext.Parameters; var parameters = buildParametersContext.Parameters;
var buildMode = parameters.BuildMode; var buildMode = parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild) if (buildMode == EBuildMode.SimulateBuild)
{ {
return 0; return 0;
} }
@ -64,7 +64,7 @@ namespace YooAsset.Editor
{ {
string filePath = bundleInfo.PackageSourceFilePath; string filePath = bundleInfo.PackageSourceFilePath;
var buildMode = buildParametersContext.Parameters.BuildMode; var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild) if (buildMode == EBuildMode.SimulateBuild)
return GetFilePathTempHash(filePath); return GetFilePathTempHash(filePath);
else else
return HashUtility.FileMD5(filePath); return HashUtility.FileMD5(filePath);
@ -73,7 +73,7 @@ namespace YooAsset.Editor
{ {
string filePath = bundleInfo.PackageSourceFilePath; string filePath = bundleInfo.PackageSourceFilePath;
var buildMode = buildParametersContext.Parameters.BuildMode; var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild) if ( buildMode == EBuildMode.SimulateBuild)
return "00000000"; //8位 return "00000000"; //8位
else else
return HashUtility.FileCRC32(filePath); return HashUtility.FileCRC32(filePath);
@ -82,7 +82,7 @@ namespace YooAsset.Editor
{ {
string filePath = bundleInfo.PackageSourceFilePath; string filePath = bundleInfo.PackageSourceFilePath;
var buildMode = buildParametersContext.Parameters.BuildMode; var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild) if (buildMode == EBuildMode.SimulateBuild)
return GetBundleTempSize(bundleInfo); return GetBundleTempSize(bundleInfo);
else else
return FileUtility.GetFileSize(filePath); return FileUtility.GetFileSize(filePath);

View File

@ -34,12 +34,6 @@ namespace YooAsset.Editor
BuildAssetBundleOptions opt = BuildAssetBundleOptions.None; BuildAssetBundleOptions opt = BuildAssetBundleOptions.None;
opt |= BuildAssetBundleOptions.StrictMode; //Do not allow the build to succeed if any errors are reporting during it. opt |= BuildAssetBundleOptions.StrictMode; //Do not allow the build to succeed if any errors are reporting during it.
if (BuildMode == EBuildMode.DryRunBuild)
{
opt |= BuildAssetBundleOptions.DryRunBuild;
return opt;
}
if (CompressOption == ECompressOption.Uncompressed) if (CompressOption == ECompressOption.Uncompressed)
opt |= BuildAssetBundleOptions.UncompressedAssetBundle; opt |= BuildAssetBundleOptions.UncompressedAssetBundle;
else if (CompressOption == ECompressOption.LZ4) else if (CompressOption == ECompressOption.LZ4)

View File

@ -24,11 +24,6 @@ namespace YooAsset.Editor
} }
// 检测不被支持的构建模式 // 检测不被支持的构建模式
if (buildParameters.BuildMode == EBuildMode.DryRunBuild)
{
string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineNotSupportBuildMode, $"{nameof(EBuildPipeline.RawFileBuildPipeline)} not support {nameof(EBuildMode.DryRunBuild)} build mode !");
throw new Exception(message);
}
if (buildParameters.BuildMode == EBuildMode.IncrementalBuild) if (buildParameters.BuildMode == EBuildMode.IncrementalBuild)
{ {
string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineNotSupportBuildMode, $"{nameof(EBuildPipeline.RawFileBuildPipeline)} not support {nameof(EBuildMode.IncrementalBuild)} build mode !"); string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineNotSupportBuildMode, $"{nameof(EBuildPipeline.RawFileBuildPipeline)} not support {nameof(EBuildMode.IncrementalBuild)} build mode !");

View File

@ -32,7 +32,7 @@ namespace YooAsset.Editor
// 开始构建 // 开始构建
IBundleBuildResults buildResults; IBundleBuildResults buildResults;
var buildParameters = scriptableBuildParameters.GetBundleBuildParameters(); var buildParameters = scriptableBuildParameters.GetBundleBuildParameters();
var taskList = SBPBuildTasks.Create(buildMapContext.Command.ShadersBundleName); var taskList = SBPBuildTasks.Create(buildMapContext.Command.ShadersBundleName, null);
ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParameters, buildContent, out buildResults, taskList); ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParameters, buildContent, out buildResults, taskList);
if (exitCode < 0) if (exitCode < 0)
{ {

View File

@ -17,11 +17,6 @@ namespace YooAsset.Editor
buildParametersContext.CheckBuildParameters(); buildParametersContext.CheckBuildParameters();
// 检测不被支持的构建模式 // 检测不被支持的构建模式
if (buildParameters.BuildMode == EBuildMode.DryRunBuild)
{
string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineNotSupportBuildMode, $"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.DryRunBuild)} build mode !");
throw new Exception(message);
}
if (buildParameters.BuildMode == EBuildMode.ForceRebuild) if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
{ {
string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineNotSupportBuildMode, $"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.ForceRebuild)} build mode !"); string message = BuildLogger.GetErrorMessage(ErrorCode.BuildPipelineNotSupportBuildMode, $"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.ForceRebuild)} build mode !");

View File

@ -9,7 +9,7 @@ namespace UnityEditor.Build.Pipeline.Tasks
{ {
public static class SBPBuildTasks public static class SBPBuildTasks
{ {
public static IList<IBuildTask> Create(string builtInShaderBundleName) public static IList<IBuildTask> Create(string builtInShaderBundleName, string unityMonoScriptsBundleName)
{ {
var buildTasks = new List<IBuildTask>(); var buildTasks = new List<IBuildTask>();
@ -28,13 +28,10 @@ namespace UnityEditor.Build.Pipeline.Tasks
#endif #endif
buildTasks.Add(new CalculateAssetDependencyData()); buildTasks.Add(new CalculateAssetDependencyData());
buildTasks.Add(new StripUnusedSpriteSources()); buildTasks.Add(new StripUnusedSpriteSources());
if (string.IsNullOrEmpty(builtInShaderBundleName) == false)
#if TUANJIE_1_0_OR_NEWER buildTasks.Add(new CreateBuiltInShadersBundle(builtInShaderBundleName));
buildTasks.Add(new CreateBuiltInShadersBundle(builtInShaderBundleName)); if (string.IsNullOrEmpty(unityMonoScriptsBundleName) == false)
#else buildTasks.Add(new CreateMonoScriptBundle(unityMonoScriptsBundleName));
buildTasks.Add(new CreateBuiltInBundle(builtInShaderBundleName));
#endif
buildTasks.Add(new PostDependencyCallback()); buildTasks.Add(new PostDependencyCallback());
// Packing // Packing

View File

@ -39,5 +39,6 @@ namespace YooAsset.Editor
// TaskCreateManifest // TaskCreateManifest
NotFoundUnityBundleInBuildResult = 600, NotFoundUnityBundleInBuildResult = 600,
FoundStrayBundle = 601, FoundStrayBundle = 601,
BundleHashConflict = 602,
} }
} }

View File

@ -16,11 +16,6 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
IncrementalBuild, IncrementalBuild,
/// <summary>
/// 演练构建模式
/// </summary>
DryRunBuild,
/// <summary> /// <summary>
/// 模拟构建模式 /// 模拟构建模式
/// </summary> /// </summary>

View File

@ -55,7 +55,6 @@ namespace YooAsset.Editor
List<Enum> buildModeList = new List<Enum>(); List<Enum> buildModeList = new List<Enum>();
buildModeList.Add(EBuildMode.ForceRebuild); buildModeList.Add(EBuildMode.ForceRebuild);
buildModeList.Add(EBuildMode.IncrementalBuild); buildModeList.Add(EBuildMode.IncrementalBuild);
buildModeList.Add(EBuildMode.DryRunBuild);
buildModeList.Add(EBuildMode.SimulateBuild); buildModeList.Add(EBuildMode.SimulateBuild);
return buildModeList; return buildModeList;
} }

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace YooAsset namespace YooAsset
{ {
internal sealed class ClearAllCacheFilesOperation : FSClearAllBundleFilesOperation internal sealed class ClearAllCacheFilesOperation : FSClearCacheBundleFilesOperation
{ {
private enum ESteps private enum ESteps
{ {

View File

@ -0,0 +1,120 @@
using System.Collections.Generic;
namespace YooAsset
{
internal class ClearCacheFilesByTagsOperaiton : FSClearCacheBundleFilesOperation
{
private enum ESteps
{
None,
CheckArgs,
GetTagsCacheFiles,
ClearTagsCacheFiles,
Done,
}
private readonly ICacheSystem _cacheSystem;
private readonly PackageManifest _manifest;
private readonly object _clearParam;
private string[] _tags;
private List<string> _clearBundleGUIDs;
private int _clearFileTotalCount = 0;
private ESteps _steps = ESteps.None;
internal ClearCacheFilesByTagsOperaiton(ICacheSystem cacheSystem, PackageManifest manifest, object clearParam)
{
_cacheSystem = cacheSystem;
_manifest = manifest;
_clearParam = clearParam;
}
internal override void InternalOnStart()
{
_steps = ESteps.CheckArgs;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckArgs)
{
if (_clearParam == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Clear param is null !";
return;
}
if (_clearParam is string)
{
_tags = new string[] { _clearParam as string };
}
else if (_clearParam is List<string>)
{
var tempList = _clearParam as List<string>;
_tags = tempList.ToArray();
}
else if (_clearParam is string[])
{
_tags = _clearParam as string[];
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Invalid clear param : {_clearParam.GetType().FullName}";
return;
}
_steps = ESteps.GetTagsCacheFiles;
}
if (_steps == ESteps.GetTagsCacheFiles)
{
_clearBundleGUIDs = GetTagsBundleGUIDs();
_clearFileTotalCount = _clearBundleGUIDs.Count;
_steps = ESteps.ClearTagsCacheFiles;
}
if (_steps == ESteps.ClearTagsCacheFiles)
{
for (int i = _clearBundleGUIDs.Count - 1; i >= 0; i--)
{
string bundleGUID = _clearBundleGUIDs[i];
_cacheSystem.DeleteCacheFile(bundleGUID);
_clearBundleGUIDs.RemoveAt(i);
if (OperationSystem.IsBusy)
break;
}
if (_clearFileTotalCount == 0)
Progress = 1.0f;
else
Progress = 1.0f - (_clearBundleGUIDs.Count / _clearFileTotalCount);
if (_clearBundleGUIDs.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
private List<string> GetTagsBundleGUIDs()
{
var allBundleGUIDs = _cacheSystem.GetAllCachedBundleGUIDs();
List<string> result = new List<string>(allBundleGUIDs.Count);
foreach (var bundleGUID in allBundleGUIDs)
{
if (_manifest.TryGetPackageBundleByBundleGUID(bundleGUID, out PackageBundle bundle))
{
if (bundle.HasTag(_tags))
{
result.Add(bundleGUID);
}
}
}
return result;
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 4f25029d71d0d8c4dad70987bda364bf guid: c42345c14a903274fb160a813ee174dc
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace YooAsset namespace YooAsset
{ {
internal sealed class ClearUnusedCacheFilesOperation : FSClearUnusedBundleFilesOperation internal sealed class ClearUnusedCacheFilesOperation : FSClearCacheBundleFilesOperation
{ {
private enum ESteps private enum ESteps
{ {

View File

@ -97,13 +97,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }
public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync() public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{ {
return _unpackFileSystem.ClearAllBundleFilesAsync(); return _unpackFileSystem.ClearCacheBundleFilesAsync(manifest, clearMode, clearParam);
}
public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(PackageManifest manifest)
{
return _unpackFileSystem.ClearUnusedBundleFilesAsync(manifest);
} }
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param) public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
{ {

View File

@ -111,17 +111,33 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }
public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync() public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{ {
var operation = new ClearAllCacheFilesOperation(this); if(clearMode == EFileClearMode.ClearAllBundleFiles.ToString())
OperationSystem.StartOperation(PackageName, operation); {
return operation; var operation = new ClearAllCacheFilesOperation(this);
} OperationSystem.StartOperation(PackageName, operation);
public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(PackageManifest manifest) return operation;
{ }
var operation = new ClearUnusedCacheFilesOperation(this, manifest); else if(clearMode == EFileClearMode.ClearUnusedBundleFiles.ToString())
OperationSystem.StartOperation(PackageName, operation); {
return operation; var operation = new ClearUnusedCacheFilesOperation(this, manifest);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
else if(clearMode == EFileClearMode.ClearBundleFilesByTags.ToString())
{
var operation = new ClearCacheFilesByTagsOperaiton(this, manifest, clearParam);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
else
{
string error = $"Invalid clear mode : {clearMode}";
var operation = new FSClearCacheBundleFilesCompleteOperation(error);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
} }
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param) public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
{ {

View File

@ -69,15 +69,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }
public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync() public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{ {
var operation = new FSClearAllBundleFilesCompleteOperation(); var operation = new FSClearCacheBundleFilesCompleteOperation(null);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(PackageManifest manifest)
{
var operation = new FSClearUnusedBundleFilesCompleteOperation();
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }

View File

@ -71,15 +71,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }
public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync() public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{ {
var operation = new FSClearAllBundleFilesCompleteOperation(); var operation = new FSClearCacheBundleFilesCompleteOperation(null);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(PackageManifest manifest)
{
var operation = new FSClearUnusedBundleFilesCompleteOperation();
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }

View File

@ -80,15 +80,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }
public virtual FSClearAllBundleFilesOperation ClearAllBundleFilesAsync() public virtual FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
{ {
var operation = new FSClearAllBundleFilesCompleteOperation(); var operation = new FSClearCacheBundleFilesCompleteOperation(null);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
public virtual FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(PackageManifest manifest)
{
var operation = new FSClearUnusedBundleFilesCompleteOperation();
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }

View File

@ -0,0 +1,25 @@

namespace YooAsset
{
/// <summary>
/// 文件清理方式
/// </summary>
public enum EFileClearMode
{
/// <summary>
/// 清理所有文件
/// </summary>
ClearAllBundleFiles = 1,
/// <summary>
/// 清理未在使用的文件
/// </summary>
ClearUnusedBundleFiles = 2,
/// <summary>
/// 清理指定标签的文件
/// 说明需要指定参数可选string, string[], List<string>
/// </summary>
ClearBundleFilesByTags = 3,
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: e9fe9171073a87746a7393f7d1fcb924 guid: 2930435fc2ba91c4ba511260b9d119d3
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -35,14 +35,9 @@ namespace YooAsset
FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout); FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout);
/// <summary> /// <summary>
/// 清空所有的文件 /// 清理缓存文件
/// </summary> /// </summary>
FSClearAllBundleFilesOperation ClearAllBundleFilesAsync(); FSClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(PackageManifest manifest, string clearMode, object clearParam);
/// <summary>
/// 清空未使用的文件
/// </summary>
FSClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync(PackageManifest manifest);
/// <summary> /// <summary>
/// 下载远端文件 /// 下载远端文件

View File

@ -1,21 +0,0 @@

namespace YooAsset
{
internal abstract class FSClearAllBundleFilesOperation : AsyncOperationBase
{
}
internal sealed class FSClearAllBundleFilesCompleteOperation : FSClearAllBundleFilesOperation
{
internal FSClearAllBundleFilesCompleteOperation()
{
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
}

View File

@ -0,0 +1,32 @@

namespace YooAsset
{
internal abstract class FSClearCacheBundleFilesOperation : AsyncOperationBase
{
}
internal sealed class FSClearCacheBundleFilesCompleteOperation : FSClearCacheBundleFilesOperation
{
private readonly string _error;
internal FSClearCacheBundleFilesCompleteOperation(string error)
{
_error = error;
}
internal override void InternalOnStart()
{
if (string.IsNullOrEmpty(_error))
{
Status = EOperationStatus.Succeed;
}
else
{
Status = EOperationStatus.Failed;
Error = _error;
}
}
internal override void InternalOnUpdate()
{
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 39028a4006030f1469b636b0c8b3805a guid: b39545a4da23ce34abdf8da069198426
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -1,21 +0,0 @@

namespace YooAsset
{
internal abstract class FSClearUnusedBundleFilesOperation : AsyncOperationBase
{
}
internal sealed class FSClearUnusedBundleFilesCompleteOperation : FSClearUnusedBundleFilesOperation
{
internal FSClearUnusedBundleFilesCompleteOperation()
{
}
internal override void InternalOnStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
}
}
}

View File

@ -22,7 +22,7 @@ namespace YooAsset
private readonly bool _actived; private readonly bool _actived;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
#if UNITY_2022_3_OR_NEWER #if UNITY_2023_3_OR_NEWER
private AsyncInstantiateOperation _instantiateAsync; private AsyncInstantiateOperation _instantiateAsync;
#endif #endif
@ -73,7 +73,7 @@ namespace YooAsset
return; return;
} }
#if UNITY_2022_3_OR_NEWER #if UNITY_2023_3_OR_NEWER
//TODO //TODO
// BUG环境Windows平台Unity2022.3.41f1版本,编辑器模式。 // BUG环境Windows平台Unity2022.3.41f1版本,编辑器模式。
// BUG描述异步实例化Prefab预制体有概率丢失Mono脚本里序列化的数组里某个成员 // BUG描述异步实例化Prefab预制体有概率丢失Mono脚本里序列化的数组里某个成员
@ -95,7 +95,7 @@ namespace YooAsset
Status = EOperationStatus.Succeed; Status = EOperationStatus.Succeed;
} }
#if UNITY_2022_3_OR_NEWER #if UNITY_2023_3_OR_NEWER
if (_steps == ESteps.CloneAsync) if (_steps == ESteps.CloneAsync)
{ {
if (_instantiateAsync == null) if (_instantiateAsync == null)
@ -157,7 +157,7 @@ namespace YooAsset
/// </summary> /// </summary>
public void Cancel() public void Cancel()
{ {
#if UNITY_2022_3_OR_NEWER #if UNITY_2023_3_OR_NEWER
if (_instantiateAsync != null && _instantiateAsync.isDone == false) if (_instantiateAsync != null && _instantiateAsync.isDone == false)
_instantiateAsync.Cancel(); _instantiateAsync.Cancel();
#endif #endif
@ -189,10 +189,10 @@ namespace YooAsset
} }
} }
#if UNITY_2022_3_OR_NEWER #if UNITY_2023_3_OR_NEWER
/// <summary> /// <summary>
/// 异步实例化 /// 异步实例化
/// 注意Unity2022.3及以上版本生效 /// 注意Unity2022.3.20f1及以上版本生效
/// https://docs.unity3d.com/2022.3/Documentation/ScriptReference/Object.InstantiateAsync.html /// https://docs.unity3d.com/2022.3/Documentation/ScriptReference/Object.InstantiateAsync.html
/// </summary> /// </summary>
internal static AsyncInstantiateOperation InstantiateAsyncInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) internal static AsyncInstantiateOperation InstantiateAsyncInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays)

View File

@ -29,14 +29,9 @@ namespace YooAsset
PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout); PreDownloadContentOperation PreDownloadContentAsync(string packageVersion, int timeout);
/// <summary> /// <summary>
/// 清空所有文件 /// 清理缓存文件
/// </summary> /// </summary>
ClearAllBundleFilesOperation ClearAllBundleFilesAsync(); ClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(string clearMode, object clearParam);
/// <summary>
/// 清空未使用的文件
/// </summary>
ClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync();
// 下载相关 // 下载相关
ResourceDownloaderOperation CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout); ResourceDownloaderOperation CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout);

View File

@ -1,13 +1,10 @@
 
namespace YooAsset namespace YooAsset
{ {
/// <summary> public abstract class ClearCacheBundleFilesOperation : AsyncOperationBase
/// 清理所有文件
/// </summary>
public abstract class ClearAllBundleFilesOperation : AsyncOperationBase
{ {
} }
internal sealed class ClearAllBundleFilesImplOperation : ClearAllBundleFilesOperation internal sealed class ClearCacheBundleFilesImplOperation : ClearCacheBundleFilesOperation
{ {
private enum ESteps private enum ESteps
{ {
@ -22,17 +19,21 @@ namespace YooAsset
private readonly IFileSystem _fileSystemA; private readonly IFileSystem _fileSystemA;
private readonly IFileSystem _fileSystemB; private readonly IFileSystem _fileSystemB;
private readonly IFileSystem _fileSystemC; private readonly IFileSystem _fileSystemC;
private FSClearAllBundleFilesOperation _clearAllBundleFilesOpA; private readonly string _clearMode;
private FSClearAllBundleFilesOperation _clearAllBundleFilesOpB; private readonly object _clearParam;
private FSClearAllBundleFilesOperation _clearAllBundleFilesOpC; private FSClearCacheBundleFilesOperation _clearCacheBundleFilesOpA;
private FSClearCacheBundleFilesOperation _clearCacheBundleFilesOpB;
private FSClearCacheBundleFilesOperation _clearCacheBundleFilesOpC;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
internal ClearAllBundleFilesImplOperation(IPlayMode impl, IFileSystem fileSystemA, IFileSystem fileSystemB, IFileSystem fileSystemC) internal ClearCacheBundleFilesImplOperation(IPlayMode impl, IFileSystem fileSystemA, IFileSystem fileSystemB, IFileSystem fileSystemC, string clearMode, object clearParam)
{ {
_impl = impl; _impl = impl;
_fileSystemA = fileSystemA; _fileSystemA = fileSystemA;
_fileSystemB = fileSystemB; _fileSystemB = fileSystemB;
_fileSystemC = fileSystemC; _fileSystemC = fileSystemC;
_clearMode = clearMode;
_clearParam = clearParam;
} }
internal override void InternalOnStart() internal override void InternalOnStart()
{ {
@ -51,14 +52,14 @@ namespace YooAsset
return; return;
} }
if (_clearAllBundleFilesOpA == null) if (_clearCacheBundleFilesOpA == null)
_clearAllBundleFilesOpA = _fileSystemA.ClearAllBundleFilesAsync(); _clearCacheBundleFilesOpA = _fileSystemA.ClearCacheBundleFilesAsync(_impl.ActiveManifest, _clearMode, _clearParam);
Progress = _clearAllBundleFilesOpA.Progress; Progress = _clearCacheBundleFilesOpA.Progress;
if (_clearAllBundleFilesOpA.IsDone == false) if (_clearCacheBundleFilesOpA.IsDone == false)
return; return;
if (_clearAllBundleFilesOpA.Status == EOperationStatus.Succeed) if (_clearCacheBundleFilesOpA.Status == EOperationStatus.Succeed)
{ {
_steps = ESteps.ClearFileSystemB; _steps = ESteps.ClearFileSystemB;
} }
@ -66,7 +67,7 @@ namespace YooAsset
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Failed; Status = EOperationStatus.Failed;
Error = _clearAllBundleFilesOpA.Error; Error = _clearCacheBundleFilesOpA.Error;
} }
} }
@ -78,14 +79,14 @@ namespace YooAsset
return; return;
} }
if (_clearAllBundleFilesOpB == null) if (_clearCacheBundleFilesOpB == null)
_clearAllBundleFilesOpB = _fileSystemB.ClearAllBundleFilesAsync(); _clearCacheBundleFilesOpB = _fileSystemB.ClearCacheBundleFilesAsync(_impl.ActiveManifest, _clearMode, _clearParam);
Progress = _clearAllBundleFilesOpB.Progress; Progress = _clearCacheBundleFilesOpB.Progress;
if (_clearAllBundleFilesOpB.IsDone == false) if (_clearCacheBundleFilesOpB.IsDone == false)
return; return;
if (_clearAllBundleFilesOpB.Status == EOperationStatus.Succeed) if (_clearCacheBundleFilesOpB.Status == EOperationStatus.Succeed)
{ {
_steps = ESteps.ClearFileSystemC; _steps = ESteps.ClearFileSystemC;
} }
@ -93,7 +94,7 @@ namespace YooAsset
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Failed; Status = EOperationStatus.Failed;
Error = _clearAllBundleFilesOpB.Error; Error = _clearCacheBundleFilesOpB.Error;
} }
} }
@ -106,14 +107,14 @@ namespace YooAsset
return; return;
} }
if (_clearAllBundleFilesOpC == null) if (_clearCacheBundleFilesOpC == null)
_clearAllBundleFilesOpC = _fileSystemC.ClearAllBundleFilesAsync(); _clearCacheBundleFilesOpC = _fileSystemC.ClearCacheBundleFilesAsync(_impl.ActiveManifest, _clearMode, _clearParam);
Progress = _clearAllBundleFilesOpC.Progress; Progress = _clearCacheBundleFilesOpC.Progress;
if (_clearAllBundleFilesOpC.IsDone == false) if (_clearCacheBundleFilesOpC.IsDone == false)
return; return;
if (_clearAllBundleFilesOpC.Status == EOperationStatus.Succeed) if (_clearCacheBundleFilesOpC.Status == EOperationStatus.Succeed)
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Succeed; Status = EOperationStatus.Succeed;
@ -122,7 +123,7 @@ namespace YooAsset
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
Status = EOperationStatus.Failed; Status = EOperationStatus.Failed;
Error = _clearAllBundleFilesOpC.Error; Error = _clearCacheBundleFilesOpC.Error;
} }
} }
} }

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 857423cdfd4f9184eab094be01c62480 guid: 37b4e645f7a679f4fa978c55329ee01a
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -1,131 +0,0 @@

namespace YooAsset
{
/// <summary>
/// 清理未使用的文件
/// </summary>
public abstract class ClearUnusedBundleFilesOperation : AsyncOperationBase
{
}
internal sealed class ClearUnusedBundleFilesImplOperation : ClearUnusedBundleFilesOperation
{
private enum ESteps
{
None,
ClearFileSystemA,
ClearFileSystemB,
ClearFileSystemC,
Done,
}
private readonly IPlayMode _impl;
private readonly IFileSystem _fileSystemA;
private readonly IFileSystem _fileSystemB;
private readonly IFileSystem _fileSystemC;
private FSClearUnusedBundleFilesOperation _clearUnusedBundleFilesOpA;
private FSClearUnusedBundleFilesOperation _clearUnusedBundleFilesOpB;
private FSClearUnusedBundleFilesOperation _clearUnusedBundleFilesOpC;
private ESteps _steps = ESteps.None;
internal ClearUnusedBundleFilesImplOperation(IPlayMode impl, IFileSystem fileSystemA, IFileSystem fileSystemB, IFileSystem fileSystemC)
{
_impl = impl;
_fileSystemA = fileSystemA;
_fileSystemB = fileSystemB;
_fileSystemC = fileSystemC;
}
internal override void InternalOnStart()
{
_steps = ESteps.ClearFileSystemA;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.ClearFileSystemA)
{
if (_fileSystemA == null)
{
_steps = ESteps.ClearFileSystemB;
return;
}
if (_clearUnusedBundleFilesOpA == null)
_clearUnusedBundleFilesOpA = _fileSystemA.ClearUnusedBundleFilesAsync(_impl.ActiveManifest);
Progress = _clearUnusedBundleFilesOpA.Progress;
if (_clearUnusedBundleFilesOpA.IsDone == false)
return;
if (_clearUnusedBundleFilesOpA.Status == EOperationStatus.Succeed)
{
_steps = ESteps.ClearFileSystemB;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _clearUnusedBundleFilesOpA.Error;
}
}
if (_steps == ESteps.ClearFileSystemB)
{
if (_fileSystemB == null)
{
_steps = ESteps.ClearFileSystemC;
return;
}
if (_clearUnusedBundleFilesOpB == null)
_clearUnusedBundleFilesOpB = _fileSystemB.ClearUnusedBundleFilesAsync(_impl.ActiveManifest);
Progress = _clearUnusedBundleFilesOpB.Progress;
if (_clearUnusedBundleFilesOpB.IsDone == false)
return;
if (_clearUnusedBundleFilesOpB.Status == EOperationStatus.Succeed)
{
_steps = ESteps.ClearFileSystemC;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _clearUnusedBundleFilesOpB.Error;
}
}
if (_steps == ESteps.ClearFileSystemC)
{
if (_fileSystemC == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
return;
}
if (_clearUnusedBundleFilesOpC == null)
_clearUnusedBundleFilesOpC = _fileSystemC.ClearUnusedBundleFilesAsync(_impl.ActiveManifest);
Progress = _clearUnusedBundleFilesOpC.Progress;
if (_clearUnusedBundleFilesOpC.IsDone == false)
return;
if (_clearUnusedBundleFilesOpC.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _clearUnusedBundleFilesOpC.Error;
}
}
}
}
}

View File

@ -52,16 +52,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }
ClearCacheBundleFilesOperation IPlayMode.ClearCacheBundleFilesAsync(string clearMode, object clearParam)
ClearAllBundleFilesOperation IPlayMode.ClearAllBundleFilesAsync()
{ {
var operation = new ClearAllBundleFilesImplOperation(this, EditorFileSystem, null, null); var operation = new ClearCacheBundleFilesImplOperation(this, EditorFileSystem, null, null, clearMode, clearParam);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
ClearUnusedBundleFilesOperation IPlayMode.ClearUnusedBundleFilesAsync()
{
var operation = new ClearUnusedBundleFilesImplOperation(this, EditorFileSystem, null, null);
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }

View File

@ -56,16 +56,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }
ClearCacheBundleFilesOperation IPlayMode.ClearCacheBundleFilesAsync(string clearMode, object clearParam)
ClearAllBundleFilesOperation IPlayMode.ClearAllBundleFilesAsync()
{ {
var operation = new ClearAllBundleFilesImplOperation(this, BuildinFileSystem, CacheFileSystem, null); var operation = new ClearCacheBundleFilesImplOperation(this, BuildinFileSystem, CacheFileSystem, null, clearMode, clearParam);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
ClearUnusedBundleFilesOperation IPlayMode.ClearUnusedBundleFilesAsync()
{
var operation = new ClearUnusedBundleFilesImplOperation(this, BuildinFileSystem, CacheFileSystem, null);
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }

View File

@ -52,16 +52,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }
ClearCacheBundleFilesOperation IPlayMode.ClearCacheBundleFilesAsync(string clearMode, object clearParam)
ClearAllBundleFilesOperation IPlayMode.ClearAllBundleFilesAsync()
{ {
var operation = new ClearAllBundleFilesImplOperation(this, BuildinFileSystem, null, null); var operation = new ClearCacheBundleFilesImplOperation(this, BuildinFileSystem, null, null, clearMode, clearParam);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
ClearUnusedBundleFilesOperation IPlayMode.ClearUnusedBundleFilesAsync()
{
var operation = new ClearUnusedBundleFilesImplOperation(this, BuildinFileSystem, null, null);
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }

View File

@ -74,16 +74,9 @@ namespace YooAsset
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }
ClearCacheBundleFilesOperation IPlayMode.ClearCacheBundleFilesAsync(string clearMode, object clearParam)
ClearAllBundleFilesOperation IPlayMode.ClearAllBundleFilesAsync()
{ {
var operation = new ClearAllBundleFilesImplOperation(this, WebServerFileSystem, WebRemoteFileSystem, null); var operation = new ClearCacheBundleFilesImplOperation(this, WebServerFileSystem, WebRemoteFileSystem, null, clearMode, clearParam);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
ClearUnusedBundleFilesOperation IPlayMode.ClearUnusedBundleFilesAsync()
{
var operation = new ClearUnusedBundleFilesImplOperation(this, WebServerFileSystem, WebRemoteFileSystem, null);
OperationSystem.StartOperation(PackageName, operation); OperationSystem.StartOperation(PackageName, operation);
return operation; return operation;
} }

View File

@ -236,21 +236,25 @@ namespace YooAsset
} }
/// <summary> /// <summary>
/// 清理文件系统所有的资源文件 /// 清理缓存文件
/// </summary> /// </summary>
public ClearAllBundleFilesOperation ClearAllBundleFilesAsync() /// <param name="clearMode">清理方式</param>
/// <param name="clearParam">执行参数</param>
public ClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(EFileClearMode clearMode, object clearParam = null)
{ {
DebugCheckInitialize(); DebugCheckInitialize();
return _playModeImpl.ClearAllBundleFilesAsync(); return _playModeImpl.ClearCacheBundleFilesAsync(clearMode.ToString(), clearParam);
} }
/// <summary> /// <summary>
/// 清理文件系统未使用的资源文件 /// 清理缓存文件
/// </summary> /// </summary>
public ClearUnusedBundleFilesOperation ClearUnusedBundleFilesAsync() /// <param name="clearMode">清理方式</param>
/// <param name="clearParam">执行参数</param>
public ClearCacheBundleFilesOperation ClearCacheBundleFilesAsync(string clearMode, object clearParam = null)
{ {
DebugCheckInitialize(); DebugCheckInitialize();
return _playModeImpl.ClearUnusedBundleFilesAsync(); return _playModeImpl.ClearCacheBundleFilesAsync(clearMode, clearParam);
} }
/// <summary> /// <summary>

View File

@ -20,7 +20,7 @@ internal class FsmClearPackageCache : IStateNode
PatchEventDefine.PatchStatesChange.SendEventMessage("清理未使用的缓存文件!"); PatchEventDefine.PatchStatesChange.SendEventMessage("清理未使用的缓存文件!");
var packageName = (string)_machine.GetBlackboardValue("PackageName"); var packageName = (string)_machine.GetBlackboardValue("PackageName");
var package = YooAssets.GetPackage(packageName); var package = YooAssets.GetPackage(packageName);
var operation = package.ClearUnusedBundleFilesAsync(); var operation = package.ClearCacheBundleFilesAsync(EFileClearMode.ClearUnusedBundleFiles);
operation.Completed += Operation_Completed; operation.Completed += Operation_Completed;
} }
void IStateNode.OnUpdate() void IStateNode.OnUpdate()

View File

@ -31,7 +31,7 @@
}, },
"relatedPackages": {}, "relatedPackages": {},
"dependencies": { "dependencies": {
"com.unity.scriptablebuildpipeline": "2.1.3", "com.unity.scriptablebuildpipeline": "1.21.25",
"com.unity.modules.assetbundle": "1.0.0", "com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0", "com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0" "com.unity.modules.unitywebrequestassetbundle": "1.0.0"