Compare commits

...

61 Commits

Author SHA1 Message Date
何冠峰
9ed85afb29 Update CHANGELOG.md 2025-06-17 19:26:39 +08:00
何冠峰
560a395173 Update CHANGELOG.md 2025-06-17 19:23:57 +08:00
何冠峰
8bce963588 Update package.json 2025-06-17 19:23:32 +08:00
何冠峰
f8a3fe47e5 add mini game sample
修复程序集不正确的问题
2025-06-17 18:29:17 +08:00
何冠峰
48356a4f9e fix #573 2025-06-17 18:20:28 +08:00
何冠峰
d2a28bd801 fix #562 2025-06-17 17:07:02 +08:00
何冠峰
3949abb53f fix #566
重构了资源构建页面,方便扩展自定义界面。
2025-06-17 15:29:54 +08:00
何冠峰
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
何冠峰
9fb7f8bbfe Update CHANGELOG.md 2025-04-01 14:20:52 +08:00
何冠峰
b0382afad0 Update package.json 2025-04-01 14:20:46 +08:00
何冠峰
1ab7689174 fix #524
新增初始化参数 BundleLoadingMaxConcurrency
2025-04-01 11:44:10 +08:00
何冠峰
29d456c065 fix #523 2025-04-01 10:22:01 +08:00
何冠峰
b0dc829b04 fix #515
资源路径大小写不敏感逻辑优化
2025-03-31 19:06:03 +08:00
何冠峰
b3ead90832 fix #526 2025-03-31 18:13:07 +08:00
何冠峰
7bf00d4ff6 update space shooter 2025-03-31 17:28:10 +08:00
何冠峰
030e94d8ff update test sample 2025-03-31 17:27:58 +08:00
何冠峰
cf05254121 fix #519
FileSystemParametersDefine新增参数:INSTALL_CLEAR_MODE
2025-03-31 17:26:46 +08:00
何冠峰
3f786bca3b Merge branch 'dev' of https://github.com/tuyoogame/YooAsset into dev 2025-03-26 15:12:04 +08:00
何冠峰
98719d212f Merge pull request #520 from SongQQQ/fix-UWPError
修复了UWP平台报错
2025-03-26 14:35:24 +08:00
SONG\11700
3409f7ce4d 修复了UWP平台报错 2025-03-26 12:07:59 +08:00
何冠峰
f57b354e9b fix : UWP平台的适配问题。
修复UWP平台获取WWW加载路径未适配的问题。
2025-03-26 11:45:50 +08:00
197 changed files with 2760 additions and 806 deletions

View File

@@ -2,6 +2,151 @@
All notable changes to this package will be documented in this file.
## [2.3.10] - 2025-06-17
### Improvements
- 小游戏扩展库已经独立,可以单独导入到项目工程。
- 编辑器里的TableView视图新增了AssetObjectCell类。
- (#552) 微信小游戏文件系统类增加了URL合法性的初始化检测机制。
- (#566) 重构了资源构建页面,方便扩展自定义界面。
- (#573) 完善了AssetDependencyDB的输出日志可以正确输出丢失的引用资产信息。
### Fixed
- 修复太空战机DEMO在退出运行模式时的报错。
- (#551) 修复了Unity2019, Unity2020的代码兼容性报错。
- (#569) 修复了TVOS平台的兼容问题。
- (#564) 修复了TiktokFileSystem文件系统里appendTimeTicks无效的问题。
### Added
- (#562) 新增了解密方法。
```csharp
public interface IDecryptionServices
{
/// <summary>
/// 后备方式获取解密的资源包对象
/// 注意:当正常解密方法失败后,会触发后备加载!
/// 说明建议通过LoadFromMemory()方法加载资源对象作为保底机制。
/// issues : https://github.com/tuyoogame/YooAsset/issues/562
/// </summary>
DecryptResult LoadAssetBundleFallback(DecryptFileInfo fileInfo);
}
```
## [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
- (#526) 运行时资源清单的哈希值验证兼容了MD5和CRC32两种方式。
- (#515) 优化了资源路径大小写不敏感的逻辑代码减少字符串操作产生的GC。
- (#523) UnloadUnusedAssetsOperation方法支持了分帧处理。
### Fixed
- (#520) 修复了UWP平台获取WWW加载路径未适配的问题。
### Added
- 新增了文件系统初始化参数INSTALL_CLEAR_MODE
```csharp
/// <summary>
/// 覆盖安装清理模式
/// </summary>
public enum EOverwriteInstallClearMode
{
/// <summary>
/// 不做任何处理
/// </summary>
None = 0,
/// <summary>
/// 清理所有缓存文件(包含资源文件和清单文件)
/// </summary>
ClearAllCacheFiles = 1,
/// <summary>
/// 清理所有缓存的资源文件
/// </summary>
ClearAllBundleFiles = 2,
/// <summary>
/// 清理所有缓存的清单文件
/// </summary>
ClearAllManifestFiles = 3,
}
```
- 新增了初始化参数BundleLoadingMaxConcurrency
```csharp
public abstract class InitializeParameters
{
/// <summary>
/// 同时加载Bundle文件的最大并发数
/// </summary>
public int BundleLoadingMaxConcurrency = int.MaxValue;
}
```
## [2.3.6] - 2025-03-25
### 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

@@ -6,97 +6,98 @@ namespace YooAsset.Editor
{
public static class AssetBundleBuilderSetting
{
// EBuildPipeline
public static EBuildPipeline GetPackageBuildPipeline(string packageName)
// BuildPipelineName
public static string GetPackageBuildPipeline(string packageName)
{
string key = $"{Application.productName}_{packageName}_{nameof(EBuildPipeline)}";
return (EBuildPipeline)EditorPrefs.GetInt(key, (int)EBuildPipeline.BuiltinBuildPipeline);
string key = $"{Application.productName}_{packageName}_BuildPipelineName";
string defaultValue = EBuildPipeline.ScriptableBuildPipeline.ToString();
return EditorPrefs.GetString(key, defaultValue);
}
public static void SetPackageBuildPipeline(string packageName, EBuildPipeline buildPipeline)
public static void SetPackageBuildPipeline(string packageName, string buildPipeline)
{
string key = $"{Application.productName}_{packageName}_{nameof(EBuildPipeline)}";
EditorPrefs.SetInt(key, (int)buildPipeline);
string key = $"{Application.productName}_{packageName}_BuildPipelineName";
EditorPrefs.SetString(key, buildPipeline);
}
// ECompressOption
public static ECompressOption GetPackageCompressOption(string packageName, EBuildPipeline buildPipeline)
public static ECompressOption GetPackageCompressOption(string packageName, string buildPipeline)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(ECompressOption)}";
return (ECompressOption)EditorPrefs.GetInt(key, (int)ECompressOption.LZ4);
}
public static void SetPackageCompressOption(string packageName, EBuildPipeline buildPipeline, ECompressOption compressOption)
public static void SetPackageCompressOption(string packageName, string buildPipeline, ECompressOption compressOption)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(ECompressOption)}";
EditorPrefs.SetInt(key, (int)compressOption);
}
// EFileNameStyle
public static EFileNameStyle GetPackageFileNameStyle(string packageName, EBuildPipeline buildPipeline)
public static EFileNameStyle GetPackageFileNameStyle(string packageName, string buildPipeline)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(EFileNameStyle)}";
return (EFileNameStyle)EditorPrefs.GetInt(key, (int)EFileNameStyle.HashName);
}
public static void SetPackageFileNameStyle(string packageName, EBuildPipeline buildPipeline, EFileNameStyle fileNameStyle)
public static void SetPackageFileNameStyle(string packageName, string buildPipeline, EFileNameStyle fileNameStyle)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(EFileNameStyle)}";
EditorPrefs.SetInt(key, (int)fileNameStyle);
}
// EBuildinFileCopyOption
public static EBuildinFileCopyOption GetPackageBuildinFileCopyOption(string packageName, EBuildPipeline buildPipeline)
public static EBuildinFileCopyOption GetPackageBuildinFileCopyOption(string packageName, string buildPipeline)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(EBuildinFileCopyOption)}";
return (EBuildinFileCopyOption)EditorPrefs.GetInt(key, (int)EBuildinFileCopyOption.None);
}
public static void SetPackageBuildinFileCopyOption(string packageName, EBuildPipeline buildPipeline, EBuildinFileCopyOption buildinFileCopyOption)
public static void SetPackageBuildinFileCopyOption(string packageName, string buildPipeline, EBuildinFileCopyOption buildinFileCopyOption)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(EBuildinFileCopyOption)}";
EditorPrefs.SetInt(key, (int)buildinFileCopyOption);
}
// BuildFileCopyParams
public static string GetPackageBuildinFileCopyParams(string packageName, EBuildPipeline buildPipeline)
public static string GetPackageBuildinFileCopyParams(string packageName, string buildPipeline)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_BuildFileCopyParams";
return EditorPrefs.GetString(key, string.Empty);
}
public static void SetPackageBuildinFileCopyParams(string packageName, EBuildPipeline buildPipeline, string buildinFileCopyParams)
public static void SetPackageBuildinFileCopyParams(string packageName, string buildPipeline, string buildinFileCopyParams)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_BuildFileCopyParams";
EditorPrefs.SetString(key, buildinFileCopyParams);
}
// EncyptionClassName
public static string GetPackageEncyptionClassName(string packageName, EBuildPipeline buildPipeline)
public static string GetPackageEncyptionClassName(string packageName, string buildPipeline)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_EncyptionClassName";
return EditorPrefs.GetString(key, string.Empty);
}
public static void SetPackageEncyptionClassName(string packageName, EBuildPipeline buildPipeline, string encyptionClassName)
public static void SetPackageEncyptionClassName(string packageName, string buildPipeline, string encyptionClassName)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_EncyptionClassName";
EditorPrefs.SetString(key, encyptionClassName);
}
// ClearBuildCache
public static bool GetPackageClearBuildCache(string packageName, EBuildPipeline buildPipeline)
public static bool GetPackageClearBuildCache(string packageName, string buildPipeline)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_ClearBuildCache";
return EditorPrefs.GetInt(key, 0) > 0;
}
public static void SetPackageClearBuildCache(string packageName, EBuildPipeline buildPipeline, bool clearBuildCache)
public static void SetPackageClearBuildCache(string packageName, string buildPipeline, bool clearBuildCache)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_ClearBuildCache";
EditorPrefs.SetInt(key, clearBuildCache ? 1 : 0);
}
// UseAssetDependencyDB
public static bool GetPackageUseAssetDependencyDB(string packageName, EBuildPipeline buildPipeline)
public static bool GetPackageUseAssetDependencyDB(string packageName, string buildPipeline)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_UseAssetDependencyDB";
return EditorPrefs.GetInt(key, 0) > 0;
}
public static void SetPackageUseAssetDependencyDB(string packageName, EBuildPipeline buildPipeline, bool useAssetDependencyDB)
public static void SetPackageUseAssetDependencyDB(string packageName, string buildPipeline, bool useAssetDependencyDB)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_UseAssetDependencyDB";
EditorPrefs.SetInt(key, useAssetDependencyDB ? 1 : 0);

