Compare commits

...

41 Commits

Author SHA1 Message Date
何冠峰
06a50a049e add mini game sample 2025-06-13 18:31:05 +08:00
何冠峰
6f049e2427 add mini game sample
小游戏扩展库独立
2025-06-13 18:19:35 +08:00
何冠峰
01c08a46ab fix #564 2025-06-13 17:39:30 +08:00
何冠峰
31dc5b494d fix #569 2025-06-13 17:25:13 +08:00
何冠峰
18e74e906e fix #551 2025-06-13 17:18:38 +08:00
何冠峰
4f62b249b4 update TableView
增加AssetObjectCell类
2025-05-19 16:25:16 +08:00
何冠峰
fe7f9bff08 fix #552 2025-05-15 15:38:13 +08:00
何冠峰
e71077f294 fix space shooter quit game error
修复太空战机DEMO在退出运行模式时的报错。
2025-05-13 17:53:17 +08:00
何冠峰
eabebf3d8f Update CHANGELOG.md 2025-05-13 10:47:59 +08:00
何冠峰
4ef789520a Update package.json 2025-05-13 10:47:49 +08:00
何冠峰
4322f3c58c fix #545 2025-05-13 10:23:22 +08:00
何冠峰
c40a796170 fix #542 2025-05-13 10:11:06 +08:00
何冠峰
32841d4773 Update AssetBundleDebuggerWindow.cs 2025-05-09 15:29:26 +08:00
何冠峰
e469b32d94 refactor: The tag diffusion logic in the collector
优化收集器tag传染扩散逻辑,避免Group里配置了Tag导致的无意义的警告信息。
2025-04-23 18:42:26 +08:00
何冠峰
c0e5315953 feat : Buld the pipeline output the log file.
构建管线输出构建日志到输出目录下。
2025-04-23 18:19:13 +08:00
何冠峰
7b5f366533 Build system add BuiltinShadersBundleNameIsNull ErrorCode 2025-04-23 16:56:03 +08:00
何冠峰
e674d5bf97 update extension sample
PanelMonitor增加控制开关
2025-04-23 16:39:07 +08:00
何冠峰
9b0bebd981 refactor : Macro scripts control by YOO_ASSET_EXPERIMENT 2025-04-23 16:38:17 +08:00
何冠峰
dc46462bfa fix : remove Caching class
it's not support in webGL
2025-04-23 14:14:34 +08:00
何冠峰
51c9943cf2 修复了输出csproject工程文件编码为UTF16的问题
修正BOM问题
2025-04-22 17:41:36 +08:00
何冠峰
3db9b750e3 update logo 2025-04-22 16:47:44 +08:00
何冠峰
1b57a0b7df 修复了输出csproject工程文件编码为UTF16的问题。 2025-04-22 16:47:33 +08:00
何冠峰
bd5ce1e6bd perf : webgl platform use crc verify the bundle when first time downloaded
WebGL平台首次下载会验证CRC。
2025-04-18 18:21:24 +08:00
何冠峰
7eb74d4dd1 update extension sample 2025-04-18 17:11:40 +08:00
何冠峰
a384ca1f18 feat : scriptable build pipeline add StripUnityVersion parameter.
新增构建参数
2025-04-18 16:48:03 +08:00
何冠峰
c7253a3f23 Update CHANGELOG.md 2025-04-17 19:02:59 +08:00
何冠峰
b296abb27e Update package.json 2025-04-17 19:02:57 +08:00
何冠峰
999ede6bab fix #534 2025-04-17 18:51:08 +08:00
何冠峰
bd1569c34d fix #533 2025-04-17 18:47:59 +08:00
何冠峰
3c265c1ab4 update extension sample 2025-04-17 15:38:07 +08:00
何冠峰
570a3a817c update space shooter 2025-04-17 15:16:05 +08:00
何冠峰
7a8f344927 update extension sample 2025-04-17 15:15:48 +08:00
何冠峰
b2c9cb3a7e update space shooter 2025-04-17 14:16:56 +08:00
何冠峰
06a5c90b23 update space shooter 2025-04-17 12:00:45 +08:00
何冠峰
dcd8ced42a update space shooter 2025-04-17 11:10:08 +08:00
何冠峰
76b31bd3cf update extension sample 2025-04-17 11:09:37 +08:00
何冠峰
009e8ece79 fix #528 #531 2025-04-15 14:20:32 +08:00
何冠峰
4e257ab27d fix #531 2025-04-09 11:39:42 +08:00
何冠峰
927400b669 refactor : EFileNameStyle move to runtime code 2025-04-08 14:28:52 +08:00
何冠峰
c0d42e79d8 refactor : DownloadParam rename DownloadFileOptions 2025-04-08 11:48:32 +08:00
何冠峰
b843c6b0ed refactor : add ClearCacheFilesOptions define 2025-04-08 11:34:46 +08:00
143 changed files with 1564 additions and 251 deletions

View File

