Compare commits

...

90 Commits

Author SHA1 Message Date
何冠峰
53163a75ae Update CHANGELOG.md 2025-07-01 16:46:10 +08:00
何冠峰
273401cb20 Update package.json 2025-07-01 16:45:50 +08:00
何冠峰
97fe3b0681 update file system
修正2.3.11版本同步加载本地加密文件失败的问题。
2025-07-01 16:40:01 +08:00
何冠峰
d401086fd1 update test sample 2025-07-01 15:32:44 +08:00
何冠峰
e3a12ef361 style : file system code style 2025-07-01 11:06:41 +08:00
何冠峰
1b0288fcd0 update mini game
微信小游戏和抖音小游戏支持资源清单加密。
2025-06-30 16:19:59 +08:00
何冠峰
3ee94fb3b9 update extension sample 2025-06-30 15:43:47 +08:00
何冠峰
a0ea80c158 Update CHANGELOG.md 2025-06-30 12:06:30 +08:00
何冠峰
264415b362 Update package.json 2025-06-30 12:06:07 +08:00
何冠峰
6a76d44c38 update test sample 2025-06-30 11:30:56 +08:00
何冠峰
cebfd57851 update test sample 2025-06-30 11:22:38 +08:00
何冠峰
60eb1c3522 update test sample
修正单元测试失败
2025-06-30 11:07:46 +08:00
何冠峰
40c82835bf style : code style 2025-06-30 10:53:16 +08:00
何冠峰
a13913f572 Merge pull request #582 from hhmmLife/dev
fix: 只有递归收集依赖时,依赖列表中才默认包含主资源
2025-06-30 10:47:28 +08:00
何冠峰
150b46a0a7 update file system
新增ICopyLocalFileServices服务类
2025-06-27 17:42:57 +08:00
何冠峰
ebde5a52d3 fix #585 2025-06-25 19:27:52 +08:00
何冠峰
e57466e9e2 style : file system code 2025-06-25 18:12:37 +08:00
何冠峰
6f7fca7b34 perf : main thread sleep one 2025-06-25 18:10:50 +08:00
何冠峰
756331fe0b style : file system code 2025-06-25 18:04:53 +08:00
何冠峰
5139e2f3a7 update extension sample 2025-06-23 18:57:48 +08:00
hhmmLife
1c4aba6db5 fix: 只有递归收集依赖时,依赖列表中才默认包含主资源 2025-06-23 00:56:50 +08:00
何冠峰
44faa0c5e6 fix #572
修复了资源收集页面指定收集的预制体名称变动的问题。
2025-06-20 17:55:51 +08:00
何冠峰
72c97341b1 fix #579 2025-06-20 14:03:12 +08:00
何冠峰
9acc240b5a update extension sample 2025-06-20 11:36:56 +08:00
何冠峰
ed89e73d26 fix #576
资源清单加密和解密
2025-06-20 11:36:29 +08:00
何冠峰
9e33df0375 style :services code 2025-06-20 11:29:22 +08:00
何冠峰
6c98f9a09d update resource manager
新增初始化参数:WebGLForceSyncLoadAsset
2025-06-18 11:12:42 +08:00
何冠峰
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
何冠峰
974493f88d Update CHANGELOG.md 2025-03-25 11:15:56 +08:00
何冠峰
69a69988a1 Update package.json 2025-03-25 11:15:24 +08:00
246 changed files with 4017 additions and 957 deletions

View File