View File

@@ -19,7 +19,9 @@ namespace YooAsset.Editor
}
private string _buildPackage;
private EBuildPipeline _buildPipeline;
private string _buildPipeline;
private Dictionary<string, Type> _viewClassDic = new Dictionary<string, Type>(10);
private Toolbar _toolbar;
private ToolbarMenu _packageMenu;
@@ -69,11 +71,23 @@ namespace YooAsset.Editor
{
_pipelineMenu = new ToolbarMenu();
_pipelineMenu.style.width = 200;
_pipelineMenu.menu.AppendAction(EBuildPipeline.EditorSimulateBuildPipeline.ToString(), PipelineMenuAction, PipelineMenuFun, EBuildPipeline.EditorSimulateBuildPipeline);
_pipelineMenu.menu.AppendAction(EBuildPipeline.BuiltinBuildPipeline.ToString(), PipelineMenuAction, PipelineMenuFun, EBuildPipeline.BuiltinBuildPipeline);
_pipelineMenu.menu.AppendAction(EBuildPipeline.ScriptableBuildPipeline.ToString(), PipelineMenuAction, PipelineMenuFun, EBuildPipeline.ScriptableBuildPipeline);
_pipelineMenu.menu.AppendAction(EBuildPipeline.RawFileBuildPipeline.ToString(), PipelineMenuAction, PipelineMenuFun, EBuildPipeline.RawFileBuildPipeline);
_toolbar.Add(_pipelineMenu);
var viewerClassTypes = EditorTools.GetAssignableTypes(typeof(BuildPipelineViewerBase));
foreach (var classType in viewerClassTypes)
{
var buildPipelineAttribute = EditorTools.GetAttribute<BuildPipelineAttribute>(classType);
string pipelineName = buildPipelineAttribute.PipelineName;
if (_viewClassDic.ContainsKey(pipelineName))
{
Debug.LogWarning($"The pipeline has already exist : {pipelineName}");
}
else
{
_viewClassDic.Add(pipelineName, classType);
_pipelineMenu.menu.AppendAction(pipelineName, PipelineMenuAction, PipelineMenuFun);
}
}
}
RefreshBuildPipelineView();
@@ -91,28 +105,18 @@ namespace YooAsset.Editor
_buildPipeline = AssetBundleBuilderSetting.GetPackageBuildPipeline(_buildPackage);
_packageMenu.text = _buildPackage;
_pipelineMenu.text = _buildPipeline.ToString();
_pipelineMenu.text = _buildPipeline;
var buildTarget = EditorUserBuildSettings.activeBuildTarget;
if (_buildPipeline == EBuildPipeline.EditorSimulateBuildPipeline)
if (_viewClassDic.TryGetValue(_buildPipeline, out Type value))
{
var viewer = new EditorSimulateBuildPipelineViewer(_buildPackage, buildTarget, _container);
}
else if (_buildPipeline == EBuildPipeline.BuiltinBuildPipeline)
{
var viewer = new BuiltinBuildPipelineViewer(_buildPackage, buildTarget, _container);
}
else if (_buildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
var viewer = new ScriptableBuildPipelineViewer(_buildPackage, buildTarget, _container);
}
else if (_buildPipeline == EBuildPipeline.RawFileBuildPipeline)
{
var viewer = new RawfileBuildpipelineViewer(_buildPackage, buildTarget, _container);
var buildTarget = EditorUserBuildSettings.activeBuildTarget;
var viewer = Activator.CreateInstance(value) as BuildPipelineViewerBase;
viewer.InitView(_buildPackage, _buildPipeline, buildTarget);
viewer.CreateView(_container);
}
else
{
throw new System.NotImplementedException(_buildPipeline.ToString());
Debug.LogError($"Not found build pipeline : {_buildPipeline}");
}
}
private List<string> GetBuildPackageNames()
@@ -145,18 +149,16 @@ namespace YooAsset.Editor
private void PipelineMenuAction(DropdownMenuAction action)
{
var pipelineType = (EBuildPipeline)action.userData;
if (_buildPipeline != pipelineType)
if (_buildPipeline != action.name)
{
_buildPipeline = pipelineType;
AssetBundleBuilderSetting.SetPackageBuildPipeline(_buildPackage, pipelineType);
_buildPipeline = action.name;
AssetBundleBuilderSetting.SetPackageBuildPipeline(_buildPackage, _buildPipeline);
RefreshBuildPipelineView();
}
}
private DropdownMenuAction.Status PipelineMenuFun(DropdownMenuAction action)
{
var pipelineType = (EBuildPipeline)action.userData;
if (_buildPipeline == pipelineType)
if (_buildPipeline == action.name)
return DropdownMenuAction.Status.Checked;
else
return DropdownMenuAction.Status.Normal;

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

@@ -1,8 +1,13 @@

using UnityEditor;
using UnityEngine;
namespace YooAsset.Editor
{
public interface IBuildPipeline
{
/// <summary>
/// 运行构建任务
/// </summary>
BuildResult Run(BuildParameters buildParameters, bool enableLog);
}
}

View File

@@ -0,0 +1,14 @@
using System;
namespace YooAsset.Editor
{
public class BuildPipelineAttribute : Attribute
{
public string PipelineName;
public BuildPipelineAttribute(string name)
{
this.PipelineName = name;
}
}
}

View File

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

View File

@@ -12,190 +12,35 @@ namespace YooAsset.Editor
{
internal abstract class BuildPipelineViewerBase
{
private const int StyleWidth = 400;
private const int LabelMinWidth = 180;
protected const int StyleWidth = 400;
protected const int LabelMinWidth = 190;
protected readonly string PackageName;
protected readonly BuildTarget BuildTarget;
protected readonly EBuildPipeline BuildPipeline;
protected TemplateContainer Root;
protected string PackageName { private set; get; }
protected string PipelineName { private set; get; }
protected BuildTarget BuildTarget { private set; get; }
private TextField _buildOutputField;
private TextField _buildVersionField;
private PopupField<Enum> _buildModeField;
private PopupField<Type> _encryptionField;
private EnumField _compressionField;
private EnumField _outputNameStyleField;
private EnumField _copyBuildinFileOptionField;
private TextField _copyBuildinFileTagsField;
private Toggle _clearBuildCacheToggle;
private Toggle _useAssetDependencyDBToggle;
public BuildPipelineViewerBase(string packageName, EBuildPipeline buildPipeline, BuildTarget buildTarget, VisualElement parent)
/// <summary>
/// 初始化视图
/// </summary>
public void InitView(string packageName, string pipelineName, BuildTarget buildTarget)
{
PackageName = packageName;
PipelineName = pipelineName;
BuildTarget = buildTarget;
BuildPipeline = buildPipeline;
CreateView(parent);
RefreshView();
}
private void CreateView(VisualElement parent)
{
// 加载布局文件
var visualAsset = UxmlLoader.LoadWindowUXML<BuildPipelineViewerBase>();
if (visualAsset == null)
return;
Root = visualAsset.CloneTree();
Root.style.flexGrow = 1f;
parent.Add(Root);
// 输出目录
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
_buildOutputField = Root.Q<TextField>("BuildOutput");
_buildOutputField.SetValueWithoutNotify(defaultOutputRoot);
_buildOutputField.SetEnabled(false);
// 构建版本
_buildVersionField = Root.Q<TextField>("BuildVersion");
_buildVersionField.style.width = StyleWidth;
_buildVersionField.SetValueWithoutNotify(GetDefaultPackageVersion());
// 加密方法
{
var encryptionContainer = Root.Q("EncryptionContainer");
var encryptionClassTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices));
if (encryptionClassTypes.Count > 0)
{
var encyptionClassName = AssetBundleBuilderSetting.GetPackageEncyptionClassName(PackageName, BuildPipeline);
int defaultIndex = encryptionClassTypes.FindIndex(x => x.FullName.Equals(encyptionClassName));
if (defaultIndex < 0)
defaultIndex = 0;
_encryptionField = new PopupField<Type>(encryptionClassTypes, defaultIndex);
_encryptionField.label = "Encryption";
_encryptionField.style.width = StyleWidth;
_encryptionField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageEncyptionClassName(PackageName, BuildPipeline, _encryptionField.value.FullName);
});
encryptionContainer.Add(_encryptionField);
}
else
{
_encryptionField = new PopupField<Type>();
_encryptionField.label = "Encryption";
_encryptionField.style.width = StyleWidth;
encryptionContainer.Add(_encryptionField);
}
}
// 压缩方式选项
var compressOption = AssetBundleBuilderSetting.GetPackageCompressOption(PackageName, BuildPipeline);
_compressionField = Root.Q<EnumField>("Compression");
_compressionField.Init(compressOption);
_compressionField.SetValueWithoutNotify(compressOption);
_compressionField.style.width = StyleWidth;
_compressionField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageCompressOption(PackageName, BuildPipeline, (ECompressOption)_compressionField.value);
});
// 输出文件名称样式
var fileNameStyle = AssetBundleBuilderSetting.GetPackageFileNameStyle(PackageName, BuildPipeline);
_outputNameStyleField = Root.Q<EnumField>("FileNameStyle");
_outputNameStyleField.Init(fileNameStyle);
_outputNameStyleField.SetValueWithoutNotify(fileNameStyle);
_outputNameStyleField.style.width = StyleWidth;
_outputNameStyleField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageFileNameStyle(PackageName, BuildPipeline, (EFileNameStyle)_outputNameStyleField.value);
});
// 首包文件拷贝选项
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, BuildPipeline);
_copyBuildinFileOptionField = Root.Q<EnumField>("CopyBuildinFileOption");
_copyBuildinFileOptionField.Init(buildinFileCopyOption);
_copyBuildinFileOptionField.SetValueWithoutNotify(buildinFileCopyOption);
_copyBuildinFileOptionField.style.width = StyleWidth;
_copyBuildinFileOptionField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageBuildinFileCopyOption(PackageName, BuildPipeline, (EBuildinFileCopyOption)_copyBuildinFileOptionField.value);
RefreshView();
});
// 首包文件拷贝参数
var buildinFileCopyParams = AssetBundleBuilderSetting.GetPackageBuildinFileCopyParams(PackageName, BuildPipeline);
_copyBuildinFileTagsField = Root.Q<TextField>("CopyBuildinFileParam");
_copyBuildinFileTagsField.SetValueWithoutNotify(buildinFileCopyParams);
_copyBuildinFileTagsField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageBuildinFileCopyParams(PackageName, BuildPipeline, _copyBuildinFileTagsField.value);
});
// 清理构建缓存
bool clearBuildCache = AssetBundleBuilderSetting.GetPackageClearBuildCache(PackageName, BuildPipeline);
_clearBuildCacheToggle = Root.Q<Toggle>("ClearBuildCache");
_clearBuildCacheToggle.SetValueWithoutNotify(clearBuildCache);
_clearBuildCacheToggle.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageClearBuildCache(PackageName, BuildPipeline, _clearBuildCacheToggle.value);
});
// 使用资源依赖数据库
bool useAssetDependencyDB = AssetBundleBuilderSetting.GetPackageUseAssetDependencyDB(PackageName, BuildPipeline);
_useAssetDependencyDBToggle = Root.Q<Toggle>("UseAssetDependency");
_useAssetDependencyDBToggle.SetValueWithoutNotify(useAssetDependencyDB);
_useAssetDependencyDBToggle.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageUseAssetDependencyDB(PackageName, BuildPipeline, _useAssetDependencyDBToggle.value);
});
// 对齐文本间距
UIElementsTools.SetElementLabelMinWidth(_buildOutputField, LabelMinWidth);
UIElementsTools.SetElementLabelMinWidth(_buildVersionField, LabelMinWidth);
UIElementsTools.SetElementLabelMinWidth(_compressionField, LabelMinWidth);
UIElementsTools.SetElementLabelMinWidth(_encryptionField, LabelMinWidth);
UIElementsTools.SetElementLabelMinWidth(_outputNameStyleField, LabelMinWidth);
UIElementsTools.SetElementLabelMinWidth(_copyBuildinFileOptionField, LabelMinWidth);
UIElementsTools.SetElementLabelMinWidth(_copyBuildinFileTagsField, LabelMinWidth);
UIElementsTools.SetElementLabelMinWidth(_clearBuildCacheToggle, LabelMinWidth);
UIElementsTools.SetElementLabelMinWidth(_useAssetDependencyDBToggle, LabelMinWidth);
// 构建按钮
var buildButton = Root.Q<Button>("Build");
buildButton.clicked += BuildButton_clicked;
}
private void RefreshView()
{
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, BuildPipeline);
bool tagsFiledVisible = buildinFileCopyOption == EBuildinFileCopyOption.ClearAndCopyByTags || buildinFileCopyOption == EBuildinFileCopyOption.OnlyCopyByTags;
_copyBuildinFileTagsField.visible = tagsFiledVisible;
}
private void BuildButton_clicked()
{
if (EditorUtility.DisplayDialog("提示", $"开始构建资源包[{PackageName}]", "Yes", "No"))
{
EditorTools.ClearUnityConsole();
EditorApplication.delayCall += ExecuteBuild;
}
else
{
Debug.LogWarning("[Build] 打包已经取消");
}
}
/// <summary>
/// 执行构建任务
/// 创建视图
/// </summary>
protected abstract void ExecuteBuild();
public abstract void CreateView(VisualElement parent);
/// <summary>
/// 获取构建版本
/// 获取默认版本
/// </summary>
protected string GetPackageVersion()
protected virtual string GetDefaultPackageVersion()
{
return _buildVersionField.value;
int totalMinutes = DateTime.Now.Hour * 60 + DateTime.Now.Minute;
return DateTime.Now.ToString("yyyy-MM-dd") + "-" + totalMinutes;
}
/// <summary>
@@ -203,7 +48,7 @@ namespace YooAsset.Editor
/// </summary>
protected IEncryptionServices CreateEncryptionInstance()
{
var encyptionClassName = AssetBundleBuilderSetting.GetPackageEncyptionClassName(PackageName, BuildPipeline);
var encyptionClassName = AssetBundleBuilderSetting.GetPackageEncyptionClassName(PackageName, PipelineName);
var encryptionClassTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices));
var classType = encryptionClassTypes.Find(x => x.FullName.Equals(encyptionClassName));
if (classType != null)
@@ -212,11 +57,130 @@ namespace YooAsset.Editor
return null;
}
private string GetDefaultPackageVersion()
#region UI元素通用处理方法
protected void SetBuildOutputField(TextField textField)
{
int totalMinutes = DateTime.Now.Hour * 60 + DateTime.Now.Minute;
return DateTime.Now.ToString("yyyy-MM-dd") + "-" + totalMinutes;
// 输出目录
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
textField.SetValueWithoutNotify(defaultOutputRoot);
textField.SetEnabled(false);
UIElementsTools.SetElementLabelMinWidth(textField, LabelMinWidth);
}
protected void SetBuildVersionField(TextField textField)
{
// 构建版本
textField.style.width = StyleWidth;
textField.SetValueWithoutNotify(GetDefaultPackageVersion());
UIElementsTools.SetElementLabelMinWidth(textField, LabelMinWidth);
}
protected void SetCompressionField(EnumField enumField)
{
// 压缩方式选项
var compressOption = AssetBundleBuilderSetting.GetPackageCompressOption(PackageName, PipelineName);
enumField.Init(compressOption);
enumField.SetValueWithoutNotify(compressOption);
enumField.style.width = StyleWidth;
enumField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageCompressOption(PackageName, PipelineName, (ECompressOption)enumField.value);
});
UIElementsTools.SetElementLabelMinWidth(enumField, LabelMinWidth);
}
protected void SetOutputNameStyleField(EnumField enumField)
{
// 输出文件名称样式
var fileNameStyle = AssetBundleBuilderSetting.GetPackageFileNameStyle(PackageName, PipelineName);
enumField.Init(fileNameStyle);
enumField.SetValueWithoutNotify(fileNameStyle);
enumField.style.width = StyleWidth;
enumField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageFileNameStyle(PackageName, PipelineName, (EFileNameStyle)enumField.value);
});
UIElementsTools.SetElementLabelMinWidth(enumField, LabelMinWidth);
}
protected void SetCopyBuildinFileOptionField(EnumField enumField, TextField tagField)
{
// 首包文件拷贝选项
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, PipelineName);
enumField.Init(buildinFileCopyOption);
enumField.SetValueWithoutNotify(buildinFileCopyOption);
enumField.style.width = StyleWidth;
enumField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageBuildinFileCopyOption(PackageName, PipelineName, (EBuildinFileCopyOption)enumField.value);
// 设置内置资源标签显隐
bool tagsFiledVisible = buildinFileCopyOption == EBuildinFileCopyOption.ClearAndCopyByTags || buildinFileCopyOption == EBuildinFileCopyOption.OnlyCopyByTags;
tagField.visible = tagsFiledVisible;
});
UIElementsTools.SetElementLabelMinWidth(enumField, LabelMinWidth);
}
protected void SetCopyBuildinFileTagsField(TextField textField)
{
// 首包文件拷贝参数
var buildinFileCopyParams = AssetBundleBuilderSetting.GetPackageBuildinFileCopyParams(PackageName, PipelineName);
textField.SetValueWithoutNotify(buildinFileCopyParams);
textField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageBuildinFileCopyParams(PackageName, PipelineName, textField.value);
});
UIElementsTools.SetElementLabelMinWidth(textField, LabelMinWidth);
}
protected void SetClearBuildCacheToggle(Toggle toggle)
{
// 清理构建缓存
bool clearBuildCache = AssetBundleBuilderSetting.GetPackageClearBuildCache(PackageName, PipelineName);
toggle.SetValueWithoutNotify(clearBuildCache);
toggle.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageClearBuildCache(PackageName, PipelineName, toggle.value);
});
UIElementsTools.SetElementLabelMinWidth(toggle, LabelMinWidth);
}
protected void SetUseAssetDependencyDBToggle(Toggle toggle)
{
// 使用资源依赖数据库
bool useAssetDependencyDB = AssetBundleBuilderSetting.GetPackageUseAssetDependencyDB(PackageName, PipelineName);
toggle.SetValueWithoutNotify(useAssetDependencyDB);
toggle.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageUseAssetDependencyDB(PackageName, PipelineName, toggle.value);
});
UIElementsTools.SetElementLabelMinWidth(toggle, LabelMinWidth);
}
protected PopupField<Type> CreateEncryptionField(VisualElement container)
{
// 加密方法
var encryptionClassTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices));
if (encryptionClassTypes.Count > 0)
{
var encyptionClassName = AssetBundleBuilderSetting.GetPackageEncyptionClassName(PackageName, PipelineName);
int defaultIndex = encryptionClassTypes.FindIndex(x => x.FullName.Equals(encyptionClassName));
if (defaultIndex < 0)
defaultIndex = 0;
var encryptionField = new PopupField<Type>(encryptionClassTypes, defaultIndex);
encryptionField.label = "Encryption";
encryptionField.style.width = StyleWidth;
encryptionField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageEncyptionClassName(PackageName, PipelineName, encryptionField.value.FullName);
});
container.Add(encryptionField);
UIElementsTools.SetElementLabelMinWidth(encryptionField, LabelMinWidth);
return encryptionField;
}
else
{
var encryptionField = new PopupField<Type>();
encryptionField.label = "Encryption";
encryptionField.style.width = StyleWidth;
container.Add(encryptionField);
UIElementsTools.SetElementLabelMinWidth(encryptionField, LabelMinWidth);
return encryptionField;
}
}
#endregion
}
}
#endif