@@ -2,6 +2,59 @@
All notable changes to this package will be documented in this file.
## [2.3.9] - 2025-05-13
### Improvements
- 增加了YOO_ASSET_EXPERIMENT宏用于控制实验性代码的开关。
- 构建管线目前会输出构建日志到输出目录下,方便查看引擎在构建时主动清空的控制台日志。
- 优化了收集器tag传染扩散逻辑避免Group里配置了Tag导致的无意义的警告信息。
- 扩展工程内PanelMonitor代码默认关闭状态。
### Fixed
- (#528) 修复了AssetDependencyDatabase在查询引擎资源对象是否存在的时效问题。
### Added
- (#542) 新增了资源管理系统销毁方法。
该方法会销毁所有的资源包裹和异步操作任务以及卸载所有AssetBundle对象
```csharp
public class YooAssets
{
/// <summary>
/// 销毁资源系统
/// </summary>
public static void Destroy();
}
```
- 新增了SBP构建管线的构建参数
```csharp
/// <summary>
/// 从AssetBundle文件头里剥离Unity版本信息
/// </summary>
public bool StripUnityVersion = false;
```
- 新增了构建错误码BuiltinShadersBundleNameIsNull
## [2.3.8] - 2025-04-17
### Improvements
- 扩展工程里增加了“图集丢失变白块的解决方案”的相关代码。
### Fixed
- (#528) 修复了微信小游戏平台WXFSClearUnusedBundleFiles无法清理的问题。
- (#531) 修复了微信小游戏平台WXFSClearUnusedBundleFiles没有适配BundleName_HashName命名方式。
- (#533) 修复了Editor程序集下无法访问YooAsset.Editor程序集里的internal字段的问题。
- (#534) 修复了资源报告窗口AssetView视图里依赖资源包列表显示不准确的问题。
## [2.3.7] - 2025-04-01
### Improvements

View File

@@ -0,0 +1,5 @@
using System.Runtime.CompilerServices;
// 外部友元
[assembly: InternalsVisibleTo("YooAsset.EditorExtension")]
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor")]

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 56ea224b45d314e4a86b558404e9b6c8
guid: ef774f01e50ab0a4d88122041938a6b9
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
#if YOO_ASSET_EXPERIMENT
namespace YooAsset.Editor
{
public class MacroDefine
@@ -15,3 +16,4 @@ namespace YooAsset.Editor
};
}
}
#endif

View File

@@ -5,6 +5,7 @@ using System.Text;
using System.Xml;
using UnityEditor;
#if YOO_ASSET_EXPERIMENT
namespace YooAsset.Editor
{
[InitializeOnLoad]
@@ -22,13 +23,21 @@ namespace YooAsset.Editor
return content;
// 将修改后的XML结构重新输出为文本
var stringWriter = new StringWriter();
var writerSettings = new XmlWriterSettings();
writerSettings.Indent = true;
var xmlWriter = XmlWriter.Create(stringWriter, writerSettings);
xmlDoc.WriteTo(xmlWriter);
xmlWriter.Flush();
return stringWriter.ToString();
using (var memoryStream = new MemoryStream())
{
var writerSettings = new XmlWriterSettings
{
Indent = true,
Encoding = new UTF8Encoding(false), //无BOM
OmitXmlDeclaration = false
};
using (var xmlWriter = XmlWriter.Create(memoryStream, writerSettings))
{
xmlDoc.Save(xmlWriter);
}
return Encoding.UTF8.GetString(memoryStream.ToArray());
}
}
/// <summary>
@@ -94,3 +103,4 @@ namespace YooAsset.Editor
}
}
}
#endif

View File

@@ -196,6 +196,32 @@ namespace YooAsset.Editor
}
}
/// <summary>
/// 导入单个报告对象
/// </summary>
public void ImportSingleReprotFile(ScanReport report)
{
_reportCombiner = new ScanReportCombiner();
try
{
_reportCombiner.Combine(report);
// 刷新页面
RefreshToolbar();
FillTableView();
RebuildView();
}
catch (System.Exception e)
{
_reportCombiner = null;
_titleLabel.text = "导入报告失败!";
_descLabel.text = e.Message;
UnityEngine.Debug.LogError(e.StackTrace);
}
}
private void ImportSingleBtn_clicked()
{
string selectFilePath = EditorUtility.OpenFilePanel("导入报告", _lastestOpenFolder, "json");
@@ -446,15 +472,31 @@ namespace YooAsset.Editor
var column = new TableColumn(header.HeaderTitle, header.HeaderTitle, columnStyle);
column.MakeCell = () =>
{
var label = new Label();
label.style.marginLeft = 3f;
label.style.unityTextAlign = TextAnchor.MiddleLeft;
return label;
if (header.HeaderType == EHeaderType.AssetObject)
{
var objectFiled = new ObjectField();
return objectFiled;
}
else
{
var label = new Label();
label.style.marginLeft = 3f;
label.style.unityTextAlign = TextAnchor.MiddleLeft;
return label;
}
};
column.BindCell = (VisualElement element, ITableData data, ITableCell cell) =>
{
var infoLabel = element as Label;
infoLabel.text = (string)cell.GetDisplayObject();
if (header.HeaderType == EHeaderType.AssetObject)
{
var objectFiled = element as ObjectField;
objectFiled.value = (UnityEngine.Object)cell.GetDisplayObject();
}
else
{
var infoLabel = element as Label;
infoLabel.text = (string)cell.GetDisplayObject();
}
};
_elementTableView.AddColumn(column);
}
@@ -480,6 +522,10 @@ namespace YooAsset.Editor
{
tableData.AddAssetPathCell(scanInfo.HeaderTitle, scanInfo.ScanInfo);
}
else if (header.HeaderType == EHeaderType.AssetObject)
{
tableData.AddAssetObjectCell(scanInfo.HeaderTitle, scanInfo.ScanInfo);
}
else if (header.HeaderType == EHeaderType.StringValue)
{
tableData.AddStringValueCell(scanInfo.HeaderTitle, scanInfo.ScanInfo);

View File

@@ -8,6 +8,11 @@ namespace YooAsset.Editor
/// </summary>
AssetPath,
/// <summary>
/// 资源对象
/// </summary>
AssetObject,
/// <summary>
/// 字符串
/// </summary>

View File

@@ -126,6 +126,12 @@ namespace YooAsset.Editor
if (string.IsNullOrEmpty(guid))
throw new Exception($"{HeaderTitle} value is invalid asset path : {value}");
}
else if (HeaderType == EHeaderType.AssetObject)
{
string guid = AssetDatabase.AssetPathToGUID(value);
if (string.IsNullOrEmpty(guid))
throw new Exception($"{HeaderTitle} value is invalid asset object : {value}");
}
else if (HeaderType == EHeaderType.DoubleValue)
{
if (double.TryParse(value, out double doubleValue) == false)

View File

@@ -46,7 +46,7 @@ namespace YooAsset.Editor
}
catch (Exception e)
{
return new ScannerResult(e.Message);
return new ScannerResult(e.StackTrace);
}
}

View File

@@ -52,7 +52,7 @@ namespace YooAsset.Editor
if (Succeed)
{
var reproterWindow = AssetArtReporterWindow.OpenWindow();
reproterWindow.ImportSingleReprotFile(ReprotFilePath);
reproterWindow.ImportSingleReprotFile(Report);
}
}
}

View File

@@ -32,8 +32,9 @@ namespace YooAsset.Editor
var buildParametersContext = new BuildParametersContext(buildParameters);
_buildContext.SetContextObject(buildParametersContext);
// 初始化日志
BuildLogger.InitLogger(enableLog);
// 初始化日志系统
string logFilePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/buildInfo.log";
BuildLogger.InitLogger(enableLog, logFilePath);
// 执行构建流程
BuildLogger.Log($"Begin to build package : {buildParameters.PackageName} by {buildParameters.BuildPipeline}");
@@ -50,6 +51,9 @@ namespace YooAsset.Editor
BuildLogger.Error(buildResult.ErrorInfo);
}
// 关闭日志系统
BuildLogger.Shuntdown();
return buildResult;
}
}

View File

@@ -11,7 +11,7 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildParameters = buildParametersContext.Parameters;
var buildParameters = buildParametersContext.Parameters as ScriptableBuildParameters;
// 检测基础构建参数
buildParametersContext.CheckBuildParameters();
@@ -50,6 +50,13 @@ namespace YooAsset.Editor
{
BuildLogger.Log($"Create pipeline output directory: {pipelineOutputDirectory}");
}
// 检测内置着色器资源包名称
if (string.IsNullOrEmpty(buildParameters.BuiltinShadersBundleName))
{
string warning = BuildLogger.GetErrorMessage(ErrorCode.BuiltinShadersBundleNameIsNull, $"Builtin shaders bundle name is null. It will cause resource redundancy !");
BuildLogger.Warning(warning);
}
}
}
}

View File