@@ -2,6 +2,221 @@
All notable changes to this package will be documented in this file. All notable changes to this package will be documented in this file.
## [2.3.12] - 2025-07-01
### Improvements
- 优化了同步接口导致的资源拷贝和资源验证性能开销高的现象。
- 微信小游戏和抖音小游戏支持资源清单加密。
### Fixed
- (#579) 修复了2.3.10版本资源包构建页面里CopyBuildinFileParam无法编辑问题。
- (#572) 修复了资源收集页面指定收集的预制体名称变动的问题。
- (#582) 修复了非递归收集依赖时,依赖列表中才包含主资源的问题。
### Added
- 新增初始化参数WebGLForceSyncLoadAsset
```csharp
public abstract class InitializeParameters
{
/// <summary>
/// WebGL平台强制同步加载资源对象
/// </summary>Add commentMore actions
public bool WebGLForceSyncLoadAsset = false;
}
```
- (#576) 新增了资源清单服务类IManifestServices
```csharp
/// <summary>
/// 资源清单文件处理服务接口
/// </summary>
public interface IManifestServices
{
/// <summary>
/// 处理资源清单(压缩和加密)
/// </summary>
byte[] ProcessManifest(byte[] fileData);
/// <summary>
/// 还原资源清单(解压和解密)
/// </summary>
byte[] RestoreManifest(byte[] fileData);
}
```
- (#585) 新增了本地文件拷贝服务类ICopyLocalFileServices
```csharp
/// <summary>
/// 本地文件拷贝服务类
/// </summary>
public interface ICopyLocalFileServices
{
void CopyFile(LocalFileInfo sourceFileInfo, string destFilePath);
}
```
## [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
- 构建管线新增了TaskCreateCatalog任务节点。
- 内置文件系统的catalog文件现在存储在streammingAssets目录下。
### Fixed
- (#486) 修复了微信小游戏文件系统调用ClearUnusedBundleFiles时候的异常。
## [2.3.5-preview] - 2025-03-14 ## [2.3.5-preview] - 2025-03-14
### Fixed ### Fixed

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 fileFormatVersion: 2
guid: 56ea224b45d314e4a86b558404e9b6c8 guid: ef774f01e50ab0a4d88122041938a6b9
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

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

View File

@@ -5,6 +5,7 @@ using System.Text;
using System.Xml; using System.Xml;
using UnityEditor; using UnityEditor;
#if YOO_ASSET_EXPERIMENT
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
[InitializeOnLoad] [InitializeOnLoad]
@@ -22,13 +23,21 @@ namespace YooAsset.Editor
return content; return content;
// 将修改后的XML结构重新输出为文本 // 将修改后的XML结构重新输出为文本
var stringWriter = new StringWriter(); using (var memoryStream = new MemoryStream())
var writerSettings = new XmlWriterSettings(); {
writerSettings.Indent = true; var writerSettings = new XmlWriterSettings
var xmlWriter = XmlWriter.Create(stringWriter, writerSettings); {
xmlDoc.WriteTo(xmlWriter); Indent = true,
xmlWriter.Flush(); Encoding = new UTF8Encoding(false), //无BOM
return stringWriter.ToString(); OmitXmlDeclaration = false
};
using (var xmlWriter = XmlWriter.Create(memoryStream, writerSettings))
{
xmlDoc.Save(xmlWriter);
}
return Encoding.UTF8.GetString(memoryStream.ToArray());
}
} }
/// <summary> /// <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() private void ImportSingleBtn_clicked()
{ {
string selectFilePath = EditorUtility.OpenFilePanel("导入报告", _lastestOpenFolder, "json"); string selectFilePath = EditorUtility.OpenFilePanel("导入报告", _lastestOpenFolder, "json");
@@ -446,15 +472,31 @@ namespace YooAsset.Editor
var column = new TableColumn(header.HeaderTitle, header.HeaderTitle, columnStyle); var column = new TableColumn(header.HeaderTitle, header.HeaderTitle, columnStyle);
column.MakeCell = () => column.MakeCell = () =>
{ {
var label = new Label(); if (header.HeaderType == EHeaderType.AssetObject)
label.style.marginLeft = 3f; {
label.style.unityTextAlign = TextAnchor.MiddleLeft; var objectFiled = new ObjectField();
return label; 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) => column.BindCell = (VisualElement element, ITableData data, ITableCell cell) =>
{ {
var infoLabel = element as Label; if (header.HeaderType == EHeaderType.AssetObject)
infoLabel.text = (string)cell.GetDisplayObject(); {
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); _elementTableView.AddColumn(column);
} }
@@ -480,6 +522,10 @@ namespace YooAsset.Editor
{ {
tableData.AddAssetPathCell(scanInfo.HeaderTitle, scanInfo.ScanInfo); tableData.AddAssetPathCell(scanInfo.HeaderTitle, scanInfo.ScanInfo);
} }
else if (header.HeaderType == EHeaderType.AssetObject)
{
tableData.AddAssetObjectCell(scanInfo.HeaderTitle, scanInfo.ScanInfo);
}
else if (header.HeaderType == EHeaderType.StringValue) else if (header.HeaderType == EHeaderType.StringValue)
{ {
tableData.AddStringValueCell(scanInfo.HeaderTitle, scanInfo.ScanInfo); tableData.AddStringValueCell(scanInfo.HeaderTitle, scanInfo.ScanInfo);

View File

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

View File

@@ -126,6 +126,12 @@ namespace YooAsset.Editor
if (string.IsNullOrEmpty(guid)) if (string.IsNullOrEmpty(guid))
throw new Exception($"{HeaderTitle} value is invalid asset path : {value}"); 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) else if (HeaderType == EHeaderType.DoubleValue)
{ {
if (double.TryParse(value, out double doubleValue) == false) if (double.TryParse(value, out double doubleValue) == false)

View File

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

View File

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

View File

@@ -32,8 +32,9 @@ namespace YooAsset.Editor
var buildParametersContext = new BuildParametersContext(buildParameters); var buildParametersContext = new BuildParametersContext(buildParameters);
_buildContext.SetContextObject(buildParametersContext); _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}"); BuildLogger.Log($"Begin to build package : {buildParameters.PackageName} by {buildParameters.BuildPipeline}");
@@ -50,6 +51,9 @@ namespace YooAsset.Editor
BuildLogger.Error(buildResult.ErrorInfo); BuildLogger.Error(buildResult.ErrorInfo);
} }
// 关闭日志系统
BuildLogger.Shuntdown();
return buildResult; return buildResult;
} }
} }

View File

@@ -6,97 +6,110 @@ namespace YooAsset.Editor
{ {
public static class AssetBundleBuilderSetting public static class AssetBundleBuilderSetting
{ {
// EBuildPipeline // BuildPipelineName
public static EBuildPipeline GetPackageBuildPipeline(string packageName) public static string GetPackageBuildPipeline(string packageName)
{ {
string key = $"{Application.productName}_{packageName}_{nameof(EBuildPipeline)}"; string key = $"{Application.productName}_{packageName}_BuildPipelineName";
return (EBuildPipeline)EditorPrefs.GetInt(key, (int)EBuildPipeline.BuiltinBuildPipeline); 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)}"; string key = $"{Application.productName}_{packageName}_BuildPipelineName";
EditorPrefs.SetInt(key, (int)buildPipeline); EditorPrefs.SetString(key, buildPipeline);
} }
// ECompressOption // 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)}"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(ECompressOption)}";
return (ECompressOption)EditorPrefs.GetInt(key, (int)ECompressOption.LZ4); 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)}"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(ECompressOption)}";
EditorPrefs.SetInt(key, (int)compressOption); EditorPrefs.SetInt(key, (int)compressOption);
} }
// EFileNameStyle // 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)}"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(EFileNameStyle)}";
return (EFileNameStyle)EditorPrefs.GetInt(key, (int)EFileNameStyle.HashName); 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)}"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(EFileNameStyle)}";
EditorPrefs.SetInt(key, (int)fileNameStyle); EditorPrefs.SetInt(key, (int)fileNameStyle);
} }
// EBuildinFileCopyOption // 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)}"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(EBuildinFileCopyOption)}";
return (EBuildinFileCopyOption)EditorPrefs.GetInt(key, (int)EBuildinFileCopyOption.None); 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)}"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(EBuildinFileCopyOption)}";
EditorPrefs.SetInt(key, (int)buildinFileCopyOption); EditorPrefs.SetInt(key, (int)buildinFileCopyOption);
} }
// BuildFileCopyParams // BuildFileCopyParams
public static string GetPackageBuildinFileCopyParams(string packageName, EBuildPipeline buildPipeline) public static string GetPackageBuildinFileCopyParams(string packageName, string buildPipeline)
{ {
string key = $"{Application.productName}_{packageName}_{buildPipeline}_BuildFileCopyParams"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_BuildFileCopyParams";
return EditorPrefs.GetString(key, string.Empty); 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"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_BuildFileCopyParams";
EditorPrefs.SetString(key, buildinFileCopyParams); EditorPrefs.SetString(key, buildinFileCopyParams);
} }
// EncyptionClassName // EncyptionServicesClassName
public static string GetPackageEncyptionClassName(string packageName, EBuildPipeline buildPipeline) public static string GetPackageEncyptionServicesClassName(string packageName, string buildPipeline)
{ {
string key = $"{Application.productName}_{packageName}_{buildPipeline}_EncyptionClassName"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_EncyptionServicesClassName";
return EditorPrefs.GetString(key, string.Empty); return EditorPrefs.GetString(key, $"{typeof(EncryptionNone).FullName}");
} }
public static void SetPackageEncyptionClassName(string packageName, EBuildPipeline buildPipeline, string encyptionClassName) public static void SetPackageEncyptionServicesClassName(string packageName, string buildPipeline, string encyptionClassName)
{ {
string key = $"{Application.productName}_{packageName}_{buildPipeline}_EncyptionClassName"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_EncyptionServicesClassName";
EditorPrefs.SetString(key, encyptionClassName);
}
// ManifestServicesClassName
public static string GetPackageManifestServicesClassName(string packageName, string buildPipeline)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_ManifestServicesClassName";
return EditorPrefs.GetString(key, $"{typeof(ManifestNone).FullName}");
}
public static void SetPackageManifestServicesClassName(string packageName, string buildPipeline, string encyptionClassName)
{
string key = $"{Application.productName}_{packageName}_{buildPipeline}_ManifestServicesClassName";
EditorPrefs.SetString(key, encyptionClassName); EditorPrefs.SetString(key, encyptionClassName);
} }
// ClearBuildCache // ClearBuildCache
public static bool GetPackageClearBuildCache(string packageName, EBuildPipeline buildPipeline) public static bool GetPackageClearBuildCache(string packageName, string buildPipeline)
{ {
string key = $"{Application.productName}_{packageName}_{buildPipeline}_ClearBuildCache"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_ClearBuildCache";
return EditorPrefs.GetInt(key, 0) > 0; 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"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_ClearBuildCache";
EditorPrefs.SetInt(key, clearBuildCache ? 1 : 0); EditorPrefs.SetInt(key, clearBuildCache ? 1 : 0);
} }
// UseAssetDependencyDB // UseAssetDependencyDB
public static bool GetPackageUseAssetDependencyDB(string packageName, EBuildPipeline buildPipeline) public static bool GetPackageUseAssetDependencyDB(string packageName, string buildPipeline)
{ {
string key = $"{Application.productName}_{packageName}_{buildPipeline}_UseAssetDependencyDB"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_UseAssetDependencyDB";
return EditorPrefs.GetInt(key, 0) > 0; 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"; string key = $"{Application.productName}_{packageName}_{buildPipeline}_UseAssetDependencyDB";
EditorPrefs.SetInt(key, useAssetDependencyDB ? 1 : 0); EditorPrefs.SetInt(key, useAssetDependencyDB ? 1 : 0);

View File

@@ -19,7 +19,9 @@ namespace YooAsset.Editor
} }
private string _buildPackage; private string _buildPackage;
private EBuildPipeline _buildPipeline; private string _buildPipeline;
private Dictionary<string, Type> _viewClassDic = new Dictionary<string, Type>(10);
private Toolbar _toolbar; private Toolbar _toolbar;
private ToolbarMenu _packageMenu; private ToolbarMenu _packageMenu;
@@ -69,11 +71,23 @@ namespace YooAsset.Editor
{ {
_pipelineMenu = new ToolbarMenu(); _pipelineMenu = new ToolbarMenu();
_pipelineMenu.style.width = 200; _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); _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(); RefreshBuildPipelineView();
@@ -91,28 +105,18 @@ namespace YooAsset.Editor
_buildPipeline = AssetBundleBuilderSetting.GetPackageBuildPipeline(_buildPackage); _buildPipeline = AssetBundleBuilderSetting.GetPackageBuildPipeline(_buildPackage);
_packageMenu.text = _buildPackage; _packageMenu.text = _buildPackage;
_pipelineMenu.text = _buildPipeline.ToString(); _pipelineMenu.text = _buildPipeline;
var buildTarget = EditorUserBuildSettings.activeBuildTarget; if (_viewClassDic.TryGetValue(_buildPipeline, out Type value))
if (_buildPipeline == EBuildPipeline.EditorSimulateBuildPipeline)
{ {
var viewer = new EditorSimulateBuildPipelineViewer(_buildPackage, buildTarget, _container); var buildTarget = EditorUserBuildSettings.activeBuildTarget;
} var viewer = Activator.CreateInstance(value) as BuildPipelineViewerBase;
else if (_buildPipeline == EBuildPipeline.BuiltinBuildPipeline) viewer.InitView(_buildPackage, _buildPipeline, buildTarget);
{ viewer.CreateView(_container);
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);
} }
else else
{ {
throw new System.NotImplementedException(_buildPipeline.ToString()); Debug.LogError($"Not found build pipeline : {_buildPipeline}");
} }
} }
private List<string> GetBuildPackageNames() private List<string> GetBuildPackageNames()
@@ -145,18 +149,16 @@ namespace YooAsset.Editor
private void PipelineMenuAction(DropdownMenuAction action) private void PipelineMenuAction(DropdownMenuAction action)
{ {
var pipelineType = (EBuildPipeline)action.userData; if (_buildPipeline != action.name)
if (_buildPipeline != pipelineType)
{ {
_buildPipeline = pipelineType; _buildPipeline = action.name;
AssetBundleBuilderSetting.SetPackageBuildPipeline(_buildPackage, pipelineType); AssetBundleBuilderSetting.SetPackageBuildPipeline(_buildPackage, _buildPipeline);
RefreshBuildPipelineView(); RefreshBuildPipelineView();
} }
} }
private DropdownMenuAction.Status PipelineMenuFun(DropdownMenuAction action) private DropdownMenuAction.Status PipelineMenuFun(DropdownMenuAction action)
{ {
var pipelineType = (EBuildPipeline)action.userData; if (_buildPipeline == action.name)
if (_buildPipeline == pipelineType)
return DropdownMenuAction.Status.Checked; return DropdownMenuAction.Status.Checked;
else else
return DropdownMenuAction.Status.Normal; return DropdownMenuAction.Status.Normal;

View File

@@ -98,6 +98,11 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public IEncryptionServices EncryptionServices; public IEncryptionServices EncryptionServices;
/// <summary>
/// 资源清单服务类
/// </summary>
public IManifestServices ManifestServices;
private string _pipelineOutputDirectory = string.Empty; private string _pipelineOutputDirectory = string.Empty;
private string _packageOutputDirectory = string.Empty; private string _packageOutputDirectory = string.Empty;

View File

@@ -14,7 +14,8 @@ namespace YooAsset.Editor
{ {
string buildinRootDirectory = buildParametersContext.GetBuildinRootDirectory(); string buildinRootDirectory = buildParametersContext.GetBuildinRootDirectory();
string buildPackageName = buildParametersContext.Parameters.PackageName; string buildPackageName = buildParametersContext.Parameters.PackageName;
DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(buildPackageName, buildinRootDirectory); var manifestServices = buildParametersContext.Parameters.ManifestServices;
DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(manifestServices, buildPackageName, buildinRootDirectory);
// 刷新目录 // 刷新目录
AssetDatabase.Refresh(); AssetDatabase.Refresh();

View File

@@ -58,7 +58,7 @@ namespace YooAsset.Editor
if (processBundleDepends) if (processBundleDepends)
ProcessBuiltinBundleDependency(context, manifest); ProcessBuiltinBundleDependency(context, manifest);
// 创建补丁清单文本文件 // 创建资源清单文本文件
{ {
string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion); string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}"; string filePath = $"{packageOutputDirectory}/{fileName}";
@@ -66,18 +66,18 @@ namespace YooAsset.Editor
BuildLogger.Log($"Create package manifest file: {filePath}"); BuildLogger.Log($"Create package manifest file: {filePath}");
} }
// 创建补丁清单二进制文件 // 创建资源清单二进制文件
string packageHash; string packageHash;
string packagePath; string packagePath;
{ {
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion); string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
packagePath = $"{packageOutputDirectory}/{fileName}"; packagePath = $"{packageOutputDirectory}/{fileName}";
ManifestTools.SerializeToBinary(packagePath, manifest); ManifestTools.SerializeToBinary(packagePath, manifest, buildParameters.ManifestServices);
packageHash = HashUtility.FileCRC32(packagePath); packageHash = HashUtility.FileCRC32(packagePath);
BuildLogger.Log($"Create package manifest file: {packagePath}"); BuildLogger.Log($"Create package manifest file: {packagePath}");
} }
// 创建补丁清单哈希文件 // 创建资源清单哈希文件
{ {
string fileName = YooAssetSettingsData.GetPackageHashFileName(buildParameters.PackageName, buildParameters.PackageVersion); string fileName = YooAssetSettingsData.GetPackageHashFileName(buildParameters.PackageName, buildParameters.PackageVersion);
string filePath = $"{packageOutputDirectory}/{fileName}"; string filePath = $"{packageOutputDirectory}/{fileName}";
@@ -85,7 +85,7 @@ namespace YooAsset.Editor
BuildLogger.Log($"Create package manifest hash file: {filePath}"); BuildLogger.Log($"Create package manifest hash file: {filePath}");
} }
// 创建补丁清单版本文件 // 创建资源清单版本文件
{ {
string fileName = YooAssetSettingsData.GetPackageVersionFileName(buildParameters.PackageName); string fileName = YooAssetSettingsData.GetPackageVersionFileName(buildParameters.PackageName);
string filePath = $"{packageOutputDirectory}/{fileName}"; string filePath = $"{packageOutputDirectory}/{fileName}";
@@ -97,7 +97,7 @@ namespace YooAsset.Editor
{ {
ManifestContext manifestContext = new ManifestContext(); ManifestContext manifestContext = new ManifestContext();
byte[] bytesData = FileUtility.ReadAllBytes(packagePath); byte[] bytesData = FileUtility.ReadAllBytes(packagePath);
manifestContext.Manifest = ManifestTools.DeserializeFromBinary(bytesData); manifestContext.Manifest = ManifestTools.DeserializeFromBinary(bytesData, buildParameters.ManifestServices);
context.SetContextObject(manifestContext); context.SetContextObject(manifestContext);
} }
} }

View File

@@ -43,7 +43,8 @@ namespace YooAsset.Editor
buildReport.Summary.EnableSharePackRule = buildParameters.EnableSharePackRule; buildReport.Summary.EnableSharePackRule = buildParameters.EnableSharePackRule;
buildReport.Summary.SingleReferencedPackAlone = buildParameters.SingleReferencedPackAlone; buildReport.Summary.SingleReferencedPackAlone = buildParameters.SingleReferencedPackAlone;
buildReport.Summary.FileNameStyle = buildParameters.FileNameStyle; buildReport.Summary.FileNameStyle = buildParameters.FileNameStyle;
buildReport.Summary.EncryptionClassName = buildParameters.EncryptionServices == null ? "null" : buildParameters.EncryptionServices.GetType().FullName; buildReport.Summary.EncryptionServicesClassName = buildParameters.EncryptionServices == null ? "null" : buildParameters.EncryptionServices.GetType().FullName;
buildReport.Summary.ManifestServicesClassName = buildParameters.ManifestServices == null ? "null" : buildParameters.ManifestServices.GetType().FullName;
if (buildParameters is BuiltinBuildParameters) if (buildParameters is BuiltinBuildParameters)
{ {
var builtinBuildParameters = buildParameters as BuiltinBuildParameters; var builtinBuildParameters = buildParameters as BuiltinBuildParameters;

View File

@@ -11,7 +11,7 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context) void IBuildTask.Run(BuildContext context)
{ {
var buildParametersContext = context.GetContextObject<BuildParametersContext>(); var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildParameters = buildParametersContext.Parameters; var buildParameters = buildParametersContext.Parameters as ScriptableBuildParameters;
// 检测基础构建参数 // 检测基础构建参数
buildParametersContext.CheckBuildParameters(); buildParametersContext.CheckBuildParameters();
@@ -50,6 +50,13 @@ namespace YooAsset.Editor
{ {
BuildLogger.Log($"Create pipeline output directory: {pipelineOutputDirectory}"); 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> /// </summary>
public ECompressOption CompressOption = ECompressOption.Uncompressed; public ECompressOption CompressOption = ECompressOption.Uncompressed;
/// <summary>
/// 从AssetBundle文件头里剥离Unity版本信息
/// </summary>
public bool StripUnityVersion = false;
/// <summary> /// <summary>
/// 禁止写入类型树结构(可以降低包体和内存并提高加载效率) /// 禁止写入类型树结构(可以降低包体和内存并提高加载效率)
/// </summary> /// </summary>
@@ -70,6 +75,9 @@ namespace YooAsset.Editor
else else
throw new System.NotImplementedException(CompressOption.ToString()); throw new System.NotImplementedException(CompressOption.ToString());
if (StripUnityVersion)
buildParams.ContentBuildFlags |= UnityEditor.Build.Content.ContentBuildFlags.StripUnityVersion;
if (DisableWriteTypeTree) if (DisableWriteTypeTree)
buildParams.ContentBuildFlags |= UnityEditor.Build.Content.ContentBuildFlags.DisableWriteTypeTree; buildParams.ContentBuildFlags |= UnityEditor.Build.Content.ContentBuildFlags.DisableWriteTypeTree;

View File

@@ -2,37 +2,100 @@
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using System.Text;
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
internal static class BuildLogger 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; _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) public static void Log(string message)
{ {
if (_enableLog) if (_enableLog)
{ {
WriteLog("INFO", message);
Debug.Log(message); Debug.Log(message);
} }
} }
public static void Warning(string message) public static void Warning(string message)
{ {
Debug.LogWarning(message); if (_enableLog)
{
WriteLog("WARN", message);
Debug.LogWarning(message);
}
} }
public static void Error(string 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) public static string GetErrorMessage(ErrorCode code, string message)
{ {
return $"[ErrorCode{(int)code}] {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, BuildPipelineIsNullOrEmpty = 116,
BuildBundleTypeIsUnknown = 117, BuildBundleTypeIsUnknown = 117,
RecommendScriptBuildPipeline = 130, RecommendScriptBuildPipeline = 130,
BuiltinShadersBundleNameIsNull = 131,
// TaskGetBuildMap // TaskGetBuildMap
RemoveInvalidTags = 200, RemoveInvalidTags = 200,

View File

@@ -0,0 +1,15 @@

namespace YooAsset.Editor
{
public class ManifestNone : IManifestServices
{
public byte[] ProcessManifest(byte[] fileData)
{
return fileData;
}
public byte[] RestoreManifest(byte[] fileData)
{
return fileData;
}
}
}

View File

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

View File

@@ -1,8 +1,13 @@
 using UnityEditor;
using UnityEngine;
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
public interface IBuildPipeline public interface IBuildPipeline
{ {
/// <summary>
/// 运行构建任务
/// </summary>
BuildResult Run(BuildParameters buildParameters, bool enableLog); 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,211 +12,224 @@ namespace YooAsset.Editor
{ {
internal abstract class BuildPipelineViewerBase internal abstract class BuildPipelineViewerBase
{ {
private const int StyleWidth = 400; protected const int StyleWidth = 400;
private const int LabelMinWidth = 180; protected const int LabelMinWidth = 190;
protected readonly string PackageName; protected string PackageName { private set; get; }
protected readonly BuildTarget BuildTarget; protected string PipelineName { private set; get; }
protected readonly EBuildPipeline BuildPipeline; protected BuildTarget BuildTarget { private set; get; }
protected TemplateContainer Root;
private TextField _buildOutputField; /// <summary>
private TextField _buildVersionField; /// 初始化视图
private PopupField<Enum> _buildModeField; /// </summary>
private PopupField<Type> _encryptionField; public void InitView(string packageName, string pipelineName, BuildTarget buildTarget)
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)
{ {
PackageName = packageName; PackageName = packageName;
PipelineName = pipelineName;
BuildTarget = buildTarget; 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>
/// 执行构建任务 /// 创建视图
/// </summary> /// </summary>
protected abstract void ExecuteBuild(); public abstract void CreateView(VisualElement parent);
/// <summary> /// <summary>
/// 获取构建版本 /// 获取默认版本
/// </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> /// <summary>
/// 创建加密类实例 /// 创建资源加密服务类实例
/// </summary> /// </summary>
protected IEncryptionServices CreateEncryptionInstance() protected IEncryptionServices CreateEncryptionServicesInstance()
{ {
var encyptionClassName = AssetBundleBuilderSetting.GetPackageEncyptionClassName(PackageName, BuildPipeline); var className = AssetBundleBuilderSetting.GetPackageEncyptionServicesClassName(PackageName, PipelineName);
var encryptionClassTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices)); var classTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices));
var classType = encryptionClassTypes.Find(x => x.FullName.Equals(encyptionClassName)); var classType = classTypes.Find(x => x.FullName.Equals(className));
if (classType != null) if (classType != null)
return (IEncryptionServices)Activator.CreateInstance(classType); return (IEncryptionServices)Activator.CreateInstance(classType);
else else
return null; return null;
} }
private string GetDefaultPackageVersion() /// <summary>
/// 创建资源清单服务类实例
/// </summary>
protected IManifestServices CreateManifestServicesInstance()
{ {
int totalMinutes = DateTime.Now.Hour * 60 + DateTime.Now.Minute; var className = AssetBundleBuilderSetting.GetPackageManifestServicesClassName(PackageName, PipelineName);
return DateTime.Now.ToString("yyyy-MM-dd") + "-" + totalMinutes; var classTypes = EditorTools.GetAssignableTypes(typeof(IManifestServices));
var classType = classTypes.Find(x => x.FullName.Equals(className));
if (classType != null)
return (IManifestServices)Activator.CreateInstance(classType);
else
return null;
} }
#region UI元素通用处理方法
protected void SetBuildOutputField(TextField textField)
{
// 输出目录
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);
// 设置内置资源标签显隐
SetCopyBuildinFileTagsVisible(tagField);
});
UIElementsTools.SetElementLabelMinWidth(enumField, LabelMinWidth);
}
protected void SetCopyBuildinFileTagsVisible(TextField tagField)
{
var option = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, PipelineName);
tagField.visible = option == EBuildinFileCopyOption.ClearAndCopyByTags || option == EBuildinFileCopyOption.OnlyCopyByTags;
}
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> CreateEncryptionServicesField(VisualElement container)
{
// 加密服务类
var classTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices));
if (classTypes.Count > 0)
{
var className = AssetBundleBuilderSetting.GetPackageEncyptionServicesClassName(PackageName, PipelineName);
int defaultIndex = classTypes.FindIndex(x => x.FullName.Equals(className));
if (defaultIndex < 0)
defaultIndex = 0;
var popupField = new PopupField<Type>(classTypes, defaultIndex);
popupField.label = "Encryption Services";
popupField.style.width = StyleWidth;
popupField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageEncyptionServicesClassName(PackageName, PipelineName, popupField.value.FullName);
});
container.Add(popupField);
UIElementsTools.SetElementLabelMinWidth(popupField, LabelMinWidth);
return popupField;
}
else
{
var popupField = new PopupField<Type>();
popupField.label = "Encryption Services";
popupField.style.width = StyleWidth;
container.Add(popupField);
UIElementsTools.SetElementLabelMinWidth(popupField, LabelMinWidth);
return popupField;
}
}
protected PopupField<Type> CreateManifestServicesField(VisualElement container)
{
// 清单服务类
var classTypes = EditorTools.GetAssignableTypes(typeof(IManifestServices));
if (classTypes.Count > 0)
{
var className = AssetBundleBuilderSetting.GetPackageManifestServicesClassName(PackageName, PipelineName);
int defaultIndex = classTypes.FindIndex(x => x.FullName.Equals(className));
if (defaultIndex < 0)
defaultIndex = 0;
var popupField = new PopupField<Type>(classTypes, defaultIndex);
popupField.label = "Manifest Services";
popupField.style.width = StyleWidth;
popupField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSetting.SetPackageManifestServicesClassName(PackageName, PipelineName, popupField.value.FullName);
});
container.Add(popupField);
UIElementsTools.SetElementLabelMinWidth(popupField, LabelMinWidth);
return popupField;
}
else
{
var popupField = new PopupField<Type>();
popupField.label = "Manifest Services";
popupField.style.width = StyleWidth;
container.Add(popupField);
UIElementsTools.SetElementLabelMinWidth(popupField, LabelMinWidth);
return popupField;
}
}
#endregion
} }
} }
#endif #endif