View File

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

View File

@@ -0,0 +1,128 @@
#if UNITY_2019_4_OR_NEWER
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
[BuildPipelineAttribute(nameof(EBuildPipeline.BuiltinBuildPipeline))]
internal class BuiltinBuildPipelineViewer : BuildPipelineViewerBase
{
protected TemplateContainer Root;
protected TextField _buildOutputField;
protected TextField _buildVersionField;
protected PopupField<Type> _encryptionField;
protected EnumField _compressionField;
protected EnumField _outputNameStyleField;
protected EnumField _copyBuildinFileOptionField;
protected TextField _copyBuildinFileTagsField;
protected Toggle _clearBuildCacheToggle;
protected Toggle _useAssetDependencyDBToggle;
public override void CreateView(VisualElement parent)
{
// 加载布局文件
var visualAsset = UxmlLoader.LoadWindowUXML<BuiltinBuildPipelineViewer>();
if (visualAsset == null)
return;
Root = visualAsset.CloneTree();
Root.style.flexGrow = 1f;
parent.Add(Root);
// 输出目录
_buildOutputField = Root.Q<TextField>("BuildOutput");
SetBuildOutputField(_buildOutputField);
// 构建版本
_buildVersionField = Root.Q<TextField>("BuildVersion");
SetBuildVersionField(_buildVersionField);
// 加密方法
var encryptionContainer = Root.Q("EncryptionContainer");
_encryptionField = CreateEncryptionField(encryptionContainer);
// 压缩方式选项
_compressionField = Root.Q<EnumField>("Compression");
SetCompressionField(_compressionField);
// 输出文件名称样式
_outputNameStyleField = Root.Q<EnumField>("FileNameStyle");
SetOutputNameStyleField(_outputNameStyleField);
// 首包文件拷贝参数
_copyBuildinFileTagsField = Root.Q<TextField>("CopyBuildinFileParam");
SetCopyBuildinFileTagsField(_copyBuildinFileTagsField);
// 首包文件拷贝选项
_copyBuildinFileOptionField = Root.Q<EnumField>("CopyBuildinFileOption");
SetCopyBuildinFileOptionField(_copyBuildinFileOptionField, _copyBuildinFileTagsField);
// 清理构建缓存
_clearBuildCacheToggle = Root.Q<Toggle>("ClearBuildCache");
SetClearBuildCacheToggle(_clearBuildCacheToggle);
// 使用资源依赖数据库
_useAssetDependencyDBToggle = Root.Q<Toggle>("UseAssetDependency");
SetUseAssetDependencyDBToggle(_useAssetDependencyDBToggle);
// 构建按钮
var buildButton = Root.Q<Button>("Build");
buildButton.clicked += BuildButton_clicked;
}
private void BuildButton_clicked()
{
if (EditorUtility.DisplayDialog("提示", $"开始构建资源包[{PackageName}]", "Yes", "No"))
{
EditorTools.ClearUnityConsole();
EditorApplication.delayCall += ExecuteBuild;
}
else
{
Debug.LogWarning("[Build] 打包已经取消");
}
}
/// <summary>
/// 执行构建
/// </summary>
protected virtual void ExecuteBuild()
{
var fileNameStyle = AssetBundleBuilderSetting.GetPackageFileNameStyle(PackageName, PipelineName);
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, PipelineName);
var buildinFileCopyParams = AssetBundleBuilderSetting.GetPackageBuildinFileCopyParams(PackageName, PipelineName);
var compressOption = AssetBundleBuilderSetting.GetPackageCompressOption(PackageName, PipelineName);
var clearBuildCache = AssetBundleBuilderSetting.GetPackageClearBuildCache(PackageName, PipelineName);
var useAssetDependencyDB = AssetBundleBuilderSetting.GetPackageUseAssetDependencyDB(PackageName, PipelineName);
BuiltinBuildParameters buildParameters = new BuiltinBuildParameters();
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = PipelineName.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.AssetBundle;
buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = _buildVersionField.value;
buildParameters.EnableSharePackRule = true;
buildParameters.VerifyBuildingResult = true;
buildParameters.FileNameStyle = fileNameStyle;
buildParameters.BuildinFileCopyOption = buildinFileCopyOption;
buildParameters.BuildinFileCopyParams = buildinFileCopyParams;
buildParameters.CompressOption = compressOption;
buildParameters.ClearBuildCacheFiles = clearBuildCache;
buildParameters.UseAssetDependencyDB = useAssetDependencyDB;
buildParameters.EncryptionServices = CreateEncryptionInstance();
BuiltinBuildPipeline pipeline = new BuiltinBuildPipeline();
var buildResult = pipeline.Run(buildParameters, true);
if (buildResult.Success)
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
}
}
}
#endif

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 86d0df373d425b449a3bbc42b4b2e5bb
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