@@ -14,6 +14,11 @@ namespace YooAsset.Editor
/// </summary>
public ECompressOption CompressOption = ECompressOption.Uncompressed;
/// <summary>
/// 从AssetBundle文件头里剥离Unity版本信息
/// </summary>
public bool StripUnityVersion = false;
/// <summary>
/// 禁止写入类型树结构(可以降低包体和内存并提高加载效率)
/// </summary>
@@ -70,6 +75,9 @@ namespace YooAsset.Editor
else
throw new System.NotImplementedException(CompressOption.ToString());
if (StripUnityVersion)
buildParams.ContentBuildFlags |= UnityEditor.Build.Content.ContentBuildFlags.StripUnityVersion;
if (DisableWriteTypeTree)
buildParams.ContentBuildFlags |= UnityEditor.Build.Content.ContentBuildFlags.DisableWriteTypeTree;

View File

@@ -2,37 +2,100 @@
using System.IO;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
namespace YooAsset.Editor
{
internal static class BuildLogger
{
private static bool _enableLog = true;
private const int MAX_LOG_BUFFER_SIZE = 1024 * 1024 * 2; //2MB
public static void InitLogger(bool enableLog)
private static bool _enableLog = true;
private static string _logFilePath;
private static readonly object _lockObj = new object();
private static readonly StringBuilder _logBuilder = new StringBuilder(MAX_LOG_BUFFER_SIZE);
/// <summary>
/// 初始化日志系统
/// </summary>
public static void InitLogger(bool enableLog, string logFilePath)
{
_enableLog = enableLog;
_logFilePath = logFilePath;
_logBuilder.Clear();
if (_enableLog)
{
if (string.IsNullOrEmpty(_logFilePath))
throw new Exception("Log file path is null or empty !");
Debug.Log($"Logger initialized at {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
}
}
/// <summary>
/// 关闭日志系统
/// </summary>
public static void Shuntdown()
{
if (_enableLog)
{
lock (_lockObj)
{
try
{
if (File.Exists(_logFilePath))
File.Delete(_logFilePath);
FileUtility.CreateFileDirectory(_logFilePath);
File.WriteAllText(_logFilePath, _logBuilder.ToString(), Encoding.UTF8);
_logBuilder.Clear();
}
catch (Exception ex)
{
Debug.LogError($"Failed to write log file: {ex.Message}");
}
}
}
}
public static void Log(string message)
{
if (_enableLog)
{
WriteLog("INFO", message);
Debug.Log(message);
}
}
public static void Warning(string message)
{
Debug.LogWarning(message);
if (_enableLog)
{
WriteLog("WARN", message);
Debug.LogWarning(message);
}
}
public static void Error(string message)
{
Debug.LogError(message);
if (_enableLog)
{
WriteLog("ERROR", message);
Debug.LogError(message);
}
}
public static string GetErrorMessage(ErrorCode code, string message)
{
return $"[ErrorCode{(int)code}] {message}";
}
private static void WriteLog(string level, string message)
{
lock (_lockObj)
{
string logEntry = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} [{level}] {message}";
_logBuilder.AppendLine(logEntry);
}
}
}
}

View File

@@ -15,6 +15,7 @@ namespace YooAsset.Editor
BuildPipelineIsNullOrEmpty = 116,
BuildBundleTypeIsUnknown = 117,
RecommendScriptBuildPipeline = 130,
BuiltinShadersBundleNameIsNull = 131,
// TaskGetBuildMap
RemoveInvalidTags = 200,

View File

@@ -259,10 +259,13 @@ namespace YooAsset.Editor
}
private List<string> GetAssetTags(AssetBundleCollectorGroup group)
{
List<string> tags = EditorTools.StringToStringList(group.AssetTags, ';');
List<string> temper = EditorTools.StringToStringList(AssetTags, ';');
tags.AddRange(temper);
return tags;
List<string> result = EditorTools.StringToStringList(AssetTags, ';');
if (CollectorType == ECollectorType.MainAssetCollector)
{
List<string> temps = EditorTools.StringToStringList(group.AssetTags, ';');
result.AddRange(temps);
}
return result;
}
private List<AssetInfo> GetAllDependencies(CollectCommand command, string mainAssetPath)
{

View File

@@ -70,7 +70,11 @@ namespace YooAsset.Editor
foreach (var cacheInfoPair in _database)
{
var assetPath = cacheInfoPair.Key;
#if UNITY_2021_3_OR_NEWER
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath, AssetPathToGUIDOptions.OnlyExistingAssets);
#else
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
#endif
if (string.IsNullOrEmpty(assetGUID))
{
removeList.Add(assetPath);

View File

@@ -296,6 +296,7 @@ namespace YooAsset.Editor
string filePath = $"{resultPath}/{nameof(DebugReport)}_{_currentReport.FrameCount}.json";
string fileContent = JsonUtility.ToJson(_currentReport, true);
FileUtility.WriteAllText(filePath, fileContent);
Debug.Log($"Debug report file saved : {filePath}");
}
}
private void OnSearchKeyWordChange(ChangeEvent<string> e)

View File

@@ -238,9 +238,8 @@ namespace YooAsset.Editor
ReportAssetInfo assetInfo = assetTableData.AssetInfo;
// 填充依赖数据
var mainBundle = _buildReport.GetBundleInfo(assetInfo.MainBundleName);
var sourceDatas = new List<ITableData>(mainBundle.DependBundles.Count);
foreach (string dependBundleName in mainBundle.DependBundles)
var sourceDatas = new List<ITableData>(assetInfo.DependBundles.Count);
foreach (string dependBundleName in assetInfo.DependBundles)
{
var dependBundle = _buildReport.GetBundleInfo(dependBundleName);
var rowData = new DependTableData();

View File

@@ -0,0 +1,42 @@
#if UNITY_2019_4_OR_NEWER
using UnityEditor;
using System;
namespace YooAsset.Editor
{
public class AssetObjectCell : ITableCell, IComparable
{
public string SearchTag { private set; get; }
public object CellValue { set; get; }
public string StringValue
{
get
{
return (string)CellValue;
}
}
public AssetObjectCell(string searchTag, string assetPath)
{
SearchTag = searchTag;
CellValue = assetPath;
}
public object GetDisplayObject()
{
return AssetDatabase.LoadMainAssetAtPath(StringValue);
}
public int CompareTo(object other)
{
if (other is AssetObjectCell cell)
{
return this.StringValue.CompareTo(cell.StringValue);
}
else
{
return 0;
}
}
}
}
#endif

View File

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

View File

@@ -31,9 +31,14 @@ namespace YooAsset.Editor
var cell = new ButtonCell(searchTag);
Cells.Add(cell);
}
public void AddAssetPathCell(string searchTag, string path)
public void AddAssetPathCell(string searchTag, string assetPath)
{
var cell = new AssetPathCell(searchTag, path);
var cell = new AssetPathCell(searchTag, assetPath);
Cells.Add(cell);
}
public void AddAssetObjectCell(string searchTag, string assetPath)
{
var cell = new AssetObjectCell(searchTag, assetPath);
Cells.Add(cell);
}
public void AddStringValueCell(string searchTag, string value)