View File

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

View File

@@ -0,0 +1,132 @@
#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> _encryptionServicesField;
protected PopupField<Type> _manifestServicesField;
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 popupContainer = Root.Q("PopupContainer");
_encryptionServicesField = CreateEncryptionServicesField(popupContainer);
_manifestServicesField = CreateManifestServicesField(popupContainer);
// 压缩方式选项
_compressionField = Root.Q<EnumField>("Compression");
SetCompressionField(_compressionField);
// 输出文件名称样式
_outputNameStyleField = Root.Q<EnumField>("FileNameStyle");
SetOutputNameStyleField(_outputNameStyleField);
// 首包文件拷贝参数
_copyBuildinFileTagsField = Root.Q<TextField>("CopyBuildinFileParam");
SetCopyBuildinFileTagsField(_copyBuildinFileTagsField);
SetCopyBuildinFileTagsVisible(_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 = CreateEncryptionServicesInstance();
buildParameters.ManifestServices = CreateManifestServicesInstance();
BuiltinBuildPipeline pipeline = new BuiltinBuildPipeline();
var buildResult = pipeline.Run(buildParameters, true);
if (buildResult.Success)
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
}
}
}
#endif

View File

@@ -4,7 +4,7 @@
<ui:TextField picking-mode="Ignore" label="Build Version" name="BuildVersion" /> <ui:TextField picking-mode="Ignore" label="Build Version" name="BuildVersion" />
<ui:Toggle label="Clear Build Cache" name="ClearBuildCache" /> <ui:Toggle label="Clear Build Cache" name="ClearBuildCache" />
<ui:Toggle label="Use Asset Depend DB" name="UseAssetDependency" /> <ui:Toggle label="Use Asset Depend DB" name="UseAssetDependency" />
<ui:VisualElement name="EncryptionContainer" style="height: 24px;" /> <ui:VisualElement name="PopupContainer" style="flex-grow: 1;" />
<uie:EnumField label="Compression" value="Center" name="Compression" /> <uie:EnumField label="Compression" value="Center" name="Compression" />
<uie:EnumField label="File Name Style" value="Center" name="FileNameStyle" /> <uie:EnumField label="File Name Style" value="Center" name="FileNameStyle" />
<uie:EnumField label="Copy Buildin File Option" value="Center" name="CopyBuildinFileOption" /> <uie:EnumField label="Copy Buildin File Option" value="Center" name="CopyBuildinFileOption" />

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,85 @@
#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;
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,124 @@
#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> _encryptionServicesField;
protected PopupField<Type> _manifestServicesField;
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 popupContainer = Root.Q("PopupContainer");
_encryptionServicesField = CreateEncryptionServicesField(popupContainer);
_manifestServicesField = CreateManifestServicesField(popupContainer);
// 输出文件名称样式
_outputNameStyleField = Root.Q<EnumField>("FileNameStyle");
SetOutputNameStyleField(_outputNameStyleField);
// 首包文件拷贝参数
_copyBuildinFileTagsField = Root.Q<TextField>("CopyBuildinFileParam");
SetCopyBuildinFileTagsField(_copyBuildinFileTagsField);
SetCopyBuildinFileTagsVisible(_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 = CreateEncryptionServicesInstance();
buildParameters.ManifestServices = CreateManifestServicesInstance();
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="PopupContainer" style="flex-grow: 1;" />
<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,145 @@
#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> _encryptionServicesField;
protected PopupField<Type> _manifestServicesField;
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 popupContainer = Root.Q("PopupContainer");
_encryptionServicesField = CreateEncryptionServicesField(popupContainer);
_manifestServicesField = CreateManifestServicesField(popupContainer);
// 压缩方式选项
_compressionField = Root.Q<EnumField>("Compression");
SetCompressionField(_compressionField);
// 输出文件名称样式
_outputNameStyleField = Root.Q<EnumField>("FileNameStyle");
SetOutputNameStyleField(_outputNameStyleField);
// 首包文件拷贝参数
_copyBuildinFileTagsField = Root.Q<TextField>("CopyBuildinFileParam");
SetCopyBuildinFileTagsField(_copyBuildinFileTagsField);
SetCopyBuildinFileTagsVisible(_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 = CreateEncryptionServicesInstance();
buildParameters.ManifestServices = CreateManifestServicesInstance();
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="PopupContainer" style="flex-grow: 1;" />
<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) private List<string> GetAssetTags(AssetBundleCollectorGroup group)
{ {
List<string> tags = EditorTools.StringToStringList(group.AssetTags, ';'); List<string> result = EditorTools.StringToStringList(AssetTags, ';');
List<string> temper = EditorTools.StringToStringList(AssetTags, ';'); if (CollectorType == ECollectorType.MainAssetCollector)
tags.AddRange(temper); {
return tags; List<string> temps = EditorTools.StringToStringList(group.AssetTags, ';');
result.AddRange(temps);
}
return result;
} }
private List<AssetInfo> GetAllDependencies(CollectCommand command, string mainAssetPath) 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) 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) if (attribute != null && string.IsNullOrEmpty(attribute.DisplayName) == false)
return attribute.DisplayName; return attribute.DisplayName;
else else