View File

@@ -1,57 +0,0 @@
#if UNITY_2019_4_OR_NEWER
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
internal class BuiltinBuildPipelineViewer : BuildPipelineViewerBase
{
public BuiltinBuildPipelineViewer(string packageName, BuildTarget buildTarget, VisualElement parent)
: base(packageName, EBuildPipeline.BuiltinBuildPipeline, buildTarget, parent)
{
}
/// <summary>
/// 执行构建
/// </summary>
protected override void ExecuteBuild()
{
var fileNameStyle = AssetBundleBuilderSetting.GetPackageFileNameStyle(PackageName, BuildPipeline);
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, BuildPipeline);
var buildinFileCopyParams = AssetBundleBuilderSetting.GetPackageBuildinFileCopyParams(PackageName, BuildPipeline);
var compressOption = AssetBundleBuilderSetting.GetPackageCompressOption(PackageName, BuildPipeline);
var clearBuildCache = AssetBundleBuilderSetting.GetPackageClearBuildCache(PackageName, BuildPipeline);
var useAssetDependencyDB = AssetBundleBuilderSetting.GetPackageUseAssetDependencyDB(PackageName, BuildPipeline);
BuiltinBuildParameters buildParameters = new BuiltinBuildParameters();
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = BuildPipeline.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.AssetBundle;
buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = GetPackageVersion();
buildParameters.EnableSharePackRule = true;
buildParameters.VerifyBuildingResult = true;
buildParameters.FileNameStyle = fileNameStyle;
buildParameters.BuildinFileCopyOption = buildinFileCopyOption;
buildParameters.BuildinFileCopyParams = buildinFileCopyParams;
buildParameters.CompressOption = compressOption;
buildParameters.ClearBuildCacheFiles = clearBuildCache;
buildParameters.UseAssetDependencyDB = useAssetDependencyDB;
buildParameters.EncryptionServices = CreateEncryptionInstance();
BuiltinBuildPipeline pipeline = new BuiltinBuildPipeline();
var buildResult = pipeline.Run(buildParameters, true);
if (buildResult.Success)
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,86 @@
#if UNITY_2019_4_OR_NEWER
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
[BuildPipelineAttribute(nameof(EBuildPipeline.EditorSimulateBuildPipeline))]
internal class EditorSimulateBuildPipelineViewer : BuildPipelineViewerBase
{
protected TemplateContainer Root;
protected TextField _buildOutputField;
protected TextField _buildVersionField;
public override void CreateView(VisualElement parent)
{
// 加载布局文件
var visualAsset = UxmlLoader.LoadWindowUXML<EditorSimulateBuildPipelineViewer>();
if (visualAsset == null)
return;
Root = visualAsset.CloneTree();
Root.style.flexGrow = 1f;
parent.Add(Root);
// 输出目录
_buildOutputField = Root.Q<TextField>("BuildOutput");
SetBuildOutputField(_buildOutputField);
// 构建版本
_buildVersionField = Root.Q<TextField>("BuildVersion");
SetBuildVersionField(_buildVersionField);
// 构建按钮
var buildButton = Root.Q<Button>("Build");
buildButton.clicked += BuildButton_clicked;
}
private void BuildButton_clicked()
{
if (EditorUtility.DisplayDialog("提示", $"开始构建资源包[{PackageName}]", "Yes", "No"))
{
EditorTools.ClearUnityConsole();
EditorApplication.delayCall += ExecuteBuild;
}
else
{
Debug.LogWarning("[Build] 打包已经取消");
}
}
/// <summary>
/// 执行构建
/// </summary>
protected virtual void ExecuteBuild()
{
var fileNameStyle = AssetBundleBuilderSetting.GetPackageFileNameStyle(PackageName, PipelineName);
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, PipelineName);
var buildinFileCopyParams = AssetBundleBuilderSetting.GetPackageBuildinFileCopyParams(PackageName, PipelineName);
EditorSimulateBuildParameters buildParameters = new EditorSimulateBuildParameters();
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = PipelineName.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.VirtualBundle;
buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = _buildVersionField.value;
buildParameters.VerifyBuildingResult = true;
buildParameters.FileNameStyle = fileNameStyle;
buildParameters.BuildinFileCopyOption = buildinFileCopyOption;
buildParameters.BuildinFileCopyParams = buildinFileCopyParams;
buildParameters.EncryptionServices = CreateEncryptionInstance();
EditorSimulateBuildPipeline pipeline = new EditorSimulateBuildPipeline();
var buildResult = pipeline.Run(buildParameters, true);
if (buildResult.Success)
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
}
}
}
#endif