View File

@@ -1,7 +1,11 @@
using System.Runtime.CompilerServices;
// 内部友元
[assembly: InternalsVisibleTo("YooAsset.Editor")]
[assembly: InternalsVisibleTo("YooAsset.EditorExtension")]
[assembly: InternalsVisibleTo("YooAsset.RuntimeExtension")]
[assembly: InternalsVisibleTo("YooAsset.Test.Editor")]
// 外部友元
[assembly: InternalsVisibleTo("YooAsset.MiniGame")]
[assembly: InternalsVisibleTo("YooAsset.RuntimeExtension")]
[assembly: InternalsVisibleTo("YooAsset.EditorExtension")]
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor")]

View File

@@ -1,30 +0,0 @@

namespace YooAsset
{
internal class DownloadParam
{
public readonly int FailedTryAgain;
public readonly int Timeout;
/// <summary>
/// 导入的本地文件路径
/// </summary>
public string ImportFilePath { set; get; }
/// <summary>
/// 主资源地址
/// </summary>
public string MainURL { set; get; }
/// <summary>
/// 备用资源地址
/// </summary>
public string FallbackURL { set; get; }
public DownloadParam(int failedTryAgain, int timeout)
{
FailedTryAgain = failedTryAgain;
Timeout = timeout;
}
}
}

View File

@@ -69,6 +69,8 @@ namespace YooAsset
url = new System.Uri(path).ToString();
#elif UNITY_STANDALONE || UNITY_WSA
url = StringUtility.Format("file:///{0}", path);
#elif UNITY_TVOS
url = StringUtility.Format("file:///{0}", path);
#else
throw new System.NotImplementedException();
#endif

View File

@@ -109,15 +109,15 @@ namespace YooAsset
var operation = new DBFSRequestPackageVersionOperation(this);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{
return _unpackFileSystem.ClearCacheFilesAsync(manifest, clearMode, clearParam);
return _unpackFileSystem.ClearCacheFilesAsync(manifest, options);
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
// 注意:业务层的解压下载器会依赖内置文件系统的下载方法
param.ImportFilePath = GetBuildinFileLoadPath(bundle);
return _unpackFileSystem.DownloadFileAsync(bundle, param);
options.ImportFilePath = GetBuildinFileLoadPath(bundle);
return _unpackFileSystem.DownloadFileAsync(bundle, options);
}
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)
{

View File

@@ -120,43 +120,43 @@ namespace YooAsset
var operation = new DCFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{
if (clearMode == EFileClearMode.ClearAllBundleFiles.ToString())
if (options.ClearMode == EFileClearMode.ClearAllBundleFiles.ToString())
{
var operation = new ClearAllCacheBundleFilesOperation(this);
return operation;
}
else if (clearMode == EFileClearMode.ClearUnusedBundleFiles.ToString())
else if (options.ClearMode == EFileClearMode.ClearUnusedBundleFiles.ToString())
{
var operation = new ClearUnusedCacheBundleFilesOperation(this, manifest);
return operation;
}
else if (clearMode == EFileClearMode.ClearBundleFilesByTags.ToString())
else if (options.ClearMode == EFileClearMode.ClearBundleFilesByTags.ToString())
{
var operation = new ClearCacheBundleFilesByTagsOperaiton(this, manifest, clearParam);
var operation = new ClearCacheBundleFilesByTagsOperaiton(this, manifest, options.ClearParam);
return operation;
}
else if (clearMode == EFileClearMode.ClearAllManifestFiles.ToString())
else if (options.ClearMode == EFileClearMode.ClearAllManifestFiles.ToString())
{
var operation = new ClearAllCacheManifestFilesOperation(this);
return operation;
}
else if (clearMode == EFileClearMode.ClearUnusedManifestFiles.ToString())
else if (options.ClearMode == EFileClearMode.ClearUnusedManifestFiles.ToString())
{
var operation = new ClearUnusedCacheManifestFilesOperation(this, manifest);
return operation;
}
else
{
string error = $"Invalid clear mode : {clearMode}";
string error = $"Invalid clear mode : {options.ClearMode}";
var operation = new FSClearCacheFilesCompleteOperation(error);
return operation;
}
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
var downloader = DownloadCenter.DownloadFileAsync(bundle, param);
var downloader = DownloadCenter.DownloadFileAsync(bundle, options);
downloader.Reference(); //增加下载器的引用计数
// 注意:将下载器进行包裹,可以避免父类任务终止的时候,连带子任务里的下载器也一起被终止!

View File

@@ -58,8 +58,8 @@ namespace YooAsset
// 注意边玩边下下载器引用计数没有Release
if (_downloadFileOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, downloadParam);
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, options);
_downloadFileOp.StartOperation();
AddChildOperation(_downloadFileOp);
}
@@ -297,8 +297,8 @@ namespace YooAsset
// 注意边玩边下下载器引用计数没有Release
if (_downloadFileOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, downloadParam);
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, options);
_downloadFileOp.StartOperation();
AddChildOperation(_downloadFileOp);
}

View File

@@ -74,7 +74,7 @@ namespace YooAsset
/// <summary>
/// 创建下载任务
/// </summary>
public FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
// 查询旧的下载器
if (_downloaders.TryGetValue(bundle.BundleGUID, out var oldDownloader))
@@ -83,29 +83,29 @@ namespace YooAsset
}
// 设置请求URL
if (string.IsNullOrEmpty(param.ImportFilePath))
if (string.IsNullOrEmpty(options.ImportFilePath))
{
param.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(bundle.FileName);
param.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(bundle.FileName);
options.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(bundle.FileName);
options.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(bundle.FileName);
}
else
{
// 注意:把本地文件路径指定为远端下载地址
param.MainURL = DownloadSystemHelper.ConvertToWWWPath(param.ImportFilePath);
param.FallbackURL = param.MainURL;
options.MainURL = DownloadSystemHelper.ConvertToWWWPath(options.ImportFilePath);
options.FallbackURL = options.MainURL;
}
// 创建新的下载器
DefaultDownloadFileOperation newDownloader;
if (bundle.FileSize >= _fileSystem.ResumeDownloadMinimumSize)
{
newDownloader = new DownloadResumeFileOperation(_fileSystem, bundle, param);
newDownloader = new DownloadResumeFileOperation(_fileSystem, bundle, options);
AddChildOperation(newDownloader);
_downloaders.Add(bundle.BundleGUID, newDownloader);
}
else
{
newDownloader = new DownloadNormalFileOperation(_fileSystem, bundle, param);
newDownloader = new DownloadNormalFileOperation(_fileSystem, bundle, options);
AddChildOperation(newDownloader);
_downloaders.Add(bundle.BundleGUID, newDownloader);
}

View File