View File

@@ -762,6 +762,7 @@ namespace YooAsset.Editor
elementTop.Add(objectField); elementTop.Add(objectField);
var label = objectField.Q<Label>(); var label = objectField.Q<Label>();
label.style.minWidth = 63; label.style.minWidth = 63;
UIElementsTools.SetObjectFieldShowPath(objectField);
} }
// Bottom VisualElement // Bottom VisualElement
@@ -851,8 +852,6 @@ namespace YooAsset.Editor
var collector = selectGroup.Collectors[index]; var collector = selectGroup.Collectors[index];
var collectObject = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(collector.CollectPath); var collectObject = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(collector.CollectPath);
if (collectObject != null)
collectObject.name = collector.CollectPath;
// 注意:非主资源收集器的标签栏需要被冻结 // 注意:非主资源收集器的标签栏需要被冻结
var textTags = element.Q<TextField>("TextField1"); var textTags = element.Q<TextField>("TextField1");
@@ -885,13 +884,13 @@ namespace YooAsset.Editor
{ {
collector.CollectPath = AssetDatabase.GetAssetPath(evt.newValue); collector.CollectPath = AssetDatabase.GetAssetPath(evt.newValue);
collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath); collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath);
objectField1.value.name = collector.CollectPath;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) if (foldout.value)
{ {
RefreshFoldout(foldout, selectGroup, collector); RefreshFoldout(foldout, selectGroup, collector);
} }
}); });
UIElementsTools.RefreshObjectFieldShowPath(objectField1);
// Collector Type // Collector Type
var popupField0 = element.Q<PopupField<string>>("PopupField0"); var popupField0 = element.Q<PopupField<string>>("PopupField0");

View File

@@ -70,7 +70,11 @@ namespace YooAsset.Editor
foreach (var cacheInfoPair in _database) foreach (var cacheInfoPair in _database)
{ {
var assetPath = cacheInfoPair.Key; var assetPath = cacheInfoPair.Key;
#if UNITY_2021_3_OR_NEWER
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath, AssetPathToGUIDOptions.OnlyExistingAssets);
#else
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath); var assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
#endif
if (string.IsNullOrEmpty(assetGUID)) if (string.IsNullOrEmpty(assetGUID))
{ {
removeList.Add(assetPath); removeList.Add(assetPath);
@@ -173,26 +177,42 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public string[] GetDependencies(string assetPath, bool recursive) public string[] GetDependencies(string assetPath, bool recursive)
{ {
// 注意AssetDatabase.GetDependencies()方法返回结果里会踢出丢失文件!
// 注意AssetDatabase.GetDependencies()方法返回结果里会包含主资源路径!
// 注意:机制上不允许存在未收录的资源 // 注意:机制上不允许存在未收录的资源
if (_database.ContainsKey(assetPath) == false) if (_database.ContainsKey(assetPath) == false)
{ {
throw new Exception($"Fatal : can not found cache info : {assetPath}"); throw new Exception($"Fatal : can not found cache info : {assetPath}");
} }
var result = new HashSet<string> { assetPath }; var result = new HashSet<string>();
CollectDependencies(assetPath, result, recursive);
// 注意:递归收集依赖时,依赖列表中包含主资源
if (recursive)
result.Add(assetPath);
// 收集依赖
CollectDependencies(assetPath, assetPath, result, recursive);
// 注意AssetDatabase.GetDependencies保持一致将主资源添加到依赖列表最前面
return result.ToArray(); 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) 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) foreach (var dependGUID in cacheInfo.DependGUIDs)
@@ -213,7 +233,7 @@ namespace YooAsset.Editor
// 递归收集依赖 // 递归收集依赖
if (recursive) if (recursive)
CollectDependencies(dependAssetPath, result, recursive); CollectDependencies(assetPath, dependAssetPath, result, recursive);
} }
} }
@@ -237,6 +257,7 @@ namespace YooAsset.Editor
} }
private DependencyInfo CreateDependencyInfo(string assetPath) private DependencyInfo CreateDependencyInfo(string assetPath)
{ {
// 注意AssetDatabase.GetDependencies()方法返回结果里会踢出丢失文件!
var dependHash = AssetDatabase.GetAssetDependencyHash(assetPath); var dependHash = AssetDatabase.GetAssetDependencyHash(assetPath);
var dependAssetPaths = AssetDatabase.GetDependencies(assetPath, false); var dependAssetPaths = AssetDatabase.GetDependencies(assetPath, false);
var dependGUIDs = new List<string>(); var dependGUIDs = new List<string>();

View File

@@ -1,5 +1,4 @@
using System; using System;
using System.Reflection;
namespace YooAsset.Editor namespace YooAsset.Editor
{ {
@@ -15,22 +14,4 @@ namespace YooAsset.Editor
this.DisplayName = name; 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 filePath = $"{resultPath}/{nameof(DebugReport)}_{_currentReport.FrameCount}.json";
string fileContent = JsonUtility.ToJson(_currentReport, true); string fileContent = JsonUtility.ToJson(_currentReport, true);
FileUtility.WriteAllText(filePath, fileContent); FileUtility.WriteAllText(filePath, fileContent);
Debug.Log($"Debug report file saved : {filePath}");
} }
} }
private void OnSearchKeyWordChange(ChangeEvent<string> e) private void OnSearchKeyWordChange(ChangeEvent<string> e)