View File

@@ -0,0 +1,8 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
<ui:VisualElement name="BuildContainer">
<ui:TextField picking-mode="Ignore" label="Build Output" name="BuildOutput" />
<ui:TextField picking-mode="Ignore" label="Build Version" name="BuildVersion" />
<ui:VisualElement name="ExtensionContainer" />
<ui:Button text="Click Build" display-tooltip-when-elided="true" name="Build" style="height: 50px; background-color: rgb(40, 106, 42); margin-top: 10px;" />
</ui:VisualElement>
</ui:UXML>

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 90cc4546b2b8afe4e8c864c132a999a9
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

View File

@@ -1,70 +0,0 @@
#if UNITY_2019_4_OR_NEWER
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
internal class EditorSimulateBuildPipelineViewer : BuildPipelineViewerBase
{
public EditorSimulateBuildPipelineViewer(string packageName, BuildTarget buildTarget, VisualElement parent)
: base(packageName, EBuildPipeline.RawFileBuildPipeline, buildTarget, parent)
{
var compressionField = Root.Q<EnumField>("Compression");
UIElementsTools.SetElementVisible(compressionField, false);
var encryptionContainer = Root.Q<VisualElement>("EncryptionContainer");
UIElementsTools.SetElementVisible(encryptionContainer, false);
var fileNameStyleField = Root.Q<EnumField>("FileNameStyle");
UIElementsTools.SetElementVisible(fileNameStyleField, false);
var copyBuildinFileOptionField = Root.Q<EnumField>("CopyBuildinFileOption");
UIElementsTools.SetElementVisible(copyBuildinFileOptionField, false);
var copyBuildinFileParamField = Root.Q<TextField>("CopyBuildinFileParam");
UIElementsTools.SetElementVisible(copyBuildinFileParamField, false);
var clearBuildCacheToggle = Root.Q<Toggle>("ClearBuildCache");
UIElementsTools.SetElementVisible(clearBuildCacheToggle, false);
var useAssetDependencyToggle = Root.Q<Toggle>("UseAssetDependency");
UIElementsTools.SetElementVisible(useAssetDependencyToggle, false);
}
/// <summary>
/// 执行构建
/// </summary>
protected override void ExecuteBuild()
{
var fileNameStyle = AssetBundleBuilderSetting.GetPackageFileNameStyle(PackageName, BuildPipeline);
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, BuildPipeline);
var buildinFileCopyParams = AssetBundleBuilderSetting.GetPackageBuildinFileCopyParams(PackageName, BuildPipeline);
EditorSimulateBuildParameters buildParameters = new EditorSimulateBuildParameters();
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = BuildPipeline.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.VirtualBundle;
buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = GetPackageVersion();
buildParameters.VerifyBuildingResult = true;
buildParameters.FileNameStyle = fileNameStyle;
buildParameters.BuildinFileCopyOption = buildinFileCopyOption;
buildParameters.BuildinFileCopyParams = buildinFileCopyParams;
buildParameters.EncryptionServices = CreateEncryptionInstance();
EditorSimulateBuildPipeline pipeline = new EditorSimulateBuildPipeline();
var buildResult = pipeline.Run(buildParameters, true);
if (buildResult.Success)
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,120 @@
#if UNITY_2019_4_OR_NEWER
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
[BuildPipelineAttribute(nameof(EBuildPipeline.RawFileBuildPipeline))]
internal class RawfileBuildpipelineViewer : BuildPipelineViewerBase
{
protected TemplateContainer Root;
protected TextField _buildOutputField;
protected TextField _buildVersionField;
protected PopupField<Type> _encryptionField;
protected EnumField _outputNameStyleField;
protected EnumField _copyBuildinFileOptionField;
protected TextField _copyBuildinFileTagsField;
protected Toggle _clearBuildCacheToggle;
protected Toggle _useAssetDependencyDBToggle;
public override void CreateView(VisualElement parent)
{
// 加载布局文件
var visualAsset = UxmlLoader.LoadWindowUXML<RawfileBuildpipelineViewer>();
if (visualAsset == null)
return;
Root = visualAsset.CloneTree();
Root.style.flexGrow = 1f;
parent.Add(Root);
// 输出目录
_buildOutputField = Root.Q<TextField>("BuildOutput");
SetBuildOutputField(_buildOutputField);
// 构建版本
_buildVersionField = Root.Q<TextField>("BuildVersion");
SetBuildVersionField(_buildVersionField);
// 加密方法
var encryptionContainer = Root.Q("EncryptionContainer");
_encryptionField = CreateEncryptionField(encryptionContainer);
// 输出文件名称样式
_outputNameStyleField = Root.Q<EnumField>("FileNameStyle");
SetOutputNameStyleField(_outputNameStyleField);
// 首包文件拷贝参数
_copyBuildinFileTagsField = Root.Q<TextField>("CopyBuildinFileParam");
SetCopyBuildinFileTagsField(_copyBuildinFileTagsField);
// 首包文件拷贝选项
_copyBuildinFileOptionField = Root.Q<EnumField>("CopyBuildinFileOption");
SetCopyBuildinFileOptionField(_copyBuildinFileOptionField, _copyBuildinFileTagsField);
// 清理构建缓存
_clearBuildCacheToggle = Root.Q<Toggle>("ClearBuildCache");
SetClearBuildCacheToggle(_clearBuildCacheToggle);
// 使用资源依赖数据库
_useAssetDependencyDBToggle = Root.Q<Toggle>("UseAssetDependency");
SetUseAssetDependencyDBToggle(_useAssetDependencyDBToggle);
// 构建按钮
var buildButton = Root.Q<Button>("Build");
buildButton.clicked += BuildButton_clicked;
}
private void BuildButton_clicked()
{
if (EditorUtility.DisplayDialog("提示", $"开始构建资源包[{PackageName}]", "Yes", "No"))
{
EditorTools.ClearUnityConsole();
EditorApplication.delayCall += ExecuteBuild;
}
else
{
Debug.LogWarning("[Build] 打包已经取消");
}
}
/// <summary>
/// 执行构建
/// </summary>
protected virtual void ExecuteBuild()
{
var fileNameStyle = AssetBundleBuilderSetting.GetPackageFileNameStyle(PackageName, PipelineName);
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, PipelineName);
var buildinFileCopyParams = AssetBundleBuilderSetting.GetPackageBuildinFileCopyParams(PackageName, PipelineName);
var clearBuildCache = AssetBundleBuilderSetting.GetPackageClearBuildCache(PackageName, PipelineName);
var useAssetDependencyDB = AssetBundleBuilderSetting.GetPackageUseAssetDependencyDB(PackageName, PipelineName);
RawFileBuildParameters buildParameters = new RawFileBuildParameters();
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = PipelineName.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.RawBundle;
buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = _buildVersionField.value;
buildParameters.VerifyBuildingResult = true;
buildParameters.FileNameStyle = fileNameStyle;
buildParameters.BuildinFileCopyOption = buildinFileCopyOption;
buildParameters.BuildinFileCopyParams = buildinFileCopyParams;
buildParameters.ClearBuildCacheFiles = clearBuildCache;
buildParameters.UseAssetDependencyDB = useAssetDependencyDB;
buildParameters.EncryptionServices = CreateEncryptionInstance();
RawFileBuildPipeline pipeline = new RawFileBuildPipeline();
var buildResult = pipeline.Run(buildParameters, true);
if (buildResult.Success)
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
}
}
}
#endif

View File

@@ -0,0 +1,14 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
<ui:VisualElement name="BuildContainer">
<ui:TextField picking-mode="Ignore" label="Build Output" name="BuildOutput" />
<ui:TextField picking-mode="Ignore" label="Build Version" name="BuildVersion" />
<ui:Toggle label="Clear Build Cache" name="ClearBuildCache" />
<ui:Toggle label="Use Asset Depend DB" name="UseAssetDependency" />
<ui:VisualElement name="EncryptionContainer" style="height: 24px;" />
<uie:EnumField label="File Name Style" value="Center" name="FileNameStyle" />
<uie:EnumField label="Copy Buildin File Option" value="Center" name="CopyBuildinFileOption" />
<ui:TextField picking-mode="Ignore" label="Copy Buildin File Param" name="CopyBuildinFileParam" />
<ui:VisualElement name="ExtensionContainer" />
<ui:Button text="Click Build" display-tooltip-when-elided="true" name="Build" style="height: 50px; background-color: rgb(40, 106, 42); margin-top: 10px;" />
</ui:VisualElement>
</ui:UXML>

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 8ed3387ab250c814e9797164c9a4b89a
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}

View File