@@ -12,13 +12,13 @@ namespace YooAsset
private string _tempFilePath;
private ESteps _steps = ESteps.None;
internal DownloadNormalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadNormalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
_fileSystem = fileSystem;
}
internal override void InternalStart()
{
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Param.MainURL);
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Options.MainURL);
_tempFilePath = _fileSystem.GetTempFilePath(Bundle);
_steps = ESteps.CheckExists;
}

View File

@@ -15,13 +15,13 @@ namespace YooAsset
private ESteps _steps = ESteps.None;
internal DownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
_fileSystem = fileSystem;
}
internal override void InternalStart()
{
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Param.MainURL);
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Options.MainURL);
_tempFilePath = _fileSystem.GetTempFilePath(Bundle);
_steps = ESteps.CheckExists;
}

View File

@@ -66,12 +66,12 @@ namespace YooAsset
var operation = new DEFSRequestPackageVersionOperation(this);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{
var operation = new FSClearCacheFilesCompleteOperation();
return operation;
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
throw new System.NotImplementedException();
}

View File

@@ -73,12 +73,12 @@ namespace YooAsset
var operation = new DWRFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{
var operation = new FSClearCacheFilesCompleteOperation();
return operation;
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
throw new System.NotImplementedException();
}

View File

@@ -34,19 +34,19 @@ namespace YooAsset
{
if (_downloadAssetBundleOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
downloadParam.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
downloadParam.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
options.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
options.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, downloadParam);
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, options);
_downloadAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, options);
_downloadAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp);
}

View File

@@ -82,12 +82,12 @@ namespace YooAsset
var operation = new DWSFSRequestPackageVersionOperation(this, timeout);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{
var operation = new FSClearCacheFilesCompleteOperation();
return operation;
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
throw new System.NotImplementedException();
}

View File

@@ -34,20 +34,20 @@ namespace YooAsset
{
if (_downloadAssetBundleOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle);
downloadParam.MainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath);
downloadParam.FallbackURL = downloadParam.MainURL;
options.MainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath);
options.FallbackURL = options.MainURL;
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, downloadParam);
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, options);
_downloadAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, options);
_downloadAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp);
}

View File

@@ -37,13 +37,13 @@ namespace YooAsset
/// <summary>
/// 清理缓存文件
/// </summary>
FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam);
FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options);
/// <summary>
/// 下载Bundle文件
/// </summary>
FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param);
FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options);
/// <summary>
/// 加载Bundle文件
/// </summary>

View File

@@ -1,6 +1,19 @@