View File

@@ -71,9 +71,10 @@ namespace YooAsset.Editor
public bool UseAssetDependencyDB; public bool UseAssetDependencyDB;
public bool EnableSharePackRule; public bool EnableSharePackRule;
public bool SingleReferencedPackAlone; public bool SingleReferencedPackAlone;
public string EncryptionClassName; public string EncryptionServicesClassName;
public string ManifestServicesClassName;
public EFileNameStyle FileNameStyle; public EFileNameStyle FileNameStyle;
// 引擎参数 // 引擎参数
public ECompressOption CompressOption; public ECompressOption CompressOption;
public bool DisableWriteTypeTree; public bool DisableWriteTypeTree;

View File

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

View File

@@ -66,7 +66,8 @@ namespace YooAsset.Editor
BindListViewItem("Use Asset Dependency DB", $"{buildReport.Summary.UseAssetDependencyDB}"); BindListViewItem("Use Asset Dependency DB", $"{buildReport.Summary.UseAssetDependencyDB}");
BindListViewItem("Enable Share Pack Rule", $"{buildReport.Summary.EnableSharePackRule}"); BindListViewItem("Enable Share Pack Rule", $"{buildReport.Summary.EnableSharePackRule}");
BindListViewItem("Single Referenced Pack Alone", $"{buildReport.Summary.SingleReferencedPackAlone}"); BindListViewItem("Single Referenced Pack Alone", $"{buildReport.Summary.SingleReferencedPackAlone}");
BindListViewItem("Encryption Class Name", buildReport.Summary.EncryptionClassName); BindListViewItem("Encryption Services", buildReport.Summary.EncryptionServicesClassName);
BindListViewItem("Manifest Services", buildReport.Summary.ManifestServicesClassName);
BindListViewItem("FileNameStyle", $"{buildReport.Summary.FileNameStyle}"); BindListViewItem("FileNameStyle", $"{buildReport.Summary.FileNameStyle}");
BindListViewItem("CompressOption", $"{buildReport.Summary.CompressOption}"); BindListViewItem("CompressOption", $"{buildReport.Summary.CompressOption}");
BindListViewItem("DisableWriteTypeTree", $"{buildReport.Summary.DisableWriteTypeTree}"); BindListViewItem("DisableWriteTypeTree", $"{buildReport.Summary.DisableWriteTypeTree}");

View File

@@ -129,6 +129,23 @@ namespace YooAsset.Editor
} }
#endregion #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 #region PackageManager
public static string GetPackageManagerYooVersion() 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); var cell = new ButtonCell(searchTag);
Cells.Add(cell); 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); Cells.Add(cell);
} }
public void AddStringValueCell(string searchTag, string value) public void AddStringValueCell(string searchTag, string value)

View File

@@ -33,6 +33,67 @@ namespace YooAsset.Editor
} }
} }
/// <summary>
/// 设置元素显示文本为资源路径
/// </summary>
public static void SetObjectFieldShowPath(ObjectField objectField)
{
string LabelClassName = "unity-object-field-display__label";
var nameLable = objectField.Q<Label>(className: LabelClassName);
if (nameLable == null)
return;
objectField.RegisterValueChangedCallback(evt =>
{
Object obj = evt.newValue;
if (obj == null)
{
nameLable.text = "None (Object)";
return;
}
// 获取资源路径(仅适用于项目资源)
string path = AssetDatabase.GetAssetPath(obj);
if (string.IsNullOrEmpty(path) == false)
{
nameLable.text = path;
}
else
{
nameLable.text = obj.name;
}
});
}
/// <summary>
/// 刷新元素显示文本内容
/// </summary>
public static void RefreshObjectFieldShowPath(ObjectField objectField)
{
string LabelClassName = "unity-object-field-display__label";
var nameLable = objectField.Q<Label>(className: LabelClassName);
if (nameLable == null)
return;
Object obj = objectField.value;
if (obj == null)
{
nameLable.text = "None (Object)";
return;
}
// 获取资源路径(仅适用于项目资源)
string path = AssetDatabase.GetAssetPath(obj);
if (string.IsNullOrEmpty(path) == false)
{
nameLable.text = path;
}
else
{
nameLable.text = obj.name;
}
}
/// <summary> /// <summary>
/// 设置按钮图标 /// 设置按钮图标
/// </summary> /// </summary>

View File

@@ -1,7 +1,11 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
// 内部友元
[assembly: InternalsVisibleTo("YooAsset.Editor")] [assembly: InternalsVisibleTo("YooAsset.Editor")]
[assembly: InternalsVisibleTo("YooAsset.EditorExtension")]
[assembly: InternalsVisibleTo("YooAsset.RuntimeExtension")]
[assembly: InternalsVisibleTo("YooAsset.Test.Editor")] [assembly: InternalsVisibleTo("YooAsset.Test.Editor")]
// 外部友元
[assembly: InternalsVisibleTo("YooAsset.MiniGame")]
[assembly: InternalsVisibleTo("YooAsset.RuntimeExtension")]
[assembly: InternalsVisibleTo("YooAsset.EditorExtension")]
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor")] [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 #elif UNITY_STANDALONE_OSX
url = new System.Uri(path).ToString(); 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); url = StringUtility.Format("file:///{0}", path);
#else #else
throw new System.NotImplementedException(); throw new System.NotImplementedException();

View File

@@ -106,7 +106,7 @@ namespace YooAsset
} }
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
//TODO 场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法! //注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
InternalUpdate(); InternalUpdate();
} }
public override void UnSuspendLoad() public override void UnSuspendLoad()

View File

@@ -112,7 +112,7 @@ namespace YooAsset
} }
internal override void InternalWaitForAsyncComplete() internal override void InternalWaitForAsyncComplete()
{ {
//TODO 场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法! //注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
InternalUpdate(); InternalUpdate();
} }
public override void UnSuspendLoad() public override void UnSuspendLoad()

View File

@@ -58,6 +58,11 @@ namespace YooAsset
/// </summary> /// </summary>
public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle; public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
/// <summary>
/// 自定义参数:覆盖安装缓存清理模式
/// </summary>
public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles;
/// <summary> /// <summary>
/// 自定义参数:数据文件追加文件格式 /// 自定义参数:数据文件追加文件格式
/// </summary> /// </summary>
@@ -83,6 +88,16 @@ namespace YooAsset
/// 自定义参数:解密方法类 /// 自定义参数:解密方法类
/// </summary> /// </summary>
public IDecryptionServices DecryptionServices { private set; get; } public IDecryptionServices DecryptionServices { private set; get; }
/// <summary>
/// 自定义参数:资源清单服务类
/// </summary>
public IManifestServices ManifestServices { private set; get; }
/// <summary>
/// 自定义参数:拷贝内置文件服务类
/// </summary>
public ICopyLocalFileServices CopyLocalFileServices { private set; get; }
#endregion #endregion
@@ -104,15 +119,15 @@ namespace YooAsset
var operation = new DBFSRequestPackageVersionOperation(this); var operation = new DBFSRequestPackageVersionOperation(this);
return operation; 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); options.ImportFilePath = GetBuildinFileLoadPath(bundle);
return _unpackFileSystem.DownloadFileAsync(bundle, param); return _unpackFileSystem.DownloadFileAsync(bundle, options);
} }
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle) public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)
{ {
@@ -145,6 +160,10 @@ namespace YooAsset
{ {
FileVerifyLevel = (EFileVerifyLevel)value; FileVerifyLevel = (EFileVerifyLevel)value;
} }
else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE)
{
InstallClearMode = (EOverwriteInstallClearMode)value;
}
else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION) else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION)
{ {
AppendFileExtension = Convert.ToBoolean(value); AppendFileExtension = Convert.ToBoolean(value);
@@ -165,6 +184,14 @@ namespace YooAsset
{ {
DecryptionServices = (IDecryptionServices)value; DecryptionServices = (IDecryptionServices)value;
} }
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES)
{
ManifestServices = (IManifestServices)value;
}
else if (name == FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES)
{
CopyLocalFileServices = (ICopyLocalFileServices)value;
}
else else
{ {
YooLogger.Warning($"Invalid parameter : {name}"); YooLogger.Warning($"Invalid parameter : {name}");
@@ -184,8 +211,10 @@ namespace YooAsset
_unpackFileSystem = new DefaultUnpackFileSystem(); _unpackFileSystem = new DefaultUnpackFileSystem();
_unpackFileSystem.SetParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices); _unpackFileSystem.SetParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel); _unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.INSTALL_CLEAR_MODE, InstallClearMode);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, AppendFileExtension); _unpackFileSystem.SetParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, AppendFileExtension);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, DecryptionServices); _unpackFileSystem.SetParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, DecryptionServices);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES, CopyLocalFileServices);
_unpackFileSystem.OnCreate(packageName, null); _unpackFileSystem.OnCreate(packageName, null);
} }
public virtual void OnDestroy() public virtual void OnDestroy()

View File