@@ -1,56 +0,0 @@
#if UNITY_2019_4_OR_NEWER
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
internal class RawfileBuildpipelineViewer : BuildPipelineViewerBase
{
public RawfileBuildpipelineViewer(string packageName, BuildTarget buildTarget, VisualElement parent)
: base(packageName, EBuildPipeline.RawFileBuildPipeline, buildTarget, parent)
{
var compressionField = Root.Q<EnumField>("Compression");
UIElementsTools.SetElementVisible(compressionField, false);
}
/// <summary>
/// 执行构建
/// </summary>
protected override void ExecuteBuild()
{
var fileNameStyle = AssetBundleBuilderSetting.GetPackageFileNameStyle(PackageName, BuildPipeline);
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, BuildPipeline);
var buildinFileCopyParams = AssetBundleBuilderSetting.GetPackageBuildinFileCopyParams(PackageName, BuildPipeline);
var clearBuildCache = AssetBundleBuilderSetting.GetPackageClearBuildCache(PackageName, BuildPipeline);
var useAssetDependencyDB = AssetBundleBuilderSetting.GetPackageUseAssetDependencyDB(PackageName, BuildPipeline);
RawFileBuildParameters buildParameters = new RawFileBuildParameters();
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = BuildPipeline.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.RawBundle;
buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = GetPackageVersion();
buildParameters.VerifyBuildingResult = true;
buildParameters.FileNameStyle = fileNameStyle;
buildParameters.BuildinFileCopyOption = buildinFileCopyOption;
buildParameters.BuildinFileCopyParams = buildinFileCopyParams;
buildParameters.ClearBuildCacheFiles = clearBuildCache;
buildParameters.UseAssetDependencyDB = useAssetDependencyDB;
buildParameters.EncryptionServices = CreateEncryptionInstance();
RawFileBuildPipeline pipeline = new RawFileBuildPipeline();
var buildResult = pipeline.Run(buildParameters, true);
if (buildResult.Success)
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,141 @@
#if UNITY_2019_4_OR_NEWER
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
[BuildPipelineAttribute(nameof(EBuildPipeline.ScriptableBuildPipeline))]
internal class ScriptableBuildPipelineViewer : BuildPipelineViewerBase
{
protected TemplateContainer Root;
protected TextField _buildOutputField;
protected TextField _buildVersionField;
protected PopupField<Type> _encryptionField;
protected EnumField _compressionField;
protected EnumField _outputNameStyleField;
protected EnumField _copyBuildinFileOptionField;
protected TextField _copyBuildinFileTagsField;
protected Toggle _clearBuildCacheToggle;
protected Toggle _useAssetDependencyDBToggle;
public override void CreateView(VisualElement parent)
{
// 加载布局文件
var visualAsset = UxmlLoader.LoadWindowUXML<ScriptableBuildPipelineViewer>();
if (visualAsset == null)
return;
Root = visualAsset.CloneTree();
Root.style.flexGrow = 1f;
parent.Add(Root);
// 输出目录
_buildOutputField = Root.Q<TextField>("BuildOutput");
SetBuildOutputField(_buildOutputField);
// 构建版本
_buildVersionField = Root.Q<TextField>("BuildVersion");
SetBuildVersionField(_buildVersionField);
// 加密方法
var encryptionContainer = Root.Q("EncryptionContainer");
_encryptionField = CreateEncryptionField(encryptionContainer);
// 压缩方式选项
_compressionField = Root.Q<EnumField>("Compression");
SetCompressionField(_compressionField);
// 输出文件名称样式
_outputNameStyleField = Root.Q<EnumField>("FileNameStyle");
SetOutputNameStyleField(_outputNameStyleField);
// 首包文件拷贝参数
_copyBuildinFileTagsField = Root.Q<TextField>("CopyBuildinFileParam");
SetCopyBuildinFileTagsField(_copyBuildinFileTagsField);
// 首包文件拷贝选项
_copyBuildinFileOptionField = Root.Q<EnumField>("CopyBuildinFileOption");
SetCopyBuildinFileOptionField(_copyBuildinFileOptionField, _copyBuildinFileTagsField);
// 清理构建缓存
_clearBuildCacheToggle = Root.Q<Toggle>("ClearBuildCache");
SetClearBuildCacheToggle(_clearBuildCacheToggle);
// 使用资源依赖数据库
_useAssetDependencyDBToggle = Root.Q<Toggle>("UseAssetDependency");
SetUseAssetDependencyDBToggle(_useAssetDependencyDBToggle);
// 构建按钮
var buildButton = Root.Q<Button>("Build");
buildButton.clicked += BuildButton_clicked;
}
private void BuildButton_clicked()
{
if (EditorUtility.DisplayDialog("提示", $"开始构建资源包[{PackageName}]", "Yes", "No"))
{
EditorTools.ClearUnityConsole();
EditorApplication.delayCall += ExecuteBuild;
}
else
{
Debug.LogWarning("[Build] 打包已经取消");
}
}
/// <summary>
/// 执行构建
/// </summary>
protected virtual void ExecuteBuild()
{
var fileNameStyle = AssetBundleBuilderSetting.GetPackageFileNameStyle(PackageName, PipelineName);
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, PipelineName);
var buildinFileCopyParams = AssetBundleBuilderSetting.GetPackageBuildinFileCopyParams(PackageName, PipelineName);
var compressOption = AssetBundleBuilderSetting.GetPackageCompressOption(PackageName, PipelineName);
var clearBuildCache = AssetBundleBuilderSetting.GetPackageClearBuildCache(PackageName, PipelineName);
var useAssetDependencyDB = AssetBundleBuilderSetting.GetPackageUseAssetDependencyDB(PackageName, PipelineName);
var builtinShaderBundleName = GetBuiltinShaderBundleName();
ScriptableBuildParameters buildParameters = new ScriptableBuildParameters();
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = PipelineName.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.AssetBundle;
buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = _buildVersionField.value;
buildParameters.EnableSharePackRule = true;
buildParameters.VerifyBuildingResult = true;
buildParameters.FileNameStyle = fileNameStyle;
buildParameters.BuildinFileCopyOption = buildinFileCopyOption;
buildParameters.BuildinFileCopyParams = buildinFileCopyParams;
buildParameters.CompressOption = compressOption;
buildParameters.ClearBuildCacheFiles = clearBuildCache;
buildParameters.UseAssetDependencyDB = useAssetDependencyDB;
buildParameters.BuiltinShadersBundleName = builtinShaderBundleName;
buildParameters.EncryptionServices = CreateEncryptionInstance();
ScriptableBuildPipeline pipeline = new ScriptableBuildPipeline();
var buildResult = pipeline.Run(buildParameters, true);
if (buildResult.Success)
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
}
/// <summary>
/// 内置着色器资源包名称
/// 注意:和自动收集的着色器资源包名保持一致!
/// </summary>
protected string GetBuiltinShaderBundleName()
{
var uniqueBundleName = AssetBundleCollectorSettingData.Setting.UniqueBundleName;
var packRuleResult = DefaultPackRule.CreateShadersPackRuleResult();
return packRuleResult.GetBundleName(PackageName, uniqueBundleName);
}
}
}
#endif

View File

@@ -0,0 +1,15 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
<ui:VisualElement name="BuildContainer">
<ui:TextField picking-mode="Ignore" label="Build Output" name="BuildOutput" />
<ui:TextField picking-mode="Ignore" label="Build Version" name="BuildVersion" />
<ui:Toggle label="Clear Build Cache" name="ClearBuildCache" />
<ui:Toggle label="Use Asset Depend DB" name="UseAssetDependency" />
<ui:VisualElement name="EncryptionContainer" style="height: 24px;" />
<uie:EnumField label="Compression" value="Center" name="Compression" />
<uie:EnumField label="File Name Style" value="Center" name="FileNameStyle" />
<uie:EnumField label="Copy Buildin File Option" value="Center" name="CopyBuildinFileOption" />
<ui:TextField picking-mode="Ignore" label="Copy Buildin File Param" name="CopyBuildinFileParam" />
<ui:VisualElement name="ExtensionContainer" />
<ui:Button text="Click Build" display-tooltip-when-elided="true" name="Build" style="height: 50px; background-color: rgb(40, 106, 42); margin-top: 10px;" />
</ui:VisualElement>
</ui:UXML>

View File

@@ -1,70 +0,0 @@
#if UNITY_2019_4_OR_NEWER
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
internal class ScriptableBuildPipelineViewer : BuildPipelineViewerBase
{
public ScriptableBuildPipelineViewer(string packageName, BuildTarget buildTarget, VisualElement parent)
: base(packageName, EBuildPipeline.ScriptableBuildPipeline, buildTarget, parent)
{
}
/// <summary>
/// 执行构建
/// </summary>
protected override void ExecuteBuild()
{
var fileNameStyle = AssetBundleBuilderSetting.GetPackageFileNameStyle(PackageName, BuildPipeline);
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, BuildPipeline);
var buildinFileCopyParams = AssetBundleBuilderSetting.GetPackageBuildinFileCopyParams(PackageName, BuildPipeline);
var compressOption = AssetBundleBuilderSetting.GetPackageCompressOption(PackageName, BuildPipeline);
var clearBuildCache = AssetBundleBuilderSetting.GetPackageClearBuildCache(PackageName, BuildPipeline);
var useAssetDependencyDB = AssetBundleBuilderSetting.GetPackageUseAssetDependencyDB(PackageName, BuildPipeline);
var builtinShaderBundleName = GetBuiltinShaderBundleName();
ScriptableBuildParameters buildParameters = new ScriptableBuildParameters();
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot();
buildParameters.BuildPipeline = BuildPipeline.ToString();
buildParameters.BuildBundleType = (int)EBuildBundleType.AssetBundle;
buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = GetPackageVersion();
buildParameters.EnableSharePackRule = true;
buildParameters.VerifyBuildingResult = true;
buildParameters.FileNameStyle = fileNameStyle;
buildParameters.BuildinFileCopyOption = buildinFileCopyOption;
buildParameters.BuildinFileCopyParams = buildinFileCopyParams;
buildParameters.CompressOption = compressOption;
buildParameters.ClearBuildCacheFiles = clearBuildCache;
buildParameters.UseAssetDependencyDB = useAssetDependencyDB;
buildParameters.BuiltinShadersBundleName = builtinShaderBundleName;
buildParameters.EncryptionServices = CreateEncryptionInstance();
ScriptableBuildPipeline pipeline = new ScriptableBuildPipeline();
var buildResult = pipeline.Run(buildParameters, true);
if (buildResult.Success)
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
}
/// <summary>
/// 内置着色器资源包名称
/// 注意:和自动收集的着色器资源包名保持一致!
/// </summary>
private string GetBuiltinShaderBundleName()
{
var uniqueBundleName = AssetBundleCollectorSettingData.Setting.UniqueBundleName;
var packRuleResult = DefaultPackRule.CreateShadersPackRuleResult();
return packRuleResult.GetBundleName(PackageName, uniqueBundleName);
}
}
}
#endif

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