namespace YooAsset
{
internal class ClearCacheFilesOptions
{
/// <summary>
/// 清理模式
/// </summary>
public string ClearMode;
/// <summary>
/// 附加参数
/// </summary>
public object ClearParam;
}
internal abstract class FSClearCacheFilesOperation : AsyncOperationBase
{
}

View File

@@ -1,6 +1,40 @@

namespace YooAsset
{
internal class DownloadFileOptions
{
/// <summary>
/// 失败后重试次数
/// </summary>
public readonly int FailedTryAgain;
/// <summary>
/// 超时时间
/// </summary>
public readonly int Timeout;
/// <summary>
/// 主资源地址
/// </summary>
public string MainURL { set; get; }
/// <summary>
/// 备用资源地址
/// </summary>
public string FallbackURL { set; get; }
/// <summary>
/// 导入的本地文件路径
/// </summary>
public string ImportFilePath { set; get; }
public DownloadFileOptions(int failedTryAgain, int timeout)
{
FailedTryAgain = failedTryAgain;
Timeout = timeout;
}
}
internal abstract class FSDownloadFileOperation : AsyncOperationBase
{
public PackageBundle Bundle { private set; get; }

View File

@@ -18,7 +18,7 @@ namespace YooAsset
}
// 下载参数
protected readonly DownloadParam Param;
protected readonly DownloadFileOptions Options;
// 请求相关
protected UnityWebRequest _webRequest;
@@ -35,10 +35,10 @@ namespace YooAsset
protected int FailedTryAgain;
internal DefaultDownloadFileOperation(PackageBundle bundle, DownloadParam param) : base(bundle)
internal DefaultDownloadFileOperation(PackageBundle bundle, DownloadFileOptions options) : base(bundle)
{
Param = param;
FailedTryAgain = param.FailedTryAgain;
Options = options;
FailedTryAgain = options.FailedTryAgain;
}
/// <summary>
@@ -49,9 +49,9 @@ namespace YooAsset
// 轮流返回请求地址
_requestCount++;
if (_requestCount % 2 == 0)
return Param.FallbackURL;
return Options.FallbackURL;
else
return Param.MainURL;
return Options.MainURL;
}
/// <summary>
@@ -87,7 +87,7 @@ namespace YooAsset
}
float offset = UnityEngine.Time.realtimeSinceStartup - _latestDownloadRealtime;
if (offset > Param.Timeout)
if (offset > Options.Timeout)
{
YooLogger.Warning($"Download request timeout : {_requestURL}");
if (_webRequest != null)

View File

@@ -4,7 +4,7 @@ namespace YooAsset
{
internal abstract class DownloadAssetBundleOperation : DefaultDownloadFileOperation
{
internal DownloadAssetBundleOperation(PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
}

View File

@@ -10,7 +10,7 @@ namespace YooAsset
private DownloadHandlerBuffer _downloadhandler;
private ESteps _steps = ESteps.None;
internal DownloadWebEncryptAssetBundleOperation(bool checkTimeout, IWebDecryptionServices decryptionServices, PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadWebEncryptAssetBundleOperation(bool checkTimeout, IWebDecryptionServices decryptionServices, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
_checkTimeout = checkTimeout;
_decryptionServices = decryptionServices;

View File

@@ -9,7 +9,7 @@ namespace YooAsset
private DownloadHandlerAssetBundle _downloadhandler;
private ESteps _steps = ESteps.None;
internal DownloadWebNormalAssetBundleOperation(bool disableUnityWebCache, PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadWebNormalAssetBundleOperation(bool disableUnityWebCache, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
_disableUnityWebCache = disableUnityWebCache;
}
@@ -122,7 +122,7 @@ namespace YooAsset
{
if (_disableUnityWebCache)
{
var downloadhandler = new DownloadHandlerAssetBundle(_requestURL, 0);
var downloadhandler = new DownloadHandlerAssetBundle(_requestURL, Bundle.UnityCRC);
#if UNITY_2020_3_OR_NEWER
downloadhandler.autoLoadAssetBundle = false;
#endif
@@ -132,9 +132,8 @@ namespace YooAsset
{
// 注意:优先从浏览器缓存里获取文件
// The file hash defining the version of the asset bundle.
uint unityCRC = Bundle.UnityCRC;
Hash128 fileHash = Hash128.Parse(Bundle.FileHash);
var downloadhandler = new DownloadHandlerAssetBundle(_requestURL, fileHash, unityCRC);
var downloadhandler = new DownloadHandlerAssetBundle(_requestURL, fileHash, Bundle.UnityCRC);
#if UNITY_2020_3_OR_NEWER
downloadhandler.autoLoadAssetBundle = false;
#endif

View File

@@ -38,9 +38,9 @@ namespace YooAsset
/// </summary>
public FSDownloadFileOperation CreateDownloader(int failedTryAgain, int timeout)
{
DownloadParam downloadParam = new DownloadParam(failedTryAgain, timeout);
downloadParam.ImportFilePath = _importFilePath;
return _fileSystem.DownloadFileAsync(Bundle, downloadParam);
DownloadFileOptions options = new DownloadFileOptions(failedTryAgain, timeout);
options.ImportFilePath = _importFilePath;
return _fileSystem.DownloadFileAsync(Bundle, options);
}
/// <summary>

View File

@@ -1,9 +1,6 @@

namespace YooAsset.Editor
namespace YooAsset
{
/// <summary>
/// 补丁包内的文件样式
/// </summary>
public enum EFileNameStyle
{
/// <summary>

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 84c5eff5dedf53343897e83f6b10eea6
guid: 5e81f00e510f07947873055518f5d1c6
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -31,8 +31,8 @@ namespace YooAsset
/// <summary>
/// 清理缓存文件
/// </summary>
ClearCacheFilesOperation ClearCacheFilesAsync(string clearMode, object clearParam);
ClearCacheFilesOperation ClearCacheFilesAsync(ClearCacheFilesOptions options);
// 下载相关
ResourceDownloaderOperation CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout);
ResourceDownloaderOperation CreateResourceDownloaderByTags(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout);

View File

@@ -314,27 +314,6 @@ namespace YooAsset
}
#endregion
/// <summary>
/// 注意:该类拷贝自编辑器
/// </summary>
private enum EFileNameStyle
{
/// <summary>
/// 哈希值名称
/// </summary>
HashName = 0,
/// <summary>
/// 资源包名称(不推荐)
/// </summary>
BundleName = 1,
/// <summary>
/// 资源包名称 + 哈希值名称
/// </summary>
BundleName_HashName = 2,
}
/// <summary>
/// 获取资源文件的后缀名
/// </summary>

View File

@@ -15,17 +15,15 @@ namespace YooAsset
}
private readonly PlayModeImpl _impl;
private readonly string _clearMode;
private readonly object _clearParam;
private readonly ClearCacheFilesOptions _options;
private List<IFileSystem> _cloneList;
private FSClearCacheFilesOperation _clearCacheFilesOp;
private ESteps _steps = ESteps.None;
internal ClearCacheFilesOperation(PlayModeImpl impl, string clearMode, object clearParam)
internal ClearCacheFilesOperation(PlayModeImpl impl, ClearCacheFilesOptions options)
{
_impl = impl;
_clearMode = clearMode;
_clearParam = clearParam;
_options = options;
}
internal override void InternalStart()
{
@@ -74,7 +72,7 @@ namespace YooAsset
var fileSystem = _cloneList[0];
_cloneList.RemoveAt(0);
_clearCacheFilesOp = fileSystem.ClearCacheFilesAsync(_impl.ActiveManifest, _clearMode, _clearParam);
_clearCacheFilesOp = fileSystem.ClearCacheFilesAsync(_impl.ActiveManifest, _options);
_clearCacheFilesOp.StartOperation();
AddChildOperation(_clearCacheFilesOp);
_steps = ESteps.CheckClearResult;
@@ -102,7 +100,7 @@ namespace YooAsset
}
internal override string InternalGetDesc()
{
return $"ClearMode : {_clearMode}";
return $"ClearMode : {_options.ClearMode}";
}
}
}

View File

@@ -97,9 +97,9 @@ namespace YooAsset
/// <summary>
/// 清理缓存文件
/// </summary>
ClearCacheFilesOperation IPlayMode.ClearCacheFilesAsync(string clearMode, object clearParam)
ClearCacheFilesOperation IPlayMode.ClearCacheFilesAsync(ClearCacheFilesOptions options)
{
var operation = new ClearCacheFilesOperation(this, clearMode, clearParam);
var operation = new ClearCacheFilesOperation(this, options);
return operation;
}

View File

@@ -268,7 +268,10 @@ namespace YooAsset
public ClearCacheFilesOperation ClearCacheFilesAsync(EFileClearMode clearMode, object clearParam = null)
{
DebugCheckInitialize(false);
var operation = _playModeImpl.ClearCacheFilesAsync(clearMode.ToString(), clearParam);
ClearCacheFilesOptions options = new ClearCacheFilesOptions();
options.ClearMode = clearMode.ToString();
options.ClearParam = clearParam;
var operation = _playModeImpl.ClearCacheFilesAsync(options);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}
@@ -281,7 +284,10 @@ namespace YooAsset
public ClearCacheFilesOperation ClearCacheFilesAsync(string clearMode, object clearParam = null)
{
DebugCheckInitialize(false);
var operation = _playModeImpl.ClearCacheFilesAsync(clearMode, clearParam);
ClearCacheFilesOptions options = new ClearCacheFilesOptions();
options.ClearMode = clearMode;
options.ClearParam = clearParam;
var operation = _playModeImpl.ClearCacheFilesAsync(options);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}

View File

@@ -34,6 +34,20 @@ namespace YooAsset
return str.Remove(index); //"assets/config/test.unity3d" --> "assets/config/test"
}
/// <summary>
/// URL地址是否包含双斜杠
/// 注意:只检查协议之后的部分
/// </summary>
public static bool HasDoubleSlashes(string url)
{
if (url == null)
throw new ArgumentNullException();
int protocolIndex = url.IndexOf("://");
string partToCheck = protocolIndex == -1 ? url : url.Substring(protocolIndex + 3);
return partToCheck.Contains("//") || partToCheck.Contains(@"\\");
}
/// <summary>
/// 合并路径
/// </summary>

View File

@@ -63,6 +63,29 @@ namespace YooAsset
}
}
/// <summary>
/// 销毁资源系统
/// </summary>
public static void Destroy()
{
if (_isInitialize)
{
_isInitialize = false;
if (_driver != null)
GameObject.Destroy(_driver);
// 终止并清空所有包裹的异步操作
ClearAllPackageOperation();
// 卸载所有AssetBundle
AssetBundle.UnloadAllAssetBundles(true);
// 清空资源包裹列表
_packages.Clear();
}
}
/// <summary>
/// 更新资源系统
/// </summary>
@@ -75,11 +98,10 @@ namespace YooAsset
}
/// <summary>
/// 应用程序退出处理
/// 终止并清空所有包裹的异步操作
/// </summary>
internal static void OnApplicationQuit()
internal static void ClearAllPackageOperation()
{
// 说明在编辑器下确保播放被停止时IO类操作被终止。
foreach (var package in _packages)
{
OperationSystem.ClearPackageOperation(package.PackageName);

View File

@@ -24,7 +24,8 @@ namespace YooAsset
#if UNITY_EDITOR
void OnApplicationQuit()
{
YooAssets.OnApplicationQuit();
// 说明在编辑器下确保播放被停止时IO类操作被终止。
YooAssets.ClearAllPackageOperation();
}
#endif

View File

@@ -51,10 +51,6 @@ namespace YooAsset.Editor
string manifestFileName = Path.GetFileNameWithoutExtension(manifestFilePath);
string outputDirectory = Path.GetDirectoryName(manifestFilePath);
// 加载补丁清单
byte[] bytesData = FileUtility.ReadAllBytes(manifestFilePath);
PackageManifest manifest = ManifestTools.DeserializeFromBinary(bytesData);
// 拷贝核心文件
{
string sourcePath = $"{outputDirectory}/{manifestFileName}.bytes";
@@ -67,12 +63,16 @@ namespace YooAsset.Editor
EditorTools.CopyFile(sourcePath, destPath, true);
}
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(manifest.PackageName);
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_packageName);
string sourcePath = $"{outputDirectory}/{fileName}";
string destPath = $"{AssetBundleBuilderHelper.GetStreamingAssetsRoot()}/{_packageName}/{fileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 加载补丁清单
byte[] bytesData = FileUtility.ReadAllBytes(manifestFilePath);
PackageManifest manifest = ManifestTools.DeserializeFromBinary(bytesData);
// 拷贝文件列表
int fileCount = 0;
foreach (var packageBundle in manifest.BundleList)

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 5280dfac6a481ee429c769ba5688c9d2
guid: 67ce0f6fc08b0724d95a9f86697bbde3
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,12 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;
public class PanelManifest : MonoBehaviour
{
/// <summary>
/// 面板自动引用的图集
/// </summary>
public List<SpriteAtlas> ReferencesAtlas = new List<SpriteAtlas>();
}

View File

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

View File

@@ -0,0 +1,141 @@
#if UNITY_EDITOR && UNITY_2021_3_OR_NEWER
using System.IO;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.U2D;
public static class UIPanelSettings
{
/// <summary>
/// 是否开启面板监测
/// </summary>
public static bool EnablePanelMonitor = false;
/// <summary>
/// 面板文件夹GUID
/// </summary>
private const string UIPanelDirectoryGUID = "12d33f33f3a55224c9c747d7bffa1c68";
/// <summary>
/// 精灵文件夹GUID
/// </summary>
private const string UISpriteDirectoryGUID = "935d7f20c085cc141a3daf9cacfabfae";
/// <summary>
/// 图集文件夹GUID
/// </summary>
private const string UIAtlasDirectoryGUID = "c355c783476322b4cacac98c5e1b46d8";
public static string GetPanelDirecotry()
{
string result = UnityEditor.AssetDatabase.GUIDToAssetPath(UIPanelDirectoryGUID);
if (string.IsNullOrEmpty(result))
{
throw new System.Exception($"Can not found panel direcotry : {UIPanelDirectoryGUID}");
}
return result;
}
public static string GetSpriteDirecotry()
{
string result = UnityEditor.AssetDatabase.GUIDToAssetPath(UISpriteDirectoryGUID);
if (string.IsNullOrEmpty(result))
{
throw new System.Exception($"Can not found sprite direcotry : {UISpriteDirectoryGUID}");
}
return result;
}
public static string GetAtlasDirecotry()
{
string result = UnityEditor.AssetDatabase.GUIDToAssetPath(UIAtlasDirectoryGUID);
if (string.IsNullOrEmpty(result))
{
throw new System.Exception($"Can not found atlas direcotry : {UIAtlasDirectoryGUID}");
}
return result;
}
}
public class UIPanelMonitor : UnityEditor.Editor
{
[UnityEditor.InitializeOnLoadMethod]
static void StartInitializeOnLoadMethod()
{
UnityEditor.SceneManagement.PrefabStage.prefabSaving += OnPrefabSaving;
}
static void OnPrefabSaving(GameObject go)
{
if (UIPanelSettings.EnablePanelMonitor == false)
return;
UnityEditor.SceneManagement.PrefabStage stage = UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
if (stage != null)
{
string panelDirectory = UIPanelSettings.GetPanelDirecotry();
if (stage.assetPath.StartsWith(panelDirectory))
{
PanelManifest manifest = go.GetComponent<PanelManifest>();
if (manifest == null)
manifest = go.AddComponent<PanelManifest>();
RefreshPanelManifest(manifest);
}
}
}
/// <summary>
/// 刷新面板清单
/// </summary>
private static void RefreshPanelManifest(PanelManifest manifest)
{
manifest.ReferencesAtlas.Clear();
string spriteDirectory = UIPanelSettings.GetSpriteDirecotry();
string altasDirectory = UIPanelSettings.GetAtlasDirecotry();
// 获取依赖的图集名称
Transform root = manifest.transform;
Image[] allImage = root.GetComponentsInChildren<Image>(true);
for (int i = 0; i < allImage.Length; i++)
{
Image image = allImage[i];
if (image.sprite == null)
continue;
// 文件路径
string spriteAssetPath = UnityEditor.AssetDatabase.GetAssetPath(image.sprite);
// 跳过系统内置资源
if (spriteAssetPath.Contains("_builtin_"))
continue;
// 跳过非图集精灵
if (spriteAssetPath.StartsWith(spriteDirectory) == false)
continue;
string atlasAssetPath = GetAtlasPath(altasDirectory, spriteAssetPath);
SpriteAtlas spriteAtlas = UnityEditor.AssetDatabase.LoadAssetAtPath<SpriteAtlas>(atlasAssetPath);
if (spriteAtlas == null)
{
throw new System.Exception($"Not found SpriteAtlas : {atlasAssetPath}");
}
else
{
if (manifest.ReferencesAtlas.Contains(spriteAtlas) == false)
manifest.ReferencesAtlas.Add(spriteAtlas);
}
}
}
/// <summary>
/// 获取精灵所属图集
/// </summary>
private static string GetAtlasPath(string atlasDirectory, string assetPath)
{
string directory = Path.GetDirectoryName(assetPath);
DirectoryInfo directoryInfo = new DirectoryInfo(directory);
string atlasName = directoryInfo.Name;
return $"{atlasDirectory}/{atlasName}.spriteatlas";
}
}
#endif

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: eee88a2a10c99aa49b12a0fbff4084f0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;
using YooAsset;
public class SpriteAtlasLoader : MonoBehaviour
{
private Dictionary<string, SpriteAtlas> _loadedAtlas = new Dictionary<string, SpriteAtlas>(1000);
private List<AssetHandle> _loadHandles = new List<AssetHandle>(1000);
public void Awake()
{
SpriteAtlasManager.atlasRequested += RequestAtlas;
}
public void OnDestroy()
{
foreach (var handle in _loadHandles)
{
handle.Release();
}
}
private void RequestAtlas(string atlasName, Action<SpriteAtlas> callback)
{
if (_loadedAtlas.TryGetValue(atlasName, out var value))
{
callback.Invoke(value);
}
else
{
var package = YooAssets.GetPackage("DefaultPackage");
var loadHandle = package.LoadAssetSync<SpriteAtlas>(atlasName);
if (loadHandle.Status != EOperationStatus.Succeed)
{
Debug.LogWarning($"Failed to load sprite atlas : {atlasName} ! {loadHandle.LastError}");
return;
}
_loadHandles.Add(loadHandle);
callback.Invoke(loadHandle.AssetObject as SpriteAtlas);
}
}
}

View File

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

View File

@@ -2,9 +2,7 @@
"name": "YooAsset.RuntimeExtension",
"rootNamespace": "",
"references": [
"GUID:e34a5702dd353724aa315fb8011f08c3",
"GUID:5efd170ecd8084500bed5692932fe14e",
"GUID:bb21d6197862c4c3e863390dec9859a7"
"GUID:e34a5702dd353724aa315fb8011f08c3"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2bbcb90032364234abe49c81b95714e1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b127fedb48547954b9c54084b6a32a65
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -8,7 +8,7 @@ internal class TTFSDownloadFileOperation : DefaultDownloadFileOperation
private TiktokFileSystem _fileSystem;
private ESteps _steps = ESteps.None;
internal TTFSDownloadFileOperation(TiktokFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal TTFSDownloadFileOperation(TiktokFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
_fileSystem = fileSystem;
}

View File

@@ -35,19 +35,19 @@ internal class TTFSLoadBundleOperation : FSLoadBundleOperation
{
if (_downloadAssetBundleOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
downloadParam.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); ;
downloadParam.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
options.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); ;
options.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(false, _fileSystem.DecryptionServices, _bundle, downloadParam);
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(false, _fileSystem.DecryptionServices, _bundle, options);
_downloadAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadTiktokAssetBundleOperation(_bundle, downloadParam);
_downloadAssetBundleOp = new DownloadTiktokAssetBundleOperation(_bundle, options);
_downloadAssetBundleOp.StartOperation();
AddChildOperation(_downloadAssetBundleOp);
}

View File

@@ -11,14 +11,16 @@ internal class TTFSRequestPackageVersionOperation : FSRequestPackageVersionOpera
}
private readonly TiktokFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private RequestTiktokPackageVersionOperation _requestPackageVersionOp;
private ESteps _steps = ESteps.None;
internal TTFSRequestPackageVersionOperation(TiktokFileSystem fileSystem, int timeout)
internal TTFSRequestPackageVersionOperation(TiktokFileSystem fileSystem, bool appendTimeTicks, int timeout)
{
_fileSystem = fileSystem;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalStart()
@@ -34,7 +36,7 @@ internal class TTFSRequestPackageVersionOperation : FSRequestPackageVersionOpera
{
if (_requestPackageVersionOp == null)
{
_requestPackageVersionOp = new RequestTiktokPackageVersionOperation(_fileSystem, _timeout);
_requestPackageVersionOp = new RequestTiktokPackageVersionOperation(_fileSystem, _appendTimeTicks, _timeout);
_requestPackageVersionOp.StartOperation();
AddChildOperation(_requestPackageVersionOp);
}

View File

@@ -8,7 +8,7 @@ namespace YooAsset
{
private ESteps _steps = ESteps.None;
internal DownloadTiktokAssetBundleOperation(PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadTiktokAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
}
internal override void InternalStart()

View File

@@ -11,6 +11,7 @@ internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
}
private readonly TiktokFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
private int _requestCount = 0;
@@ -21,10 +22,11 @@ internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
/// </summary>
public string PackageVersion { private set; get; }
public RequestTiktokPackageVersionOperation(TiktokFileSystem fileSystem, int timeout)
public RequestTiktokPackageVersionOperation(TiktokFileSystem fileSystem, bool appendTimeTicks, int timeout)
{
_fileSystem = fileSystem;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalStart()
@@ -80,11 +82,19 @@ internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
private string GetRequestURL(string fileName)
{
string url;
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
url = _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
else
return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
url = _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
// 在URL末尾添加时间戳
if (_appendTimeTicks)
return $"{url}?{System.DateTime.UtcNow.Ticks}";
else
return url;
}
}
#endif

View File

@@ -121,19 +121,19 @@ internal class TiktokFileSystem : IFileSystem
}
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout)
{
var operation = new TTFSRequestPackageVersionOperation(this, timeout);
var operation = new TTFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam)
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{
var operation = new FSClearCacheFilesCompleteOperation();
return operation;
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param)
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
param.MainURL = RemoteServices.GetRemoteMainURL(bundle.FileName);
param.FallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName);
var operation = new TTFSDownloadFileOperation(this, bundle, param);
options.MainURL = RemoteServices.GetRemoteMainURL(bundle.FileName);
options.FallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName);
var operation = new TTFSDownloadFileOperation(this, bundle, options);
return operation;
}
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)