@@ -11,7 +11,7 @@ namespace YooAsset
/// <summary> /// <summary>
/// 在构建应用程序前自动生成内置资源目录文件。 /// 在构建应用程序前自动生成内置资源目录文件。
/// 原理搜索StreamingAssets目录下的所有资源文件然后将这些文件信息写入文件,并存储在Resources目录下 /// 原理搜索StreamingAssets目录下的所有资源文件将这些文件信息写入文件然后在运行时做查询用途
/// </summary> /// </summary>
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report) public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
{ {
@@ -21,7 +21,7 @@ namespace YooAsset
DirectoryInfo rootDirectory = new DirectoryInfo(rootPath); DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);
if (rootDirectory.Exists == false) if (rootDirectory.Exists == false)
{ {
UnityEngine.Debug.LogWarning($"Can not found StreamingAssets root directory : {rootPath}"); Debug.LogWarning($"Can not found StreamingAssets root directory : {rootPath}");
return; return;
} }
@@ -31,10 +31,17 @@ namespace YooAsset
{ {
string packageName = subDirectory.Name; string packageName = subDirectory.Name;
string pacakgeDirectory = subDirectory.FullName; string pacakgeDirectory = subDirectory.FullName;
bool result = CreateBuildinCatalogFile(packageName, pacakgeDirectory); try
if (result == false)
{ {
throw new System.Exception($"Create package {packageName} catalog file failed ! See the detail error in console !"); bool result = CreateBuildinCatalogFile(null, packageName, pacakgeDirectory);
if (result == false)
{
Debug.LogError($"Create package {packageName} catalog file failed ! See the detail error in console !");
}
}
catch (System.Exception ex)
{
Debug.LogError($"Create package {packageName} catalog file failed ! {ex.Message}");
} }
} }
} }
@@ -42,7 +49,7 @@ namespace YooAsset
/// <summary> /// <summary>
/// 生成包裹的内置资源目录文件 /// 生成包裹的内置资源目录文件
/// </summary> /// </summary>
public static bool CreateBuildinCatalogFile(string packageName, string pacakgeDirectory) public static bool CreateBuildinCatalogFile(IManifestServices services, string packageName, string pacakgeDirectory)
{ {
// 获取资源清单版本 // 获取资源清单版本
string packageVersion; string packageVersion;
@@ -70,7 +77,7 @@ namespace YooAsset
} }
var binaryData = FileUtility.ReadAllBytes(manifestFilePath); var binaryData = FileUtility.ReadAllBytes(manifestFilePath);
packageManifest = ManifestTools.DeserializeFromBinary(binaryData); packageManifest = ManifestTools.DeserializeFromBinary(binaryData, services);
} }
// 获取文件名映射关系 // 获取文件名映射关系

View File

@@ -106,10 +106,11 @@ namespace YooAsset
if (_loadCatalogFileOp == null) if (_loadCatalogFileOp == null)
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
/*
// 兼容性初始化 // 兼容性初始化
// 说明:内置文件系统在编辑器下运行时需要动态生成 // 说明:内置文件系统在编辑器下运行时需要动态生成
string packageRoot = _fileSystem.FileRoot; string packageRoot = _fileSystem.FileRoot;
bool result = DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(_fileSystem.PackageName, packageRoot); bool result = DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(_fileSystem.ManifestServices, _fileSystem.PackageName, packageRoot);
if (result == false) if (result == false)
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
@@ -117,6 +118,7 @@ namespace YooAsset
Error = $"Create package catalog file failed ! See the detail error in console !"; Error = $"Create package catalog file failed ! See the detail error in console !";
return; return;
} }
*/
#endif #endif
_loadCatalogFileOp = new LoadBuildinCatalogFileOperation(_fileSystem); _loadCatalogFileOp = new LoadBuildinCatalogFileOperation(_fileSystem);

View File

@@ -69,8 +69,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData) if (_steps == ESteps.VerifyFileData)
{ {
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result); if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
if (fileHash == _packageHash)
{ {
_steps = ESteps.LoadManifest; _steps = ESteps.LoadManifest;
} }
@@ -86,7 +85,7 @@ namespace YooAsset
{ {
if (_deserializer == null) if (_deserializer == null)
{ {
_deserializer = new DeserializeManifestOperation(_webDataRequestOp.Result); _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _webDataRequestOp.Result);
_deserializer.StartOperation(); _deserializer.StartOperation();
AddChildOperation(_deserializer); AddChildOperation(_deserializer);
} }

View File

@@ -58,13 +58,18 @@ namespace YooAsset
/// <summary> /// <summary>
/// 自定义参数:远程服务接口 /// 自定义参数:远程服务接口
/// </summary> /// </summary>
public IRemoteServices RemoteServices { private set; get; } = null; public IRemoteServices RemoteServices { private set; get; }
/// <summary> /// <summary>
/// 自定义参数:初始化的时候缓存文件校验级别 /// 自定义参数:初始化的时候缓存文件校验级别
/// </summary> /// </summary>
public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle; public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
/// <summary>
/// 自定义参数:覆盖安装缓存清理模式
/// </summary>
public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles;
/// <summary> /// <summary>
/// 自定义参数:数据文件追加文件格式 /// 自定义参数:数据文件追加文件格式
/// </summary> /// </summary>
@@ -94,6 +99,16 @@ namespace YooAsset
/// 自定义参数:解密方法类 /// 自定义参数:解密方法类
/// </summary> /// </summary>
public IDecryptionServices DecryptionServices { private set; get; } public IDecryptionServices DecryptionServices { private set; get; }
/// <summary>
/// 自定义参数:资源清单服务类
/// </summary>
public IManifestServices ManifestServices { private set; get; }
/// <summary>
/// 自定义参数:拷贝内置文件服务类
/// </summary>
public ICopyLocalFileServices CopyLocalFileServices { private set; get; }
#endregion #endregion
@@ -115,43 +130,43 @@ namespace YooAsset
var operation = new DCFSRequestPackageVersionOperation(this, appendTimeTicks, timeout); var operation = new DCFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
return operation; 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); var operation = new ClearAllCacheBundleFilesOperation(this);
return operation; return operation;
} }
else if (clearMode == EFileClearMode.ClearUnusedBundleFiles.ToString()) else if (options.ClearMode == EFileClearMode.ClearUnusedBundleFiles.ToString())
{ {
var operation = new ClearUnusedCacheBundleFilesOperation(this, manifest); var operation = new ClearUnusedCacheBundleFilesOperation(this, manifest);
return operation; 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; return operation;
} }
else if (clearMode == EFileClearMode.ClearAllManifestFiles.ToString()) else if (options.ClearMode == EFileClearMode.ClearAllManifestFiles.ToString())
{ {
var operation = new ClearAllCacheManifestFilesOperation(this); var operation = new ClearAllCacheManifestFilesOperation(this);
return operation; return operation;
} }
else if (clearMode == EFileClearMode.ClearUnusedManifestFiles.ToString()) else if (options.ClearMode == EFileClearMode.ClearUnusedManifestFiles.ToString())
{ {
var operation = new ClearUnusedCacheManifestFilesOperation(this, manifest); var operation = new ClearUnusedCacheManifestFilesOperation(this, manifest);
return operation; return operation;
} }
else else
{ {
string error = $"Invalid clear mode : {clearMode}"; string error = $"Invalid clear mode : {options.ClearMode}";
var operation = new FSClearCacheFilesCompleteOperation(error); var operation = new FSClearCacheFilesCompleteOperation(error);
return operation; 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(); //增加下载器的引用计数 downloader.Reference(); //增加下载器的引用计数
// 注意:将下载器进行包裹,可以避免父类任务终止的时候,连带子任务里的下载器也一起被终止! // 注意:将下载器进行包裹,可以避免父类任务终止的时候,连带子任务里的下载器也一起被终止!
@@ -188,6 +203,10 @@ namespace YooAsset
{ {
FileVerifyLevel = (EFileVerifyLevel)value; FileVerifyLevel = (EFileVerifyLevel)value;
} }
else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE)
{
InstallClearMode = (EOverwriteInstallClearMode)value;
}
else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION) else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION)
{ {
AppendFileExtension = Convert.ToBoolean(value); AppendFileExtension = Convert.ToBoolean(value);
@@ -212,6 +231,14 @@ namespace YooAsset
{ {
DecryptionServices = (IDecryptionServices)value; DecryptionServices = (IDecryptionServices)value;
} }
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES)
{
ManifestServices = (IManifestServices)value;
}
else if (name == FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES)
{
CopyLocalFileServices = (ICopyLocalFileServices)value;
}
else else
{ {
YooLogger.Warning($"Invalid parameter : {name}"); YooLogger.Warning($"Invalid parameter : {name}");
@@ -227,8 +254,8 @@ namespace YooAsset
_packageRoot = packageRoot; _packageRoot = packageRoot;
_cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.BundleFilesFolderName); _cacheBundleFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.BundleFilesFolderName);
_tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
_cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.ManifestFilesFolderName); _cacheManifestFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.ManifestFilesFolderName);
_tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultCacheFileSystemDefine.TempFilesFolderName);
} }
public virtual void OnDestroy() public virtual void OnDestroy()
{ {
@@ -500,7 +527,18 @@ namespace YooAsset
} }
/// <summary> /// <summary>
/// 删除所有清单文件 /// 删除所有缓存的资源文件
/// </summary>
public void DeleteAllBundleFiles()
{
if (Directory.Exists(_cacheBundleFilesRoot))
{
Directory.Delete(_cacheBundleFilesRoot, true);
}
}
/// <summary>
/// 删除所有缓存的清单文件
/// </summary> /// </summary>
public void DeleteAllManifestFiles() public void DeleteAllManifestFiles()
{ {
@@ -539,6 +577,21 @@ namespace YooAsset
}; };
return DecryptionServices.LoadAssetBundleAsync(fileInfo); 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 #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()) 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); appFootPrint.Coverage(_fileSystem.PackageName);
YooLogger.Warning("Delete manifest files when application foot print dirty !");
} }
_steps = ESteps.SearchCacheFiles; _steps = ESteps.SearchCacheFiles;

View File