@@ -265,7 +265,7 @@ namespace YooAsset.Editor
}
private static string GetRuleDisplayName(string name, Type type)
{
var attribute = DisplayNameAttributeHelper.GetAttribute<DisplayNameAttribute>(type);
var attribute = EditorTools.GetAttribute<DisplayNameAttribute>(type);
if (attribute != null && string.IsNullOrEmpty(attribute.DisplayName) == false)
return attribute.DisplayName;
else

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);
@@ -183,16 +187,30 @@ namespace YooAsset.Editor
}
var result = new HashSet<string> { assetPath };
CollectDependencies(assetPath, result, recursive);
CollectDependencies(assetPath, assetPath, result, recursive);
// 注意AssetDatabase.GetDependencies保持一致将主资源添加到依赖列表最前面
return result.ToArray();
}
private void CollectDependencies(string assetPath, HashSet<string> result, bool recursive)
private void CollectDependencies(string parent, string assetPath, HashSet<string> result, bool recursive)
{
if (_database.TryGetValue(assetPath, out var cacheInfo) == false)
{
throw new Exception($"Fatal : can not found cache info : {assetPath}");
// 说明:检测是否为丢失引用的资产
#if UNITY_2021_3_OR_NEWER
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath, AssetPathToGUIDOptions.OnlyExistingAssets);
#else
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
#endif
if (string.IsNullOrEmpty(assetGUID))
{
Debug.LogWarning($"{parent} found missing asset : {assetPath}");
return;
}
else
{
throw new Exception($"Fatal : can not found cache info : {assetPath}");
}
}
foreach (var dependGUID in cacheInfo.DependGUIDs)
@@ -213,7 +231,7 @@ namespace YooAsset.Editor
// 递归收集依赖
if (recursive)
CollectDependencies(dependAssetPath, result, recursive);
CollectDependencies(assetPath, dependAssetPath, result, recursive);
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Reflection;
namespace YooAsset.Editor
{
@@ -15,22 +14,4 @@ namespace YooAsset.Editor
this.DisplayName = name;
}
}
public static class DisplayNameAttributeHelper
{
internal static T GetAttribute<T>(Type type) where T : Attribute
{
return (T)type.GetCustomAttribute(typeof(T), false);
}
internal static T GetAttribute<T>(MethodInfo methodInfo) where T : Attribute
{
return (T)methodInfo.GetCustomAttribute(typeof(T), false);
}
internal static T GetAttribute<T>(FieldInfo field) where T : Attribute
{
return (T)field.GetCustomAttribute(typeof(T), false);
}
}
}

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

@@ -129,6 +129,23 @@ namespace YooAsset.Editor
}
#endregion
#region Attribute
public static T GetAttribute<T>(Type type) where T : Attribute
{
return (T)type.GetCustomAttribute(typeof(T), false);
}
public static T GetAttribute<T>(MethodInfo methodInfo) where T : Attribute
{
return (T)methodInfo.GetCustomAttribute(typeof(T), false);
}
public static T GetAttribute<T>(FieldInfo field) where T : Attribute
{
return (T)field.GetCustomAttribute(typeof(T), false);
}
#endregion
#region PackageManager
public static string GetPackageManagerYooVersion()
{

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

@@ -67,7 +67,9 @@ namespace YooAsset
}
#elif UNITY_STANDALONE_OSX
url = new System.Uri(path).ToString();
#elif UNITY_STANDALONE
#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();

View File

@@ -58,6 +58,11 @@ namespace YooAsset
/// </summary>
public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
/// <summary>
/// 自定义参数:覆盖安装缓存清理模式
/// </summary>
public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles;
/// <summary>
/// 自定义参数:数据文件追加文件格式
/// </summary>
@@ -104,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)
{
@@ -145,6 +150,10 @@ namespace YooAsset
{
FileVerifyLevel = (EFileVerifyLevel)value;
}
else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE)
{
InstallClearMode = (EOverwriteInstallClearMode)value;
}
else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION)
{
AppendFileExtension = Convert.ToBoolean(value);
@@ -184,6 +193,7 @@ namespace YooAsset
_unpackFileSystem = new DefaultUnpackFileSystem();
_unpackFileSystem.SetParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.INSTALL_CLEAR_MODE, InstallClearMode);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, AppendFileExtension);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, DecryptionServices);
_unpackFileSystem.OnCreate(packageName, null);

View File

@@ -69,8 +69,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result);
if (fileHash == _packageHash)
if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
{
_steps = ESteps.LoadManifest;
}

View File

@@ -65,6 +65,11 @@ namespace YooAsset
/// </summary>
public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
/// <summary>
/// 自定义参数:覆盖安装缓存清理模式
/// </summary>
public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles;
/// <summary>
/// 自定义参数:数据文件追加文件格式
/// </summary>
@@ -115,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(); //增加下载器的引用计数
// 注意:将下载器进行包裹,可以避免父类任务终止的时候,连带子任务里的下载器也一起被终止!
@@ -188,6 +193,10 @@ namespace YooAsset
{
FileVerifyLevel = (EFileVerifyLevel)value;
}
else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE)
{
InstallClearMode = (EOverwriteInstallClearMode)value;
}
else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION)
{
AppendFileExtension = Convert.ToBoolean(value);
@@ -227,8 +236,8 @@ namespace YooAsset
_packageRoot = packageRoot;
_cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.BundleFilesFolderName);
_tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
_cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.ManifestFilesFolderName);
_tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
}
public virtual void OnDestroy()
{
@@ -500,7 +509,18 @@ namespace YooAsset
}
/// <summary>
/// 删除所有清单文件
/// 删除所有缓存的资源文件
/// </summary>
public void DeleteAllBundleFiles()
{
if (Directory.Exists(_cacheBundleFilesRoot))
{
Directory.Delete(_cacheBundleFilesRoot, true);
}
}
/// <summary>
/// 删除所有缓存的清单文件
/// </summary>
public void DeleteAllManifestFiles()
{
@@ -539,6 +559,21 @@ namespace YooAsset
};
return DecryptionServices.LoadAssetBundleAsync(fileInfo);
}
/// <summary>
/// 加载加密资源文件
/// </summary>
public DecryptResult LoadEncryptedAssetBundleFallback(PackageBundle bundle)
{
string filePath = GetCacheBundleFileLoadPath(bundle);
var fileInfo = new DecryptFileInfo()
{
BundleName = bundle.BundleName,
FileLoadCRC = bundle.UnityCRC,
FileLoadPath = filePath,
};
return DecryptionServices.LoadAssetBundleFallback(fileInfo);
}
#endregion
}
}

View File

@@ -0,0 +1,29 @@

namespace YooAsset
{
/// <summary>
/// 覆盖安装清理模式
/// </summary>
public enum EOverwriteInstallClearMode
{
/// <summary>
/// 不做任何处理
/// </summary>
None = 0,
/// <summary>
/// 清理所有缓存文件(包含资源文件和清单文件)
/// </summary>
ClearAllCacheFiles = 1,
/// <summary>
/// 清理所有缓存的资源文件
/// </summary>
ClearAllBundleFiles = 2,
/// <summary>
/// 清理所有缓存的清单文件
/// </summary>
ClearAllManifestFiles = 3,
}
}

View File

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

View File

@@ -46,9 +46,32 @@ namespace YooAsset
// 如果水印发生变化,则说明覆盖安装后首次打开游戏
if (appFootPrint.IsDirty())
{
_fileSystem.DeleteAllManifestFiles();
if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.None)
{
YooLogger.Warning("Do nothing when overwrite install application !");
}
else if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.ClearAllCacheFiles)
{
_fileSystem.DeleteAllBundleFiles();
_fileSystem.DeleteAllManifestFiles();
YooLogger.Warning("Delete all cache files when overwrite install application !");
}
else if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.ClearAllBundleFiles)
{
_fileSystem.DeleteAllBundleFiles();
YooLogger.Warning("Delete all bundle files when overwrite install application !");
}
else if (_fileSystem.InstallClearMode == EOverwriteInstallClearMode.ClearAllManifestFiles)
{
_fileSystem.DeleteAllManifestFiles();
YooLogger.Warning("Delete all manifest files when overwrite install application !");
}
else
{
throw new System.NotImplementedException(_fileSystem.InstallClearMode.ToString());
}
appFootPrint.Coverage(_fileSystem.PackageName);
YooLogger.Warning("Delete manifest files when application foot print dirty !");
}
_steps = ESteps.SearchCacheFiles;

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);
}
@@ -164,11 +164,23 @@ namespace YooAsset
{
if (_bundle.Encrypted)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to load encrypted asset bundle file : {_bundle.BundleName}";
YooLogger.Error(Error);
return;
var decryptResult = _fileSystem.LoadEncryptedAssetBundleFallback(_bundle);
_assetBundle = decryptResult.Result;
if (_assetBundle != null)
{
_steps = ESteps.Done;
Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, _managedStream);
Status = EOperationStatus.Succeed;
return;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Failed to load encrypted asset bundle file : {_bundle.BundleName}";
YooLogger.Error(Error);
return;
}
}
// 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。
@@ -297,8 +309,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