View File

@@ -1,6 +1,7 @@
#if UNITY_WEBGL && WEIXINMINIGAME
using System.Collections.Generic;
using System.IO;
using System.Linq;
using YooAsset;
using WeChatWASM;
@@ -39,6 +40,7 @@ internal class WXFSClearUnusedBundleFilesAsync : FSClearCacheFilesOperation
{
_steps = ESteps.WaitingSearch;
// 说明__GAME_FILE_CACHE/yoo/ 目录下包含所有的资源文件和清单文件
var fileSystemMgr = _fileSystem.GetFileSystemMgr();
var statOption = new WXStatOption();
statOption.path = _fileSystem.FileRoot;
@@ -47,13 +49,24 @@ internal class WXFSClearUnusedBundleFilesAsync : FSClearCacheFilesOperation
{
foreach (var fileStat in response.stats)
{
// 注意存储文件必须按照Bundle文件哈希值存储
string bundleGUID = Path.GetFileNameWithoutExtension(fileStat.path);
// 如果是目录文件
string fileExtension = Path.GetExtension(fileStat.path);
if (string.IsNullOrEmpty(fileExtension))
continue;
// 如果是资源清单
//TODO 默认的清单文件格式
if (fileExtension == ".bytes" || fileExtension == ".hash")
continue;
// 注意:适配不同的文件命名方式!
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileStat.path);
string bundleGUID = fileNameWithoutExtension.Split('_').Last();
if (_manifest.TryGetPackageBundleByBundleGUID(bundleGUID, out PackageBundle value) == false)
{
string fullPath = WX.GetCachePath(fileStat.path);
if (_unusedCacheFiles.Contains(fullPath) == false)
_unusedCacheFiles.Add(fullPath);
string filePath = _fileSystem.FileRoot + fileStat.path;
if (_unusedCacheFiles.Contains(filePath) == false)
_unusedCacheFiles.Add(filePath);
}
}

Some files were not shown because too many files have changed in this diff Show More