@@ -58,8 +58,8 @@ namespace YooAsset
// 注意边玩边下下载器引用计数没有Release // 注意边玩边下下载器引用计数没有Release
if (_downloadFileOp == null) if (_downloadFileOp == null)
{ {
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60); DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, downloadParam); _downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, options);
_downloadFileOp.StartOperation(); _downloadFileOp.StartOperation();
AddChildOperation(_downloadFileOp); AddChildOperation(_downloadFileOp);
} }
@@ -164,11 +164,23 @@ namespace YooAsset
{ {
if (_bundle.Encrypted) if (_bundle.Encrypted)
{ {
_steps = ESteps.Done; var decryptResult = _fileSystem.LoadEncryptedAssetBundleFallback(_bundle);
Status = EOperationStatus.Failed; _assetBundle = decryptResult.Result;
Error = $"Failed to load encrypted asset bundle file : {_bundle.BundleName}"; if (_assetBundle != null)
YooLogger.Error(Error); {
return; _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;
}
} }
// 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。 // 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。
@@ -216,9 +228,6 @@ namespace YooAsset
{ {
if (ExecuteWhileDone()) if (ExecuteWhileDone())
{ {
if (_downloadFileOp != null && _downloadFileOp.Status == EOperationStatus.Failed)
YooLogger.Error($"Try load bundle {_bundle.BundleName} from remote !");
_steps = ESteps.Done; _steps = ESteps.Done;
break; break;
} }
@@ -297,8 +306,8 @@ namespace YooAsset
// 注意边玩边下下载器引用计数没有Release // 注意边玩边下下载器引用计数没有Release
if (_downloadFileOp == null) if (_downloadFileOp == null)
{ {
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60); DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
_downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, downloadParam); _downloadFileOp = _fileSystem.DownloadFileAsync(_bundle, options);
_downloadFileOp.StartOperation(); _downloadFileOp.StartOperation();
AddChildOperation(_downloadFileOp); AddChildOperation(_downloadFileOp);
} }
@@ -348,10 +357,6 @@ namespace YooAsset
{ {
if (ExecuteWhileDone()) if (ExecuteWhileDone())
{ {
//TODO 拷贝本地文件失败也会触发该错误!
if (_downloadFileOp != null && _downloadFileOp.Status == EOperationStatus.Failed)
YooLogger.Error($"Try load bundle {_bundle.BundleName} from remote !");
_steps = ESteps.Done; _steps = ESteps.Done;
break; break;
} }

View File

@@ -74,7 +74,7 @@ namespace YooAsset
/// <summary> /// <summary>
/// 创建下载任务 /// 创建下载任务
/// </summary> /// </summary>
public FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param) public FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{ {
// 查询旧的下载器 // 查询旧的下载器
if (_downloaders.TryGetValue(bundle.BundleGUID, out var oldDownloader)) if (_downloaders.TryGetValue(bundle.BundleGUID, out var oldDownloader))
@@ -82,32 +82,43 @@ namespace YooAsset
return oldDownloader; return oldDownloader;
} }
// 设置请求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 else
{ {
// 注意:把本地文件路径指定为远端下载地址 // 注意:把本地导入文件路径转换为下载器请求地址
param.MainURL = DownloadSystemHelper.ConvertToWWWPath(param.ImportFilePath); options.MainURL = DownloadSystemHelper.ConvertToWWWPath(options.ImportFilePath);
param.FallbackURL = param.MainURL; options.FallbackURL = options.MainURL;
} }
// 创建新的下载器 // 创建新的下载器
DefaultDownloadFileOperation newDownloader; DefaultDownloadFileOperation newDownloader;
if (bundle.FileSize >= _fileSystem.ResumeDownloadMinimumSize) bool isRequestLocalFile = DownloadSystemHelper.IsRequestLocalFile(options.MainURL);
if (isRequestLocalFile)
{ {
newDownloader = new DownloadResumeFileOperation(_fileSystem, bundle, param); newDownloader = new DownloadLocalFileOperation(_fileSystem, bundle, options);
AddChildOperation(newDownloader); AddChildOperation(newDownloader);
_downloaders.Add(bundle.BundleGUID, newDownloader); _downloaders.Add(bundle.BundleGUID, newDownloader);
} }
else else
{ {
newDownloader = new DownloadNormalFileOperation(_fileSystem, bundle, param); if (bundle.FileSize >= _fileSystem.ResumeDownloadMinimumSize)
AddChildOperation(newDownloader); {
_downloaders.Add(bundle.BundleGUID, newDownloader); newDownloader = new DownloadResumeFileOperation(_fileSystem, bundle, options);
AddChildOperation(newDownloader);
_downloaders.Add(bundle.BundleGUID, newDownloader);
}
else
{
newDownloader = new DownloadNormalFileOperation(_fileSystem, bundle, options);
AddChildOperation(newDownloader);
_downloaders.Add(bundle.BundleGUID, newDownloader);
}
} }
return newDownloader; return newDownloader;
} }

View File

@@ -0,0 +1,221 @@
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
namespace YooAsset
{
internal class DownloadLocalFileOperation : DefaultDownloadFileOperation
{
private readonly DefaultCacheFileSystem _fileSystem;
private VerifyTempFileOperation _verifyOperation;
private string _tempFilePath;
private ESteps _steps = ESteps.None;
internal DownloadLocalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
{
_fileSystem = fileSystem;
}
internal override void InternalStart()
{
_tempFilePath = _fileSystem.GetTempFilePath(Bundle);
_steps = ESteps.CheckExists;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 检测文件是否存在
if (_steps == ESteps.CheckExists)
{
if (_fileSystem.Exists(Bundle))
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
if (_fileSystem.CopyLocalFileServices != null)
_steps = ESteps.CopyBuildinBundle;
else
_steps = ESteps.CreateRequest;
}
}
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
FileUtility.CreateFileDirectory(_tempFilePath);
// 删除临时文件
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);
// 获取请求地址
_requestURL = GetRequestURL();
// 重置请求
ResetRequestFiled();
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
CheckRequestTimeout();
return;
}
// 检查网络错误
if (CheckRequestResult())
_steps = ESteps.VerifyTempFile;
else
_steps = ESteps.TryAgain;
// 注意:最终释放请求器
DisposeWebRequest();
}
// 拷贝内置文件
if (_steps == ESteps.CopyBuildinBundle)
{
FileUtility.CreateFileDirectory(_tempFilePath);
// 删除临时文件
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);
// 获取请求地址
_requestURL = GetRequestURL();
try
{
//TODO 团结引擎,在某些机型(红米),拷贝包内文件会小概率失败!需要借助其它方式来拷贝包内文件。
var localFileInfo = new LocalFileInfo();
localFileInfo.PackageName = _fileSystem.PackageName;
localFileInfo.BundleName = Bundle.BundleName;
localFileInfo.SourceFileURL = _requestURL;
_fileSystem.CopyLocalFileServices.CopyFile(localFileInfo, _tempFilePath);
if (File.Exists(_tempFilePath))
{
DownloadProgress = 1f;
DownloadedBytes = Bundle.FileSize;
Progress = DownloadProgress;
_steps = ESteps.VerifyTempFile;
}
else
{
Error = $"Failed copy local file : {_requestURL}";
_steps = ESteps.TryAgain;
}
}
catch (System.Exception ex)
{
Error = $"Failed copy local file : {ex.Message}";
_steps = ESteps.TryAgain;
}
}
// 验证下载文件
if (_steps == ESteps.VerifyTempFile)
{
var element = new TempFileElement(_tempFilePath, Bundle.FileCRC, Bundle.FileSize);
_verifyOperation = new VerifyTempFileOperation(element);
_verifyOperation.StartOperation();
AddChildOperation(_verifyOperation);
_steps = ESteps.CheckVerifyTempFile;
}
// 等待验证完成
if (_steps == ESteps.CheckVerifyTempFile)
{
if (IsWaitForAsyncComplete)
_verifyOperation.WaitForAsyncComplete();
_verifyOperation.UpdateOperation();
if (_verifyOperation.IsDone == false)
return;
if (_verifyOperation.Status == EOperationStatus.Succeed)
{
if (_fileSystem.WriteCacheBundleFile(Bundle, _tempFilePath))
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{_fileSystem.GetType().FullName} failed to write file !";
YooLogger.Error(Error);
}
}
else
{
_steps = ESteps.TryAgain;
Error = _verifyOperation.Error;
}
// 注意:验证完成后直接删除文件
if (File.Exists(_tempFilePath))
File.Delete(_tempFilePath);
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
//TODO 拷贝本地文件失败后不再尝试!
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
}
}
internal override void InternalAbort()
{
_steps = ESteps.Done;
DisposeWebRequest();
}
internal override void InternalWaitForAsyncComplete()
{
while (true)
{
//TODO 等待导入或解压本地文件完毕,该操作会挂起主线程!
InternalUpdate();
if (IsDone)
break;
// 短暂休眠避免完全卡死
System.Threading.Thread.Sleep(1);
}
}
private void CreateWebRequest()
{
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
DownloadHandlerFile handler = new DownloadHandlerFile(_tempFilePath);
handler.removeFileOnAbort = true;
_webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
}
}

View File

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

View File