@@ -59,8 +59,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesCRC32(_fileData);
if (fileHash == _packageHash)
if (ManifestTools.VerifyManifestData(_fileData, _packageHash))
{
_steps = ESteps.LoadManifest;
}

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

@@ -59,8 +59,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesCRC32(_fileData);
if (fileHash == _packageHash)
if (ManifestTools.VerifyManifestData(_fileData, _packageHash))
{
_steps = ESteps.LoadManifest;
}

View File

@@ -14,7 +14,8 @@ namespace YooAsset
base.OnCreate(packageName, rootDirectory);
// 注意:重写保存根目录和临时目录
_cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.SaveFilesFolderName);
_cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.SaveBundleFilesFolderName);
_cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.SaveManifestFilesFolderName);
_tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.TempFilesFolderName);
}
}

View File

@@ -11,8 +11,13 @@ namespace YooAsset
/// <summary>
/// 保存的资源文件的文件夹名称
/// </summary>
public const string SaveFilesFolderName = "UnpackFiles";
public const string SaveBundleFilesFolderName = "UnpackBundleFiles";
/// <summary>
/// 保存的清单文件的文件夹名称
/// </summary>
public const string SaveManifestFilesFolderName = "UnpackManifestFiles";
/// <summary>
/// 下载的临时文件的文件夹名称
/// </summary>

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

@@ -72,8 +72,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result);
if (fileHash == _packageHash)
if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
{
_steps = ESteps.LoadManifest;
}

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

@@ -69,8 +69,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result);
if (fileHash == _packageHash)
if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
{
_steps = ESteps.LoadManifest;
}

View File

@@ -4,6 +4,7 @@ namespace YooAsset
public class FileSystemParametersDefine
{
public const string FILE_VERIFY_LEVEL = "FILE_VERIFY_LEVEL";
public const string INSTALL_CLEAR_MODE = "INSTALL_CLEAR_MODE";
public const string REMOTE_SERVICES = "REMOTE_SERVICES";
public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES";
public const string APPEND_FILE_EXTENSION = "APPEND_FILE_EXTENSION";

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,6 +38,10 @@ namespace YooAsset
/// </summary>
public abstract class InitializeParameters
{
/// <summary>
/// 同时加载Bundle文件的最大并发数
/// </summary>
public int BundleLoadingMaxConcurrency = int.MaxValue;
}
/// <summary>

View File

@@ -9,7 +9,8 @@ namespace YooAsset
private enum ESteps
{
None,
LoadFile,
CheckConcurrency,
LoadBundleFile,
Done,
}
@@ -57,17 +58,32 @@ namespace YooAsset
}
internal override void InternalStart()
{
_steps = ESteps.LoadFile;
_steps = ESteps.CheckConcurrency;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadFile)
if (_steps == ESteps.CheckConcurrency)
{
if (IsWaitForAsyncComplete)
{
_steps = ESteps.LoadBundleFile;
}
else
{
if (_resourceManager.BundleLoadingIsBusy())
return;
_steps = ESteps.LoadBundleFile;
}
}
if (_steps == ESteps.LoadBundleFile)
{
if (_loadBundleOp == null)
{
_resourceManager.BundleLoadingCounter++;
_loadBundleOp = LoadBundleInfo.LoadBundleFile();
_loadBundleOp.StartOperation();
AddChildOperation(_loadBundleOp);
@@ -103,6 +119,9 @@ namespace YooAsset
Status = EOperationStatus.Failed;
Error = _loadBundleOp.Error;
}
// 统计计数减少
_resourceManager.BundleLoadingCounter--;
}
}
internal override void InternalWaitForAsyncComplete()

View File

@@ -15,6 +15,7 @@ namespace YooAsset
private readonly ResourceManager _resManager;
private readonly int _loopCount;
private int _loopCounter = 0;
private ESteps _steps = ESteps.None;
internal UnloadUnusedAssetsOperation(ResourceManager resourceManager, int loopCount)
@@ -25,6 +26,7 @@ namespace YooAsset
internal override void InternalStart()
{
_steps = ESteps.UnloadUnused;
_loopCounter = _loopCount;
}
internal override void InternalUpdate()
{
@@ -33,13 +35,23 @@ namespace YooAsset
if (_steps == ESteps.UnloadUnused)
{
for (int i = 0; i < _loopCount; i++)
while (_loopCounter > 0)
{
_loopCounter--;
LoopUnloadUnused();
if (IsWaitForAsyncComplete == false)
{
if (OperationSystem.IsBusy)
break;
}
}
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
if (_loopCounter <= 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
internal override void InternalWaitForAsyncComplete()

View File

@@ -14,6 +14,7 @@ namespace YooAsset
internal readonly List<SceneHandle> SceneHandles = new List<SceneHandle>(100);
private long _sceneCreateIndex = 0;
private IBundleQuery _bundleQuery;
private int _bundleLoadingMaxConcurrency;
/// <summary>
/// 所属包裹
@@ -25,6 +26,11 @@ namespace YooAsset
/// </summary>
public bool LockLoadOperation = false;
/// <summary>
/// 统计正在加载的Bundle文件数量
/// </summary>
public int BundleLoadingCounter = 0;
public ResourceManager(string packageName)
{
@@ -34,8 +40,9 @@ namespace YooAsset
/// <summary>
/// 初始化
/// </summary>
public void Initialize(IBundleQuery bundleServices)
public void Initialize(InitializeParameters parameters, IBundleQuery bundleServices)
{
_bundleLoadingMaxConcurrency = parameters.BundleLoadingMaxConcurrency;
_bundleQuery = bundleServices;
SceneManager.sceneUnloaded += OnSceneUnloaded;
}
@@ -310,6 +317,10 @@ namespace YooAsset
{
return LoaderDic.Count > 0;
}
internal bool BundleLoadingIsBusy()
{
return BundleLoadingCounter >= _bundleLoadingMaxConcurrency;
}
private LoadBundleFileOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo)
{

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

@@ -8,6 +8,30 @@ namespace YooAsset
{
internal static class ManifestTools
{
/// <summary>
/// 验证清单文件的二进制数据
/// </summary>
public static bool VerifyManifestData(byte[] fileData, string hashValue)
{
if (fileData == null || fileData.Length == 0)
return false;
if (string.IsNullOrEmpty(hashValue))
return false;
// 注意:兼容俩种验证方式
// 注意计算MD5的哈希值通常为32个字符
string fileHash;
if (hashValue.Length == 32)
fileHash = HashUtility.BytesMD5(fileData);
else
fileHash = HashUtility.BytesCRC32(fileData);
if (fileHash == hashValue)
return true;
else
return false;
}
/// <summary>
/// 序列化JSON文件
/// </summary>
@@ -197,9 +221,16 @@ namespace YooAsset
manifest.AssetDic = new Dictionary<string, PackageAsset>(assetCount);
if (manifest.EnableAddressable)
{
manifest.AssetPathMapping1 = new Dictionary<string, string>(assetCount * 3);
}
else
manifest.AssetPathMapping1 = new Dictionary<string, string>(assetCount * 2);
{
if (manifest.LocationToLower)
manifest.AssetPathMapping1 = new Dictionary<string, string>(assetCount * 2, StringComparer.OrdinalIgnoreCase);
else
manifest.AssetPathMapping1 = new Dictionary<string, string>(assetCount * 2);
}
if (manifest.IncludeAssetGUID)
manifest.AssetPathMapping2 = new Dictionary<string, string>(assetCount);
@@ -221,8 +252,6 @@ namespace YooAsset
// 填充AssetPathMapping1
{
string location = packageAsset.AssetPath;
if (manifest.LocationToLower)
location = location.ToLower();
// 添加原生路径的映射
if (manifest.AssetPathMapping1.ContainsKey(location))
@@ -285,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

@@ -138,9 +138,6 @@ namespace YooAsset
if (string.IsNullOrEmpty(location))
return string.Empty;
if (LocationToLower)
location = location.ToLower();
if (AssetPathMapping1.TryGetValue(location, out string assetPath))
return assetPath;
else
@@ -307,9 +304,6 @@ namespace YooAsset
return string.Empty;
}
if (LocationToLower)
location = location.ToLower();
if (AssetPathMapping1.TryGetValue(location, out string assetPath))
{
return assetPath;

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

@@ -100,7 +100,7 @@ namespace YooAsset
var playModeImpl = new PlayModeImpl(PackageName, _playMode);
_bundleQuery = playModeImpl;
_playModeImpl = playModeImpl;
_resourceManager.Initialize(_bundleQuery);
_resourceManager.Initialize(parameters, _bundleQuery);
// 初始化资源系统
InitializationOperation initializeOperation;
@@ -162,6 +162,10 @@ namespace YooAsset
throw new Exception($"Editor simulate mode only support unity editor.");
#endif
// 检测初始化参数
if (parameters.BundleLoadingMaxConcurrency <= 0)
throw new Exception($"{nameof(parameters.BundleLoadingMaxConcurrency)} value must be greater than zero.");
// 鉴定运行模式
if (parameters is EditorSimulateModeParameters)
_playMode = EPlayMode.EditorSimulateMode;
@@ -264,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;
}
@@ -277,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;
}

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