@@ -8,17 +8,15 @@ namespace YooAsset
{ {
private readonly DefaultCacheFileSystem _fileSystem; private readonly DefaultCacheFileSystem _fileSystem;
private VerifyTempFileOperation _verifyOperation; private VerifyTempFileOperation _verifyOperation;
private bool _isReuqestLocalFile;
private string _tempFilePath; private string _tempFilePath;
private ESteps _steps = ESteps.None; 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; _fileSystem = fileSystem;
} }
internal override void InternalStart() internal override void InternalStart()
{ {
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Param.MainURL);
_tempFilePath = _fileSystem.GetTempFilePath(Bundle); _tempFilePath = _fileSystem.GetTempFilePath(Bundle);
_steps = ESteps.CheckExists; _steps = ESteps.CheckExists;
} }
@@ -133,15 +131,6 @@ namespace YooAsset
// 重新尝试下载 // 重新尝试下载
if (_steps == ESteps.TryAgain) if (_steps == ESteps.TryAgain)
{ {
//TODO 拷贝本地文件失败后不再尝试!
if (_isReuqestLocalFile)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
if (FailedTryAgain <= 0) if (FailedTryAgain <= 0)
{ {
Status = EOperationStatus.Failed; Status = EOperationStatus.Failed;
@@ -168,20 +157,17 @@ namespace YooAsset
{ {
while (true) while (true)
{ {
//TODO 如果是导入或解压本地文件,执行等待完毕 if (ExecuteWhileDone())
if (_isReuqestLocalFile)
{ {
InternalUpdate(); //TODO 尝试同步加载远端的资源文件失败
if (IsDone) if (Status == EOperationStatus.Failed)
break;
}
else
{
if (ExecuteWhileDone())
{ {
_steps = ESteps.Done; YooLogger.Error($"Try load bundle {Bundle.BundleName} from remote !");
break; YooLogger.Error($"The load remote bundle url : {_requestURL}");
} }
_steps = ESteps.Done;
break;
} }
} }
} }

View File

@@ -9,19 +9,16 @@ namespace YooAsset
private readonly DefaultCacheFileSystem _fileSystem; private readonly DefaultCacheFileSystem _fileSystem;
private DownloadHandlerFileRange _downloadHandle; private DownloadHandlerFileRange _downloadHandle;
private VerifyTempFileOperation _verifyOperation; private VerifyTempFileOperation _verifyOperation;
private bool _isReuqestLocalFile;
private long _fileOriginLength = 0; private long _fileOriginLength = 0;
private string _tempFilePath; private string _tempFilePath;
private ESteps _steps = ESteps.None; private ESteps _steps = ESteps.None;
internal DownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
internal DownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
{ {
_fileSystem = fileSystem; _fileSystem = fileSystem;
} }
internal override void InternalStart() internal override void InternalStart()
{ {
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Param.MainURL);
_tempFilePath = _fileSystem.GetTempFilePath(Bundle); _tempFilePath = _fileSystem.GetTempFilePath(Bundle);
_steps = ESteps.CheckExists; _steps = ESteps.CheckExists;
} }
@@ -152,15 +149,6 @@ namespace YooAsset
// 重新尝试下载 // 重新尝试下载
if (_steps == ESteps.TryAgain) if (_steps == ESteps.TryAgain)
{ {
//TODO 拷贝本地文件失败后不再尝试!
if (_isReuqestLocalFile)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
if (FailedTryAgain <= 0) if (FailedTryAgain <= 0)
{ {
Status = EOperationStatus.Failed; Status = EOperationStatus.Failed;
@@ -187,20 +175,17 @@ namespace YooAsset
{ {
while (true) while (true)
{ {
//TODO 如果是导入或解压本地文件,执行等待完毕 if (ExecuteWhileDone())
if (_isReuqestLocalFile)
{ {
InternalUpdate(); //TODO 尝试同步加载远端的资源文件失败
if (IsDone) if (Status == EOperationStatus.Failed)
break;
}
else
{
if (ExecuteWhileDone())
{ {
_steps = ESteps.Done; YooLogger.Error($"Try load bundle {Bundle.BundleName} from remote !");
break; YooLogger.Error($"The load remote bundle url : {_requestURL}");
} }
_steps = ESteps.Done;
break;
} }
} }
} }

View File

@@ -59,8 +59,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData) if (_steps == ESteps.VerifyFileData)
{ {
string fileHash = HashUtility.BytesCRC32(_fileData); if (ManifestTools.VerifyManifestData(_fileData, _packageHash))
if (fileHash == _packageHash)
{ {
_steps = ESteps.LoadManifest; _steps = ESteps.LoadManifest;
} }
@@ -76,7 +75,7 @@ namespace YooAsset
{ {
if (_deserializer == null) if (_deserializer == null)
{ {
_deserializer = new DeserializeManifestOperation(_fileData); _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _fileData);
_deserializer.StartOperation(); _deserializer.StartOperation();
AddChildOperation(_deserializer); AddChildOperation(_deserializer);
} }

View File

@@ -71,10 +71,13 @@ namespace YooAsset
{ {
while (true) while (true)
{ {
//TODO 等待子线程验证文件完毕,该操作会挂起主线程 //TODO 等待子线程验证文件完毕,该操作会挂起主线程
InternalUpdate(); InternalUpdate();
if (IsDone) if (IsDone)
break; break;
// 短暂休眠避免完全卡死
System.Threading.Thread.Sleep(1);
} }
} }

View File

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

View File

@@ -59,8 +59,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData) if (_steps == ESteps.VerifyFileData)
{ {
string fileHash = HashUtility.BytesCRC32(_fileData); if (ManifestTools.VerifyManifestData(_fileData, _packageHash))
if (fileHash == _packageHash)
{ {
_steps = ESteps.LoadManifest; _steps = ESteps.LoadManifest;
} }
@@ -76,7 +75,7 @@ namespace YooAsset
{ {
if (_deserializer == null) if (_deserializer == null)
{ {
_deserializer = new DeserializeManifestOperation(_fileData); _deserializer = new DeserializeManifestOperation(null, _fileData);
_deserializer.StartOperation(); _deserializer.StartOperation();
AddChildOperation(_deserializer); AddChildOperation(_deserializer);
} }

View File

@@ -14,7 +14,8 @@ namespace YooAsset
base.OnCreate(packageName, rootDirectory); 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); _tempFilesRoot = PathUtility.Combine(_packageRoot, DefaultUnpackFileSystemDefine.TempFilesFolderName);
} }
} }

View File

@@ -3,16 +3,16 @@ namespace YooAsset
{ {
internal class DefaultUnpackFileSystemDefine internal class DefaultUnpackFileSystemDefine
{ {
/// <summary>
/// 文件系统的优先级
/// </summary>
public const int DefaultPriority = 11;
/// <summary> /// <summary>
/// 保存的资源文件的文件夹名称 /// 保存的资源文件的文件夹名称
/// </summary> /// </summary>
public const string SaveFilesFolderName = "UnpackFiles"; public const string SaveBundleFilesFolderName = "UnpackBundleFiles";
/// <summary>
/// 保存的清单文件的文件夹名称
/// </summary>
public const string SaveManifestFilesFolderName = "UnpackManifestFiles";
/// <summary> /// <summary>
/// 下载的临时文件的文件夹名称 /// 下载的临时文件的文件夹名称
/// </summary> /// </summary>

View File

@@ -46,12 +46,17 @@ namespace YooAsset
/// <summary> /// <summary>
/// 自定义参数:跨域下载服务接口 /// 自定义参数:跨域下载服务接口
/// </summary> /// </summary>
public IRemoteServices RemoteServices { private set; get; } = null; public IRemoteServices RemoteServices { private set; get; }
/// <summary> /// <summary>
/// 自定义参数:解密方法类 /// 自定义参数:解密方法类
/// </summary> /// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; } public IWebDecryptionServices DecryptionServices { private set; get; }
/// <summary>
/// 自定义参数:资源清单服务类
/// </summary>
public IManifestServices ManifestServices { private set; get; }
#endregion #endregion
@@ -73,12 +78,12 @@ namespace YooAsset
var operation = new DWRFSRequestPackageVersionOperation(this, appendTimeTicks, timeout); var operation = new DWRFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
return operation; return operation;
} }
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam) public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{ {
var operation = new FSClearCacheFilesCompleteOperation(); var operation = new FSClearCacheFilesCompleteOperation();
return operation; return operation;
} }
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param) public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
@@ -111,6 +116,10 @@ namespace YooAsset
{ {
DecryptionServices = (IWebDecryptionServices)value; DecryptionServices = (IWebDecryptionServices)value;
} }
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES)
{
ManifestServices = (IManifestServices)value;
}
else else
{ {
YooLogger.Warning($"Invalid parameter : {name}"); YooLogger.Warning($"Invalid parameter : {name}");

View File

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

View File

@@ -72,8 +72,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData) if (_steps == ESteps.VerifyFileData)
{ {
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result); if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
if (fileHash == _packageHash)
{ {
_steps = ESteps.LoadManifest; _steps = ESteps.LoadManifest;
} }
@@ -89,7 +88,7 @@ namespace YooAsset
{ {
if (_deserializer == null) if (_deserializer == null)
{ {
_deserializer = new DeserializeManifestOperation(_webDataRequestOp.Result); _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _webDataRequestOp.Result);
_deserializer.StartOperation(); _deserializer.StartOperation();
AddChildOperation(_deserializer); AddChildOperation(_deserializer);
} }

View File

@@ -61,6 +61,11 @@ namespace YooAsset
/// 自定义参数:解密方法类 /// 自定义参数:解密方法类
/// </summary> /// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; } public IWebDecryptionServices DecryptionServices { private set; get; }
/// <summary>
/// 自定义参数:资源清单服务类
/// </summary>
public IManifestServices ManifestServices { private set; get; }
#endregion #endregion
@@ -82,12 +87,12 @@ namespace YooAsset
var operation = new DWSFSRequestPackageVersionOperation(this, timeout); var operation = new DWSFSRequestPackageVersionOperation(this, timeout);
return operation; return operation;
} }
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam) public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{ {
var operation = new FSClearCacheFilesCompleteOperation(); var operation = new FSClearCacheFilesCompleteOperation();
return operation; return operation;
} }
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param) public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
@@ -116,6 +121,10 @@ namespace YooAsset
{ {
DecryptionServices = (IWebDecryptionServices)value; DecryptionServices = (IWebDecryptionServices)value;
} }
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES)
{
ManifestServices = (IManifestServices)value;
}
else else
{ {
YooLogger.Warning($"Invalid parameter : {name}"); YooLogger.Warning($"Invalid parameter : {name}");

View File

@@ -33,10 +33,11 @@ namespace YooAsset
if (_loadCatalogFileOp == null) if (_loadCatalogFileOp == null)
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
/*
// 兼容性初始化 // 兼容性初始化
// 说明:内置文件系统在编辑器下运行时需要动态生成 // 说明:内置文件系统在编辑器下运行时需要动态生成
string packageRoot = _fileSystem.FileRoot; string packageRoot = _fileSystem.FileRoot;
bool result = DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(_fileSystem.PackageName, packageRoot); bool result = DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(_fileSystem.ManifestServices, _fileSystem.PackageName, packageRoot);
if (result == false) if (result == false)
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
@@ -44,6 +45,7 @@ namespace YooAsset
Error = $"Create package catalog file failed ! See the detail error in console !"; Error = $"Create package catalog file failed ! See the detail error in console !";
return; return;
} }
*/
#endif #endif
_loadCatalogFileOp = new LoadWebServerCatalogFileOperation(_fileSystem); _loadCatalogFileOp = new LoadWebServerCatalogFileOperation(_fileSystem);

View File

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

View File

@@ -69,8 +69,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileData) if (_steps == ESteps.VerifyFileData)
{ {
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result); if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
if (fileHash == _packageHash)
{ {
_steps = ESteps.LoadManifest; _steps = ESteps.LoadManifest;
} }
@@ -86,7 +85,7 @@ namespace YooAsset
{ {
if (_deserializer == null) if (_deserializer == null)
{ {
_deserializer = new DeserializeManifestOperation(_webDataRequestOp.Result); _deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _webDataRequestOp.Result);
_deserializer.StartOperation(); _deserializer.StartOperation();
AddChildOperation(_deserializer); AddChildOperation(_deserializer);
} }

View File

@@ -4,8 +4,10 @@ namespace YooAsset
public class FileSystemParametersDefine public class FileSystemParametersDefine
{ {
public const string FILE_VERIFY_LEVEL = "FILE_VERIFY_LEVEL"; 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 REMOTE_SERVICES = "REMOTE_SERVICES";
public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES"; public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES";
public const string MANIFEST_SERVICES = "MANIFEST_SERVICES";
public const string APPEND_FILE_EXTENSION = "APPEND_FILE_EXTENSION"; public const string APPEND_FILE_EXTENSION = "APPEND_FILE_EXTENSION";
public const string DISABLE_CATALOG_FILE = "DISABLE_CATALOG_FILE"; public const string DISABLE_CATALOG_FILE = "DISABLE_CATALOG_FILE";
public const string DISABLE_UNITY_WEB_CACHE = "DISABLE_UNITY_WEB_CACHE"; public const string DISABLE_UNITY_WEB_CACHE = "DISABLE_UNITY_WEB_CACHE";
@@ -17,5 +19,6 @@ namespace YooAsset
public const string ASYNC_SIMULATE_MAX_FRAME = "ASYNC_SIMULATE_MAX_FRAME"; public const string ASYNC_SIMULATE_MAX_FRAME = "ASYNC_SIMULATE_MAX_FRAME";
public const string COPY_BUILDIN_PACKAGE_MANIFEST = "COPY_BUILDIN_PACKAGE_MANIFEST"; public const string COPY_BUILDIN_PACKAGE_MANIFEST = "COPY_BUILDIN_PACKAGE_MANIFEST";
public const string COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT = "COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT"; public const string COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT = "COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT";
public const string COPY_LOCAL_FILE_SERVICES = "COPY_LOCAL_FILE_SERVICES";
} }
} }

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