mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-25 10:11:51 +00:00
Compare commits
50 Commits
2.3.9
...
f0796dccc9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0796dccc9 | ||
|
|
f383c59327 | ||
|
|
e34b9270d2 | ||
|
|
b90ab01fe9 | ||
|
|
236468b4a8 | ||
|
|
6f5fcd55b1 | ||
|
|
4b8f2e3acc | ||
|
|
090e4f4b15 | ||
|
|
53163a75ae | ||
|
|
273401cb20 | ||
|
|
97fe3b0681 | ||
|
|
d401086fd1 | ||
|
|
e3a12ef361 | ||
|
|
1b0288fcd0 | ||
|
|
3ee94fb3b9 | ||
|
|
a0ea80c158 | ||
|
|
264415b362 | ||
|
|
6a76d44c38 | ||
|
|
cebfd57851 | ||
|
|
60eb1c3522 | ||
|
|
40c82835bf | ||
|
|
a13913f572 | ||
|
|
150b46a0a7 | ||
|
|
ebde5a52d3 | ||
|
|
e57466e9e2 | ||
|
|
6f7fca7b34 | ||
|
|
756331fe0b | ||
|
|
5139e2f3a7 | ||
|
|
1c4aba6db5 | ||
|
|
44faa0c5e6 | ||
|
|
72c97341b1 | ||
|
|
9acc240b5a | ||
|
|
ed89e73d26 | ||
|
|
9e33df0375 | ||
|
|
6c98f9a09d | ||
|
|
9ed85afb29 | ||
|
|
560a395173 | ||
|
|
8bce963588 | ||
|
|
f8a3fe47e5 | ||
|
|
48356a4f9e | ||
|
|
d2a28bd801 | ||
|
|
3949abb53f | ||
|
|
06a50a049e | ||
|
|
6f049e2427 | ||
|
|
01c08a46ab | ||
|
|
31dc5b494d | ||
|
|
18e74e906e | ||
|
|
4f62b249b4 | ||
|
|
fe7f9bff08 | ||
|
|
e71077f294 |
@@ -2,6 +2,101 @@
|
||||
|
||||
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
|
||||
|
||||
@@ -196,6 +196,32 @@ namespace YooAsset.Editor
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导入单个报告对象
|
||||
/// </summary>
|
||||
public void ImportSingleReprotFile(ScanReport report)
|
||||
{
|
||||
_reportCombiner = new ScanReportCombiner();
|
||||
|
||||
try
|
||||
{
|
||||
_reportCombiner.Combine(report);
|
||||
|
||||
// 刷新页面
|
||||
RefreshToolbar();
|
||||
FillTableView();
|
||||
RebuildView();
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
_reportCombiner = null;
|
||||
_titleLabel.text = "导入报告失败!";
|
||||
_descLabel.text = e.Message;
|
||||
UnityEngine.Debug.LogError(e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ImportSingleBtn_clicked()
|
||||
{
|
||||
string selectFilePath = EditorUtility.OpenFilePanel("导入报告", _lastestOpenFolder, "json");
|
||||
@@ -446,15 +472,31 @@ namespace YooAsset.Editor
|
||||
var column = new TableColumn(header.HeaderTitle, header.HeaderTitle, columnStyle);
|
||||
column.MakeCell = () =>
|
||||
{
|
||||
var label = new Label();
|
||||
label.style.marginLeft = 3f;
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
return label;
|
||||
if (header.HeaderType == EHeaderType.AssetObject)
|
||||
{
|
||||
var objectFiled = new ObjectField();
|
||||
return objectFiled;
|
||||
}
|
||||
else
|
||||
{
|
||||
var label = new Label();
|
||||
label.style.marginLeft = 3f;
|
||||
label.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
return label;
|
||||
}
|
||||
};
|
||||
column.BindCell = (VisualElement element, ITableData data, ITableCell cell) =>
|
||||
{
|
||||
var infoLabel = element as Label;
|
||||
infoLabel.text = (string)cell.GetDisplayObject();
|
||||
if (header.HeaderType == EHeaderType.AssetObject)
|
||||
{
|
||||
var objectFiled = element as ObjectField;
|
||||
objectFiled.value = (UnityEngine.Object)cell.GetDisplayObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
var infoLabel = element as Label;
|
||||
infoLabel.text = (string)cell.GetDisplayObject();
|
||||
}
|
||||
};
|
||||
_elementTableView.AddColumn(column);
|
||||
}
|
||||
@@ -480,6 +522,10 @@ namespace YooAsset.Editor
|
||||
{
|
||||
tableData.AddAssetPathCell(scanInfo.HeaderTitle, scanInfo.ScanInfo);
|
||||
}
|
||||
else if (header.HeaderType == EHeaderType.AssetObject)
|
||||
{
|
||||
tableData.AddAssetObjectCell(scanInfo.HeaderTitle, scanInfo.ScanInfo);
|
||||
}
|
||||
else if (header.HeaderType == EHeaderType.StringValue)
|
||||
{
|
||||
tableData.AddStringValueCell(scanInfo.HeaderTitle, scanInfo.ScanInfo);
|
||||
|
||||
@@ -8,6 +8,11 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
AssetPath,
|
||||
|
||||
/// <summary>
|
||||
/// 资源对象
|
||||
/// </summary>
|
||||
AssetObject,
|
||||
|
||||
/// <summary>
|
||||
/// 字符串
|
||||
/// </summary>
|
||||
|
||||
@@ -126,6 +126,12 @@ namespace YooAsset.Editor
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
throw new Exception($"{HeaderTitle} value is invalid asset path : {value}");
|
||||
}
|
||||
else if (HeaderType == EHeaderType.AssetObject)
|
||||
{
|
||||
string guid = AssetDatabase.AssetPathToGUID(value);
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
throw new Exception($"{HeaderTitle} value is invalid asset object : {value}");
|
||||
}
|
||||
else if (HeaderType == EHeaderType.DoubleValue)
|
||||
{
|
||||
if (double.TryParse(value, out double doubleValue) == false)
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace YooAsset.Editor
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ScannerResult(e.Message);
|
||||
return new ScannerResult(e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace YooAsset.Editor
|
||||
if (Succeed)
|
||||
{
|
||||
var reproterWindow = AssetArtReporterWindow.OpenWindow();
|
||||
reproterWindow.ImportSingleReprotFile(ReprotFilePath);
|
||||
reproterWindow.ImportSingleReprotFile(Report);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,97 +6,110 @@ namespace YooAsset.Editor
|
||||
{
|
||||
public static class AssetBundleBuilderSetting
|
||||
{
|
||||
// EBuildPipeline
|
||||
public static EBuildPipeline GetPackageBuildPipeline(string packageName)
|
||||
// BuildPipelineName
|
||||
public static string GetPackageBuildPipeline(string packageName)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{nameof(EBuildPipeline)}";
|
||||
return (EBuildPipeline)EditorPrefs.GetInt(key, (int)EBuildPipeline.BuiltinBuildPipeline);
|
||||
string key = $"{Application.productName}_{packageName}_BuildPipelineName";
|
||||
string defaultValue = EBuildPipeline.ScriptableBuildPipeline.ToString();
|
||||
return EditorPrefs.GetString(key, defaultValue);
|
||||
}
|
||||
public static void SetPackageBuildPipeline(string packageName, EBuildPipeline buildPipeline)
|
||||
public static void SetPackageBuildPipeline(string packageName, string buildPipeline)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{nameof(EBuildPipeline)}";
|
||||
EditorPrefs.SetInt(key, (int)buildPipeline);
|
||||
string key = $"{Application.productName}_{packageName}_BuildPipelineName";
|
||||
EditorPrefs.SetString(key, buildPipeline);
|
||||
}
|
||||
|
||||
// ECompressOption
|
||||
public static ECompressOption GetPackageCompressOption(string packageName, EBuildPipeline buildPipeline)
|
||||
public static ECompressOption GetPackageCompressOption(string packageName, string buildPipeline)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(ECompressOption)}";
|
||||
return (ECompressOption)EditorPrefs.GetInt(key, (int)ECompressOption.LZ4);
|
||||
}
|
||||
public static void SetPackageCompressOption(string packageName, EBuildPipeline buildPipeline, ECompressOption compressOption)
|
||||
public static void SetPackageCompressOption(string packageName, string buildPipeline, ECompressOption compressOption)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(ECompressOption)}";
|
||||
EditorPrefs.SetInt(key, (int)compressOption);
|
||||
}
|
||||
|
||||
// EFileNameStyle
|
||||
public static EFileNameStyle GetPackageFileNameStyle(string packageName, EBuildPipeline buildPipeline)
|
||||
public static EFileNameStyle GetPackageFileNameStyle(string packageName, string buildPipeline)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(EFileNameStyle)}";
|
||||
return (EFileNameStyle)EditorPrefs.GetInt(key, (int)EFileNameStyle.HashName);
|
||||
}
|
||||
public static void SetPackageFileNameStyle(string packageName, EBuildPipeline buildPipeline, EFileNameStyle fileNameStyle)
|
||||
public static void SetPackageFileNameStyle(string packageName, string buildPipeline, EFileNameStyle fileNameStyle)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(EFileNameStyle)}";
|
||||
EditorPrefs.SetInt(key, (int)fileNameStyle);
|
||||
}
|
||||
|
||||
// EBuildinFileCopyOption
|
||||
public static EBuildinFileCopyOption GetPackageBuildinFileCopyOption(string packageName, EBuildPipeline buildPipeline)
|
||||
public static EBuildinFileCopyOption GetPackageBuildinFileCopyOption(string packageName, string buildPipeline)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(EBuildinFileCopyOption)}";
|
||||
return (EBuildinFileCopyOption)EditorPrefs.GetInt(key, (int)EBuildinFileCopyOption.None);
|
||||
}
|
||||
public static void SetPackageBuildinFileCopyOption(string packageName, EBuildPipeline buildPipeline, EBuildinFileCopyOption buildinFileCopyOption)
|
||||
public static void SetPackageBuildinFileCopyOption(string packageName, string buildPipeline, EBuildinFileCopyOption buildinFileCopyOption)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_{nameof(EBuildinFileCopyOption)}";
|
||||
EditorPrefs.SetInt(key, (int)buildinFileCopyOption);
|
||||
}
|
||||
|
||||
// BuildFileCopyParams
|
||||
public static string GetPackageBuildinFileCopyParams(string packageName, EBuildPipeline buildPipeline)
|
||||
public static string GetPackageBuildinFileCopyParams(string packageName, string buildPipeline)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_BuildFileCopyParams";
|
||||
return EditorPrefs.GetString(key, string.Empty);
|
||||
}
|
||||
public static void SetPackageBuildinFileCopyParams(string packageName, EBuildPipeline buildPipeline, string buildinFileCopyParams)
|
||||
public static void SetPackageBuildinFileCopyParams(string packageName, string buildPipeline, string buildinFileCopyParams)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_BuildFileCopyParams";
|
||||
EditorPrefs.SetString(key, buildinFileCopyParams);
|
||||
}
|
||||
|
||||
// EncyptionClassName
|
||||
public static string GetPackageEncyptionClassName(string packageName, EBuildPipeline buildPipeline)
|
||||
// EncyptionServicesClassName
|
||||
public static string GetPackageEncyptionServicesClassName(string packageName, string buildPipeline)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_EncyptionClassName";
|
||||
return EditorPrefs.GetString(key, string.Empty);
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_EncyptionServicesClassName";
|
||||
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);
|
||||
}
|
||||
|
||||
// ClearBuildCache
|
||||
public static bool GetPackageClearBuildCache(string packageName, EBuildPipeline buildPipeline)
|
||||
public static bool GetPackageClearBuildCache(string packageName, string buildPipeline)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_ClearBuildCache";
|
||||
return EditorPrefs.GetInt(key, 0) > 0;
|
||||
}
|
||||
public static void SetPackageClearBuildCache(string packageName, EBuildPipeline buildPipeline, bool clearBuildCache)
|
||||
public static void SetPackageClearBuildCache(string packageName, string buildPipeline, bool clearBuildCache)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_ClearBuildCache";
|
||||
EditorPrefs.SetInt(key, clearBuildCache ? 1 : 0);
|
||||
}
|
||||
|
||||
// UseAssetDependencyDB
|
||||
public static bool GetPackageUseAssetDependencyDB(string packageName, EBuildPipeline buildPipeline)
|
||||
public static bool GetPackageUseAssetDependencyDB(string packageName, string buildPipeline)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_UseAssetDependencyDB";
|
||||
return EditorPrefs.GetInt(key, 0) > 0;
|
||||
}
|
||||
public static void SetPackageUseAssetDependencyDB(string packageName, EBuildPipeline buildPipeline, bool useAssetDependencyDB)
|
||||
public static void SetPackageUseAssetDependencyDB(string packageName, string buildPipeline, bool useAssetDependencyDB)
|
||||
{
|
||||
string key = $"{Application.productName}_{packageName}_{buildPipeline}_UseAssetDependencyDB";
|
||||
EditorPrefs.SetInt(key, useAssetDependencyDB ? 1 : 0);
|
||||
|
||||
@@ -19,7 +19,9 @@ namespace YooAsset.Editor
|
||||
}
|
||||
|
||||
private string _buildPackage;
|
||||
private EBuildPipeline _buildPipeline;
|
||||
private string _buildPipeline;
|
||||
|
||||
private Dictionary<string, Type> _viewClassDic = new Dictionary<string, Type>(10);
|
||||
|
||||
private Toolbar _toolbar;
|
||||
private ToolbarMenu _packageMenu;
|
||||
@@ -69,11 +71,23 @@ namespace YooAsset.Editor
|
||||
{
|
||||
_pipelineMenu = new ToolbarMenu();
|
||||
_pipelineMenu.style.width = 200;
|
||||
_pipelineMenu.menu.AppendAction(EBuildPipeline.EditorSimulateBuildPipeline.ToString(), PipelineMenuAction, PipelineMenuFun, EBuildPipeline.EditorSimulateBuildPipeline);
|
||||
_pipelineMenu.menu.AppendAction(EBuildPipeline.BuiltinBuildPipeline.ToString(), PipelineMenuAction, PipelineMenuFun, EBuildPipeline.BuiltinBuildPipeline);
|
||||
_pipelineMenu.menu.AppendAction(EBuildPipeline.ScriptableBuildPipeline.ToString(), PipelineMenuAction, PipelineMenuFun, EBuildPipeline.ScriptableBuildPipeline);
|
||||
_pipelineMenu.menu.AppendAction(EBuildPipeline.RawFileBuildPipeline.ToString(), PipelineMenuAction, PipelineMenuFun, EBuildPipeline.RawFileBuildPipeline);
|
||||
_toolbar.Add(_pipelineMenu);
|
||||
|
||||
var viewerClassTypes = EditorTools.GetAssignableTypes(typeof(BuildPipelineViewerBase));
|
||||
foreach (var classType in viewerClassTypes)
|
||||
{
|
||||
var buildPipelineAttribute = EditorTools.GetAttribute<BuildPipelineAttribute>(classType);
|
||||
string pipelineName = buildPipelineAttribute.PipelineName;
|
||||
if (_viewClassDic.ContainsKey(pipelineName))
|
||||
{
|
||||
Debug.LogWarning($"The pipeline has already exist : {pipelineName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_viewClassDic.Add(pipelineName, classType);
|
||||
_pipelineMenu.menu.AppendAction(pipelineName, PipelineMenuAction, PipelineMenuFun);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RefreshBuildPipelineView();
|
||||
@@ -91,28 +105,18 @@ namespace YooAsset.Editor
|
||||
|
||||
_buildPipeline = AssetBundleBuilderSetting.GetPackageBuildPipeline(_buildPackage);
|
||||
_packageMenu.text = _buildPackage;
|
||||
_pipelineMenu.text = _buildPipeline.ToString();
|
||||
_pipelineMenu.text = _buildPipeline;
|
||||
|
||||
var buildTarget = EditorUserBuildSettings.activeBuildTarget;
|
||||
if (_buildPipeline == EBuildPipeline.EditorSimulateBuildPipeline)
|
||||
if (_viewClassDic.TryGetValue(_buildPipeline, out Type value))
|
||||
{
|
||||
var viewer = new EditorSimulateBuildPipelineViewer(_buildPackage, buildTarget, _container);
|
||||
}
|
||||
else if (_buildPipeline == EBuildPipeline.BuiltinBuildPipeline)
|
||||
{
|
||||
var viewer = new BuiltinBuildPipelineViewer(_buildPackage, buildTarget, _container);
|
||||
}
|
||||
else if (_buildPipeline == EBuildPipeline.ScriptableBuildPipeline)
|
||||
{
|
||||
var viewer = new ScriptableBuildPipelineViewer(_buildPackage, buildTarget, _container);
|
||||
}
|
||||
else if (_buildPipeline == EBuildPipeline.RawFileBuildPipeline)
|
||||
{
|
||||
var viewer = new RawfileBuildpipelineViewer(_buildPackage, buildTarget, _container);
|
||||
var buildTarget = EditorUserBuildSettings.activeBuildTarget;
|
||||
var viewer = Activator.CreateInstance(value) as BuildPipelineViewerBase;
|
||||
viewer.InitView(_buildPackage, _buildPipeline, buildTarget);
|
||||
viewer.CreateView(_container);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException(_buildPipeline.ToString());
|
||||
Debug.LogError($"Not found build pipeline : {_buildPipeline}");
|
||||
}
|
||||
}
|
||||
private List<string> GetBuildPackageNames()
|
||||
@@ -145,18 +149,16 @@ namespace YooAsset.Editor
|
||||
|
||||
private void PipelineMenuAction(DropdownMenuAction action)
|
||||
{
|
||||
var pipelineType = (EBuildPipeline)action.userData;
|
||||
if (_buildPipeline != pipelineType)
|
||||
if (_buildPipeline != action.name)
|
||||
{
|
||||
_buildPipeline = pipelineType;
|
||||
AssetBundleBuilderSetting.SetPackageBuildPipeline(_buildPackage, pipelineType);
|
||||
_buildPipeline = action.name;
|
||||
AssetBundleBuilderSetting.SetPackageBuildPipeline(_buildPackage, _buildPipeline);
|
||||
RefreshBuildPipelineView();
|
||||
}
|
||||
}
|
||||
private DropdownMenuAction.Status PipelineMenuFun(DropdownMenuAction action)
|
||||
{
|
||||
var pipelineType = (EBuildPipeline)action.userData;
|
||||
if (_buildPipeline == pipelineType)
|
||||
if (_buildPipeline == action.name)
|
||||
return DropdownMenuAction.Status.Checked;
|
||||
else
|
||||
return DropdownMenuAction.Status.Normal;
|
||||
|
||||
@@ -98,6 +98,11 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
public IEncryptionServices EncryptionServices;
|
||||
|
||||
/// <summary>
|
||||
/// 资源清单服务类
|
||||
/// </summary>
|
||||
public IManifestServices ManifestServices;
|
||||
|
||||
|
||||
private string _pipelineOutputDirectory = string.Empty;
|
||||
private string _packageOutputDirectory = string.Empty;
|
||||
|
||||
@@ -14,7 +14,8 @@ namespace YooAsset.Editor
|
||||
{
|
||||
string buildinRootDirectory = buildParametersContext.GetBuildinRootDirectory();
|
||||
string buildPackageName = buildParametersContext.Parameters.PackageName;
|
||||
DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(buildPackageName, buildinRootDirectory);
|
||||
var manifestServices = buildParametersContext.Parameters.ManifestServices;
|
||||
DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(manifestServices, buildPackageName, buildinRootDirectory);
|
||||
|
||||
// 刷新目录
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace YooAsset.Editor
|
||||
if (processBundleDepends)
|
||||
ProcessBuiltinBundleDependency(context, manifest);
|
||||
|
||||
// 创建补丁清单文本文件
|
||||
// 创建资源清单文本文件
|
||||
{
|
||||
string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||
string filePath = $"{packageOutputDirectory}/{fileName}";
|
||||
@@ -66,18 +66,18 @@ namespace YooAsset.Editor
|
||||
BuildLogger.Log($"Create package manifest file: {filePath}");
|
||||
}
|
||||
|
||||
// 创建补丁清单二进制文件
|
||||
// 创建资源清单二进制文件
|
||||
string packageHash;
|
||||
string packagePath;
|
||||
{
|
||||
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||
packagePath = $"{packageOutputDirectory}/{fileName}";
|
||||
ManifestTools.SerializeToBinary(packagePath, manifest);
|
||||
ManifestTools.SerializeToBinary(packagePath, manifest, buildParameters.ManifestServices);
|
||||
packageHash = HashUtility.FileCRC32(packagePath);
|
||||
BuildLogger.Log($"Create package manifest file: {packagePath}");
|
||||
}
|
||||
|
||||
// 创建补丁清单哈希文件
|
||||
// 创建资源清单哈希文件
|
||||
{
|
||||
string fileName = YooAssetSettingsData.GetPackageHashFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||
string filePath = $"{packageOutputDirectory}/{fileName}";
|
||||
@@ -85,7 +85,7 @@ namespace YooAsset.Editor
|
||||
BuildLogger.Log($"Create package manifest hash file: {filePath}");
|
||||
}
|
||||
|
||||
// 创建补丁清单版本文件
|
||||
// 创建资源清单版本文件
|
||||
{
|
||||
string fileName = YooAssetSettingsData.GetPackageVersionFileName(buildParameters.PackageName);
|
||||
string filePath = $"{packageOutputDirectory}/{fileName}";
|
||||
@@ -97,7 +97,7 @@ namespace YooAsset.Editor
|
||||
{
|
||||
ManifestContext manifestContext = new ManifestContext();
|
||||
byte[] bytesData = FileUtility.ReadAllBytes(packagePath);
|
||||
manifestContext.Manifest = ManifestTools.DeserializeFromBinary(bytesData);
|
||||
manifestContext.Manifest = ManifestTools.DeserializeFromBinary(bytesData, buildParameters.ManifestServices);
|
||||
context.SetContextObject(manifestContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,8 @@ namespace YooAsset.Editor
|
||||
buildReport.Summary.EnableSharePackRule = buildParameters.EnableSharePackRule;
|
||||
buildReport.Summary.SingleReferencedPackAlone = buildParameters.SingleReferencedPackAlone;
|
||||
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)
|
||||
{
|
||||
var builtinBuildParameters = buildParameters as BuiltinBuildParameters;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94254ab8e4496214884c11a891c131c6
|
||||
guid: 446513b0ea9f5d445ade0cfb09c5073b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -1,8 +1,13 @@
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public interface IBuildPipeline
|
||||
{
|
||||
/// <summary>
|
||||
/// 运行构建任务
|
||||
/// </summary>
|
||||
BuildResult Run(BuildParameters buildParameters, bool enableLog);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class BuildPipelineAttribute : Attribute
|
||||
{
|
||||
public string PipelineName;
|
||||
|
||||
public BuildPipelineAttribute(string name)
|
||||
{
|
||||
this.PipelineName = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8088863fc7dfbd441bc897380cd7b97f
|
||||
guid: 90d865a5cede7ae43a5fdabdc20af0fd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -12,211 +12,224 @@ namespace YooAsset.Editor
|
||||
{
|
||||
internal abstract class BuildPipelineViewerBase
|
||||
{
|
||||
private const int StyleWidth = 400;
|
||||
private const int LabelMinWidth = 180;
|
||||
protected const int StyleWidth = 400;
|
||||
protected const int LabelMinWidth = 190;
|
||||
|
||||
protected readonly string PackageName;
|
||||
protected readonly BuildTarget BuildTarget;
|
||||
protected readonly EBuildPipeline BuildPipeline;
|
||||
protected TemplateContainer Root;
|
||||
protected string PackageName { private set; get; }
|
||||
protected string PipelineName { private set; get; }
|
||||
protected BuildTarget BuildTarget { private set; get; }
|
||||
|
||||
private TextField _buildOutputField;
|
||||
private TextField _buildVersionField;
|
||||
private PopupField<Enum> _buildModeField;
|
||||
private PopupField<Type> _encryptionField;
|
||||
private EnumField _compressionField;
|
||||
private EnumField _outputNameStyleField;
|
||||
private EnumField _copyBuildinFileOptionField;
|
||||
private TextField _copyBuildinFileTagsField;
|
||||
private Toggle _clearBuildCacheToggle;
|
||||
private Toggle _useAssetDependencyDBToggle;
|
||||
|
||||
public BuildPipelineViewerBase(string packageName, EBuildPipeline buildPipeline, BuildTarget buildTarget, VisualElement parent)
|
||||
/// <summary>
|
||||
/// 初始化视图
|
||||
/// </summary>
|
||||
public void InitView(string packageName, string pipelineName, BuildTarget buildTarget)
|
||||
{
|
||||
PackageName = packageName;
|
||||
PipelineName = pipelineName;
|
||||
BuildTarget = buildTarget;
|
||||
BuildPipeline = buildPipeline;
|
||||
|
||||
CreateView(parent);
|
||||
RefreshView();
|
||||
}
|
||||
private void CreateView(VisualElement parent)
|
||||
{
|
||||
// 加载布局文件
|
||||
var visualAsset = UxmlLoader.LoadWindowUXML<BuildPipelineViewerBase>();
|
||||
if (visualAsset == null)
|
||||
return;
|
||||
|
||||
Root = visualAsset.CloneTree();
|
||||
Root.style.flexGrow = 1f;
|
||||
parent.Add(Root);
|
||||
|
||||
// 输出目录
|
||||
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
|
||||
_buildOutputField = Root.Q<TextField>("BuildOutput");
|
||||
_buildOutputField.SetValueWithoutNotify(defaultOutputRoot);
|
||||
_buildOutputField.SetEnabled(false);
|
||||
|
||||
// 构建版本
|
||||
_buildVersionField = Root.Q<TextField>("BuildVersion");
|
||||
_buildVersionField.style.width = StyleWidth;
|
||||
_buildVersionField.SetValueWithoutNotify(GetDefaultPackageVersion());
|
||||
|
||||
// 加密方法
|
||||
{
|
||||
var encryptionContainer = Root.Q("EncryptionContainer");
|
||||
var encryptionClassTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices));
|
||||
if (encryptionClassTypes.Count > 0)
|
||||
{
|
||||
var encyptionClassName = AssetBundleBuilderSetting.GetPackageEncyptionClassName(PackageName, BuildPipeline);
|
||||
int defaultIndex = encryptionClassTypes.FindIndex(x => x.FullName.Equals(encyptionClassName));
|
||||
if (defaultIndex < 0)
|
||||
defaultIndex = 0;
|
||||
_encryptionField = new PopupField<Type>(encryptionClassTypes, defaultIndex);
|
||||
_encryptionField.label = "Encryption";
|
||||
_encryptionField.style.width = StyleWidth;
|
||||
_encryptionField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
AssetBundleBuilderSetting.SetPackageEncyptionClassName(PackageName, BuildPipeline, _encryptionField.value.FullName);
|
||||
});
|
||||
encryptionContainer.Add(_encryptionField);
|
||||
}
|
||||
else
|
||||
{
|
||||
_encryptionField = new PopupField<Type>();
|
||||
_encryptionField.label = "Encryption";
|
||||
_encryptionField.style.width = StyleWidth;
|
||||
encryptionContainer.Add(_encryptionField);
|
||||
}
|
||||
}
|
||||
|
||||
// 压缩方式选项
|
||||
var compressOption = AssetBundleBuilderSetting.GetPackageCompressOption(PackageName, BuildPipeline);
|
||||
_compressionField = Root.Q<EnumField>("Compression");
|
||||
_compressionField.Init(compressOption);
|
||||
_compressionField.SetValueWithoutNotify(compressOption);
|
||||
_compressionField.style.width = StyleWidth;
|
||||
_compressionField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
AssetBundleBuilderSetting.SetPackageCompressOption(PackageName, BuildPipeline, (ECompressOption)_compressionField.value);
|
||||
});
|
||||
|
||||
// 输出文件名称样式
|
||||
var fileNameStyle = AssetBundleBuilderSetting.GetPackageFileNameStyle(PackageName, BuildPipeline);
|
||||
_outputNameStyleField = Root.Q<EnumField>("FileNameStyle");
|
||||
_outputNameStyleField.Init(fileNameStyle);
|
||||
_outputNameStyleField.SetValueWithoutNotify(fileNameStyle);
|
||||
_outputNameStyleField.style.width = StyleWidth;
|
||||
_outputNameStyleField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
AssetBundleBuilderSetting.SetPackageFileNameStyle(PackageName, BuildPipeline, (EFileNameStyle)_outputNameStyleField.value);
|
||||
});
|
||||
|
||||
// 首包文件拷贝选项
|
||||
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, BuildPipeline);
|
||||
_copyBuildinFileOptionField = Root.Q<EnumField>("CopyBuildinFileOption");
|
||||
_copyBuildinFileOptionField.Init(buildinFileCopyOption);
|
||||
_copyBuildinFileOptionField.SetValueWithoutNotify(buildinFileCopyOption);
|
||||
_copyBuildinFileOptionField.style.width = StyleWidth;
|
||||
_copyBuildinFileOptionField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
AssetBundleBuilderSetting.SetPackageBuildinFileCopyOption(PackageName, BuildPipeline, (EBuildinFileCopyOption)_copyBuildinFileOptionField.value);
|
||||
RefreshView();
|
||||
});
|
||||
|
||||
// 首包文件拷贝参数
|
||||
var buildinFileCopyParams = AssetBundleBuilderSetting.GetPackageBuildinFileCopyParams(PackageName, BuildPipeline);
|
||||
_copyBuildinFileTagsField = Root.Q<TextField>("CopyBuildinFileParam");
|
||||
_copyBuildinFileTagsField.SetValueWithoutNotify(buildinFileCopyParams);
|
||||
_copyBuildinFileTagsField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
AssetBundleBuilderSetting.SetPackageBuildinFileCopyParams(PackageName, BuildPipeline, _copyBuildinFileTagsField.value);
|
||||
});
|
||||
|
||||
// 清理构建缓存
|
||||
bool clearBuildCache = AssetBundleBuilderSetting.GetPackageClearBuildCache(PackageName, BuildPipeline);
|
||||
_clearBuildCacheToggle = Root.Q<Toggle>("ClearBuildCache");
|
||||
_clearBuildCacheToggle.SetValueWithoutNotify(clearBuildCache);
|
||||
_clearBuildCacheToggle.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
AssetBundleBuilderSetting.SetPackageClearBuildCache(PackageName, BuildPipeline, _clearBuildCacheToggle.value);
|
||||
});
|
||||
|
||||
// 使用资源依赖数据库
|
||||
bool useAssetDependencyDB = AssetBundleBuilderSetting.GetPackageUseAssetDependencyDB(PackageName, BuildPipeline);
|
||||
_useAssetDependencyDBToggle = Root.Q<Toggle>("UseAssetDependency");
|
||||
_useAssetDependencyDBToggle.SetValueWithoutNotify(useAssetDependencyDB);
|
||||
_useAssetDependencyDBToggle.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
AssetBundleBuilderSetting.SetPackageUseAssetDependencyDB(PackageName, BuildPipeline, _useAssetDependencyDBToggle.value);
|
||||
});
|
||||
|
||||
// 对齐文本间距
|
||||
UIElementsTools.SetElementLabelMinWidth(_buildOutputField, LabelMinWidth);
|
||||
UIElementsTools.SetElementLabelMinWidth(_buildVersionField, LabelMinWidth);
|
||||
UIElementsTools.SetElementLabelMinWidth(_compressionField, LabelMinWidth);
|
||||
UIElementsTools.SetElementLabelMinWidth(_encryptionField, LabelMinWidth);
|
||||
UIElementsTools.SetElementLabelMinWidth(_outputNameStyleField, LabelMinWidth);
|
||||
UIElementsTools.SetElementLabelMinWidth(_copyBuildinFileOptionField, LabelMinWidth);
|
||||
UIElementsTools.SetElementLabelMinWidth(_copyBuildinFileTagsField, LabelMinWidth);
|
||||
UIElementsTools.SetElementLabelMinWidth(_clearBuildCacheToggle, LabelMinWidth);
|
||||
UIElementsTools.SetElementLabelMinWidth(_useAssetDependencyDBToggle, LabelMinWidth);
|
||||
|
||||
// 构建按钮
|
||||
var buildButton = Root.Q<Button>("Build");
|
||||
buildButton.clicked += BuildButton_clicked;
|
||||
}
|
||||
private void RefreshView()
|
||||
{
|
||||
var buildinFileCopyOption = AssetBundleBuilderSetting.GetPackageBuildinFileCopyOption(PackageName, BuildPipeline);
|
||||
bool tagsFiledVisible = buildinFileCopyOption == EBuildinFileCopyOption.ClearAndCopyByTags || buildinFileCopyOption == EBuildinFileCopyOption.OnlyCopyByTags;
|
||||
_copyBuildinFileTagsField.visible = tagsFiledVisible;
|
||||
}
|
||||
private void BuildButton_clicked()
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("提示", $"开始构建资源包[{PackageName}]!", "Yes", "No"))
|
||||
{
|
||||
EditorTools.ClearUnityConsole();
|
||||
EditorApplication.delayCall += ExecuteBuild;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[Build] 打包已经取消");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行构建任务
|
||||
/// 创建视图
|
||||
/// </summary>
|
||||
protected abstract void ExecuteBuild();
|
||||
public abstract void CreateView(VisualElement parent);
|
||||
|
||||
/// <summary>
|
||||
/// 获取构建版本
|
||||
/// 获取默认版本
|
||||
/// </summary>
|
||||
protected string GetPackageVersion()
|
||||
protected virtual string GetDefaultPackageVersion()
|
||||
{
|
||||
return _buildVersionField.value;
|
||||
int totalMinutes = DateTime.Now.Hour * 60 + DateTime.Now.Minute;
|
||||
return DateTime.Now.ToString("yyyy-MM-dd") + "-" + totalMinutes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建加密类实例
|
||||
/// 创建资源加密服务类实例
|
||||
/// </summary>
|
||||
protected IEncryptionServices CreateEncryptionInstance()
|
||||
protected IEncryptionServices CreateEncryptionServicesInstance()
|
||||
{
|
||||
var encyptionClassName = AssetBundleBuilderSetting.GetPackageEncyptionClassName(PackageName, BuildPipeline);
|
||||
var encryptionClassTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices));
|
||||
var classType = encryptionClassTypes.Find(x => x.FullName.Equals(encyptionClassName));
|
||||
var className = AssetBundleBuilderSetting.GetPackageEncyptionServicesClassName(PackageName, PipelineName);
|
||||
var classTypes = EditorTools.GetAssignableTypes(typeof(IEncryptionServices));
|
||||
var classType = classTypes.Find(x => x.FullName.Equals(className));
|
||||
if (classType != null)
|
||||
return (IEncryptionServices)Activator.CreateInstance(classType);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private string GetDefaultPackageVersion()
|
||||
/// <summary>
|
||||
/// 创建资源清单服务类实例
|
||||
/// </summary>
|
||||
protected IManifestServices CreateManifestServicesInstance()
|
||||
{
|
||||
int totalMinutes = DateTime.Now.Hour * 60 + DateTime.Now.Minute;
|
||||
return DateTime.Now.ToString("yyyy-MM-dd") + "-" + totalMinutes;
|
||||
var className = AssetBundleBuilderSetting.GetPackageManifestServicesClassName(PackageName, PipelineName);
|
||||
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
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5280dfac6a481ee429c769ba5688c9d2
|
||||
guid: e2e1fae9b05cc554e9ebfee01f2b9333
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -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
|
||||
@@ -4,7 +4,7 @@
|
||||
<ui:TextField picking-mode="Ignore" label="Build Version" name="BuildVersion" />
|
||||
<ui:Toggle label="Clear Build Cache" name="ClearBuildCache" />
|
||||
<ui:Toggle label="Use Asset Depend DB" name="UseAssetDependency" />
|
||||
<ui:VisualElement name="EncryptionContainer" style="height: 24px;" />
|
||||
<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" />
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86d0df373d425b449a3bbc42b4b2e5bb
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
@@ -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
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 33b6cb215b1d7bb4888cb3455b500399
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90cc4546b2b8afe4e8c864c132a999a9
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
@@ -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
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 56adb3acd233fe5468af213a4c41de6a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ed3387ab250c814e9797164c9a4b89a
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
|
||||
@@ -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
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be39d027dec0b2f41ab1dba7effb1a9c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -265,7 +265,7 @@ namespace YooAsset.Editor
|
||||
}
|
||||
private static string GetRuleDisplayName(string name, Type type)
|
||||
{
|
||||
var attribute = DisplayNameAttributeHelper.GetAttribute<DisplayNameAttribute>(type);
|
||||
var attribute = EditorTools.GetAttribute<DisplayNameAttribute>(type);
|
||||
if (attribute != null && string.IsNullOrEmpty(attribute.DisplayName) == false)
|
||||
return attribute.DisplayName;
|
||||
else
|
||||
|
||||
@@ -762,6 +762,7 @@ namespace YooAsset.Editor
|
||||
elementTop.Add(objectField);
|
||||
var label = objectField.Q<Label>();
|
||||
label.style.minWidth = 63;
|
||||
UIElementsTools.SetObjectFieldShowPath(objectField);
|
||||
}
|
||||
|
||||
// Bottom VisualElement
|
||||
@@ -851,8 +852,6 @@ namespace YooAsset.Editor
|
||||
|
||||
var collector = selectGroup.Collectors[index];
|
||||
var collectObject = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(collector.CollectPath);
|
||||
if (collectObject != null)
|
||||
collectObject.name = collector.CollectPath;
|
||||
|
||||
// 注意:非主资源收集器的标签栏需要被冻结
|
||||
var textTags = element.Q<TextField>("TextField1");
|
||||
@@ -885,13 +884,13 @@ namespace YooAsset.Editor
|
||||
{
|
||||
collector.CollectPath = AssetDatabase.GetAssetPath(evt.newValue);
|
||||
collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath);
|
||||
objectField1.value.name = collector.CollectPath;
|
||||
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
|
||||
if (foldout.value)
|
||||
{
|
||||
RefreshFoldout(foldout, selectGroup, collector);
|
||||
}
|
||||
});
|
||||
UIElementsTools.RefreshObjectFieldShowPath(objectField1);
|
||||
|
||||
// Collector Type
|
||||
var popupField0 = element.Q<PopupField<string>>("PopupField0");
|
||||
|
||||
@@ -70,7 +70,11 @@ namespace YooAsset.Editor
|
||||
foreach (var cacheInfoPair in _database)
|
||||
{
|
||||
var assetPath = cacheInfoPair.Key;
|
||||
#if UNITY_2021_3_OR_NEWER
|
||||
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath, AssetPathToGUIDOptions.OnlyExistingAssets);
|
||||
#else
|
||||
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(assetGUID))
|
||||
{
|
||||
removeList.Add(assetPath);
|
||||
@@ -173,26 +177,42 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
public string[] GetDependencies(string assetPath, bool recursive)
|
||||
{
|
||||
// 注意:AssetDatabase.GetDependencies()方法返回结果里会踢出丢失文件!
|
||||
// 注意:AssetDatabase.GetDependencies()方法返回结果里会包含主资源路径!
|
||||
|
||||
// 注意:机制上不允许存在未收录的资源
|
||||
if (_database.ContainsKey(assetPath) == false)
|
||||
{
|
||||
throw new Exception($"Fatal : can not found cache info : {assetPath}");
|
||||
}
|
||||
|
||||
var result = new HashSet<string> { assetPath };
|
||||
CollectDependencies(assetPath, result, recursive);
|
||||
var result = new HashSet<string>();
|
||||
|
||||
// 注意:递归收集依赖时,依赖列表中包含主资源
|
||||
if (recursive)
|
||||
result.Add(assetPath);
|
||||
|
||||
// 收集依赖
|
||||
CollectDependencies(assetPath, assetPath, result, recursive);
|
||||
|
||||
// 注意:AssetDatabase.GetDependencies保持一致,将主资源添加到依赖列表最前面
|
||||
return result.ToArray();
|
||||
}
|
||||
private void CollectDependencies(string assetPath, HashSet<string> result, bool recursive)
|
||||
private void CollectDependencies(string parent, string assetPath, HashSet<string> result, bool recursive)
|
||||
{
|
||||
if (_database.TryGetValue(assetPath, out var cacheInfo) == false)
|
||||
{
|
||||
throw new Exception($"Fatal : can not found cache info : {assetPath}");
|
||||
// 说明:检测是否为丢失引用的资产
|
||||
#if UNITY_2021_3_OR_NEWER
|
||||
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath, AssetPathToGUIDOptions.OnlyExistingAssets);
|
||||
#else
|
||||
var assetGUID = AssetDatabase.AssetPathToGUID(assetPath);
|
||||
#endif
|
||||
if (string.IsNullOrEmpty(assetGUID))
|
||||
{
|
||||
Debug.LogWarning($"{parent} found missing asset : {assetPath}");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Fatal : can not found cache info : {assetPath}");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var dependGUID in cacheInfo.DependGUIDs)
|
||||
@@ -213,7 +233,7 @@ namespace YooAsset.Editor
|
||||
|
||||
// 递归收集依赖
|
||||
if (recursive)
|
||||
CollectDependencies(dependAssetPath, result, recursive);
|
||||
CollectDependencies(assetPath, dependAssetPath, result, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,6 +257,7 @@ namespace YooAsset.Editor
|
||||
}
|
||||
private DependencyInfo CreateDependencyInfo(string assetPath)
|
||||
{
|
||||
// 注意:AssetDatabase.GetDependencies()方法返回结果里会踢出丢失文件!
|
||||
var dependHash = AssetDatabase.GetAssetDependencyHash(assetPath);
|
||||
var dependAssetPaths = AssetDatabase.GetDependencies(assetPath, false);
|
||||
var dependGUIDs = new List<string>();
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
@@ -15,22 +14,4 @@ namespace YooAsset.Editor
|
||||
this.DisplayName = name;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DisplayNameAttributeHelper
|
||||
{
|
||||
internal static T GetAttribute<T>(Type type) where T : Attribute
|
||||
{
|
||||
return (T)type.GetCustomAttribute(typeof(T), false);
|
||||
}
|
||||
|
||||
internal static T GetAttribute<T>(MethodInfo methodInfo) where T : Attribute
|
||||
{
|
||||
return (T)methodInfo.GetCustomAttribute(typeof(T), false);
|
||||
}
|
||||
|
||||
internal static T GetAttribute<T>(FieldInfo field) where T : Attribute
|
||||
{
|
||||
return (T)field.GetCustomAttribute(typeof(T), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,9 +71,10 @@ namespace YooAsset.Editor
|
||||
public bool UseAssetDependencyDB;
|
||||
public bool EnableSharePackRule;
|
||||
public bool SingleReferencedPackAlone;
|
||||
public string EncryptionClassName;
|
||||
public string EncryptionServicesClassName;
|
||||
public string ManifestServicesClassName;
|
||||
public EFileNameStyle FileNameStyle;
|
||||
|
||||
|
||||
// 引擎参数
|
||||
public ECompressOption CompressOption;
|
||||
public bool DisableWriteTypeTree;
|
||||
|
||||
@@ -66,7 +66,8 @@ namespace YooAsset.Editor
|
||||
BindListViewItem("Use Asset Dependency DB", $"{buildReport.Summary.UseAssetDependencyDB}");
|
||||
BindListViewItem("Enable Share Pack Rule", $"{buildReport.Summary.EnableSharePackRule}");
|
||||
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("CompressOption", $"{buildReport.Summary.CompressOption}");
|
||||
BindListViewItem("DisableWriteTypeTree", $"{buildReport.Summary.DisableWriteTypeTree}");
|
||||
|
||||
@@ -129,6 +129,23 @@ namespace YooAsset.Editor
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Attribute
|
||||
public static T GetAttribute<T>(Type type) where T : Attribute
|
||||
{
|
||||
return (T)type.GetCustomAttribute(typeof(T), false);
|
||||
}
|
||||
|
||||
public static T GetAttribute<T>(MethodInfo methodInfo) where T : Attribute
|
||||
{
|
||||
return (T)methodInfo.GetCustomAttribute(typeof(T), false);
|
||||
}
|
||||
|
||||
public static T GetAttribute<T>(FieldInfo field) where T : Attribute
|
||||
{
|
||||
return (T)field.GetCustomAttribute(typeof(T), false);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PackageManager
|
||||
public static string GetPackageManagerYooVersion()
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39db4a569a0f69443a7675e19c99c389
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -31,9 +31,14 @@ namespace YooAsset.Editor
|
||||
var cell = new ButtonCell(searchTag);
|
||||
Cells.Add(cell);
|
||||
}
|
||||
public void AddAssetPathCell(string searchTag, string path)
|
||||
public void AddAssetPathCell(string searchTag, string assetPath)
|
||||
{
|
||||
var cell = new AssetPathCell(searchTag, path);
|
||||
var cell = new AssetPathCell(searchTag, assetPath);
|
||||
Cells.Add(cell);
|
||||
}
|
||||
public void AddAssetObjectCell(string searchTag, string assetPath)
|
||||
{
|
||||
var cell = new AssetObjectCell(searchTag, assetPath);
|
||||
Cells.Add(cell);
|
||||
}
|
||||
public void AddStringValueCell(string searchTag, string value)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[assembly: InternalsVisibleTo("YooAsset.Test.Editor")]
|
||||
|
||||
// 外部友元
|
||||
[assembly: InternalsVisibleTo("YooAsset.MiniGame")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.RuntimeExtension")]
|
||||
[assembly: InternalsVisibleTo("YooAsset.EditorExtension")]
|
||||
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor")]
|
||||
@@ -69,6 +69,8 @@ namespace YooAsset
|
||||
url = new System.Uri(path).ToString();
|
||||
#elif UNITY_STANDALONE || UNITY_WSA
|
||||
url = StringUtility.Format("file:///{0}", path);
|
||||
#elif UNITY_TVOS
|
||||
url = StringUtility.Format("file:///{0}", path);
|
||||
#else
|
||||
throw new System.NotImplementedException();
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class UnityAssetBundleRequestOperation : UnityWebRequestOperation
|
||||
{
|
||||
protected enum ESteps
|
||||
{
|
||||
None,
|
||||
CreateRequest,
|
||||
Download,
|
||||
Done,
|
||||
}
|
||||
|
||||
private UnityWebRequestAsyncOperation _requestOperation;
|
||||
private DownloadHandlerAssetBundle _downloadhandler;
|
||||
private readonly PackageBundle _packageBundle;
|
||||
private readonly bool _disableUnityWebCache;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
/// <summary>
|
||||
/// 请求结果
|
||||
/// </summary>
|
||||
public AssetBundle Result { private set; get; }
|
||||
|
||||
internal UnityAssetBundleRequestOperation(PackageBundle packageBundle, bool disableUnityWebCache, string url, int timeout = 60) : base(url, timeout)
|
||||
{
|
||||
_packageBundle = packageBundle;
|
||||
_disableUnityWebCache = disableUnityWebCache;
|
||||
}
|
||||
internal override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CreateRequest;
|
||||
}
|
||||
internal override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
ResetTimeout();
|
||||
CreateWebRequest();
|
||||
_steps = ESteps.Download;
|
||||
}
|
||||
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
DownloadProgress = _webRequest.downloadProgress;
|
||||
DownloadedBytes = (long)_webRequest.downloadedBytes;
|
||||
Progress = _requestOperation.progress;
|
||||
if (_requestOperation.isDone == false)
|
||||
{
|
||||
CheckRequestTimeout();
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheckRequestResult())
|
||||
{
|
||||
AssetBundle assetBundle = _downloadhandler.assetBundle;
|
||||
if (assetBundle == null)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"URL : {_requestURL} Download handler asset bundle object is null !";
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Result = assetBundle;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
}
|
||||
|
||||
// 注意:最终释放请求器
|
||||
DisposeRequest();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateWebRequest()
|
||||
{
|
||||
_downloadhandler = CreateWebDownloadHandler();
|
||||
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
|
||||
_webRequest.downloadHandler = _downloadhandler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
_requestOperation = _webRequest.SendWebRequest();
|
||||
}
|
||||
private DownloadHandlerAssetBundle CreateWebDownloadHandler()
|
||||
{
|
||||
if (_disableUnityWebCache)
|
||||
{
|
||||
var downloadhandler = new DownloadHandlerAssetBundle(_requestURL, _packageBundle.UnityCRC);
|
||||
#if UNITY_2020_3_OR_NEWER
|
||||
downloadhandler.autoLoadAssetBundle = false;
|
||||
#endif
|
||||
return downloadhandler;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 注意:优先从浏览器缓存里获取文件
|
||||
// The file hash defining the version of the asset bundle.
|
||||
Hash128 fileHash = Hash128.Parse(_packageBundle.FileHash);
|
||||
var downloadhandler = new DownloadHandlerAssetBundle(_requestURL, fileHash, _packageBundle.UnityCRC);
|
||||
#if UNITY_2020_3_OR_NEWER
|
||||
downloadhandler.autoLoadAssetBundle = false;
|
||||
#endif
|
||||
return downloadhandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e01cc308d7179a34281087fafe455b42
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -5,7 +5,17 @@ namespace YooAsset
|
||||
{
|
||||
internal class UnityWebDataRequestOperation : UnityWebRequestOperation
|
||||
{
|
||||
protected enum ESteps
|
||||
{
|
||||
None,
|
||||
CreateRequest,
|
||||
Download,
|
||||
Done,
|
||||
}
|
||||
|
||||
private UnityWebRequestAsyncOperation _requestOperation;
|
||||
private bool _checkTimeout = true;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
/// <summary>
|
||||
/// 请求结果
|
||||
@@ -27,27 +37,38 @@ namespace YooAsset
|
||||
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
_latestDownloadBytes = 0;
|
||||
_latestDownloadRealtime = Time.realtimeSinceStartup;
|
||||
|
||||
ResetTimeout();
|
||||
CreateWebRequest();
|
||||
_steps = ESteps.Download;
|
||||
}
|
||||
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
DownloadProgress = _webRequest.downloadProgress;
|
||||
DownloadedBytes = (long)_webRequest.downloadedBytes;
|
||||
Progress = _requestOperation.progress;
|
||||
if (_requestOperation.isDone == false)
|
||||
{
|
||||
CheckRequestTimeout();
|
||||
if (_checkTimeout)
|
||||
CheckRequestTimeout();
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheckRequestResult())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Result = _webRequest.downloadHandler.data;
|
||||
Status = EOperationStatus.Succeed;
|
||||
var fileData = _webRequest.downloadHandler.data;
|
||||
if (fileData == null || fileData.Length == 0)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"URL : {_requestURL} Download handler data is null or empty !";
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Result = fileData;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -59,10 +80,13 @@ namespace YooAsset
|
||||
DisposeRequest();
|
||||
}
|
||||
}
|
||||
internal override void InternalAbort()
|
||||
|
||||
/// <summary>
|
||||
/// 不检测超时
|
||||
/// </summary>
|
||||
public void DontCheckTimeout()
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
DisposeRequest();
|
||||
_checkTimeout = false;
|
||||
}
|
||||
|
||||
private void CreateWebRequest()
|
||||
|
||||
@@ -5,8 +5,18 @@ namespace YooAsset
|
||||
{
|
||||
internal class UnityWebFileRequestOperation : UnityWebRequestOperation
|
||||
{
|
||||
protected enum ESteps
|
||||
{
|
||||
None,
|
||||
CreateRequest,
|
||||
Download,
|
||||
Done,
|
||||
}
|
||||
|
||||
private UnityWebRequestAsyncOperation _requestOperation;
|
||||
private readonly string _fileSavePath;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
|
||||
internal UnityWebFileRequestOperation(string url, string fileSavePath, int timeout = 60) : base(url, timeout)
|
||||
{
|
||||
@@ -23,15 +33,15 @@ namespace YooAsset
|
||||
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
_latestDownloadBytes = 0;
|
||||
_latestDownloadRealtime = Time.realtimeSinceStartup;
|
||||
|
||||
ResetTimeout();
|
||||
CreateWebRequest();
|
||||
_steps = ESteps.Download;
|
||||
}
|
||||
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
DownloadProgress = _webRequest.downloadProgress;
|
||||
DownloadedBytes = (long)_webRequest.downloadedBytes;
|
||||
Progress = _requestOperation.progress;
|
||||
if (_requestOperation.isDone == false)
|
||||
{
|
||||
@@ -54,11 +64,6 @@ namespace YooAsset
|
||||
DisposeRequest();
|
||||
}
|
||||
}
|
||||
internal override void InternalAbort()
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
DisposeRequest();
|
||||
}
|
||||
|
||||
private void CreateWebRequest()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -8,24 +6,33 @@ namespace YooAsset
|
||||
{
|
||||
internal abstract class UnityWebRequestOperation : AsyncOperationBase
|
||||
{
|
||||
protected enum ESteps
|
||||
{
|
||||
None,
|
||||
CreateRequest,
|
||||
Download,
|
||||
Done,
|
||||
}
|
||||
|
||||
protected UnityWebRequest _webRequest;
|
||||
protected readonly string _requestURL;
|
||||
protected ESteps _steps = ESteps.None;
|
||||
|
||||
// 超时相关
|
||||
protected readonly float _timeout;
|
||||
protected ulong _latestDownloadBytes;
|
||||
protected float _latestDownloadRealtime;
|
||||
private readonly float _timeout;
|
||||
private ulong _latestDownloadBytes;
|
||||
private float _latestDownloadRealtime;
|
||||
private bool _isAbort = false;
|
||||
|
||||
/// <summary>
|
||||
/// HTTP返回码
|
||||
/// </summary>
|
||||
public long HttpCode { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前下载的字节数
|
||||
/// </summary>
|
||||
public long DownloadedBytes { protected set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前下载进度(0f - 1f)
|
||||
/// </summary>
|
||||
public float DownloadProgress { protected set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 请求的URL地址
|
||||
/// </summary>
|
||||
public string URL
|
||||
{
|
||||
get { return _requestURL; }
|
||||
@@ -36,6 +43,20 @@ namespace YooAsset
|
||||
_requestURL = url;
|
||||
_timeout = timeout;
|
||||
}
|
||||
internal override void InternalAbort()
|
||||
{
|
||||
//TODO
|
||||
// 1. 编辑器下停止运行游戏的时候主动终止下载任务
|
||||
// 2. 真机上销毁包裹的时候主动终止下载任务
|
||||
if (_isAbort == false)
|
||||
{
|
||||
if (_webRequest != null)
|
||||
{
|
||||
_webRequest.Abort();
|
||||
_isAbort = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放下载器
|
||||
@@ -44,20 +65,33 @@ namespace YooAsset
|
||||
{
|
||||
if (_webRequest != null)
|
||||
{
|
||||
//注意:引擎底层会自动调用Abort方法
|
||||
_webRequest.Dispose();
|
||||
_webRequest = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置超时计时
|
||||
/// </summary>
|
||||
protected void ResetTimeout()
|
||||
{
|
||||
_latestDownloadBytes = 0;
|
||||
_latestDownloadRealtime = Time.realtimeSinceStartup;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测超时
|
||||
/// </summary>
|
||||
protected void CheckRequestTimeout()
|
||||
{
|
||||
if (_webRequest.isDone)
|
||||
return;
|
||||
|
||||
// 注意:在连续时间段内无新增下载数据及判定为超时
|
||||
if (_isAbort == false)
|
||||
{
|
||||
if ( _latestDownloadBytes != _webRequest.downloadedBytes)
|
||||
if (_latestDownloadBytes != _webRequest.downloadedBytes)
|
||||
{
|
||||
_latestDownloadBytes = _webRequest.downloadedBytes;
|
||||
_latestDownloadRealtime = Time.realtimeSinceStartup;
|
||||
@@ -66,6 +100,7 @@ namespace YooAsset
|
||||
float offset = Time.realtimeSinceStartup - _latestDownloadRealtime;
|
||||
if (offset > _timeout)
|
||||
{
|
||||
YooLogger.Warning($"Web request timeout : {_requestURL}");
|
||||
_webRequest.Abort();
|
||||
_isAbort = true;
|
||||
}
|
||||
@@ -77,6 +112,8 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
protected bool CheckRequestResult()
|
||||
{
|
||||
HttpCode = _webRequest.responseCode;
|
||||
|
||||
#if UNITY_2020_3_OR_NEWER
|
||||
if (_webRequest.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
|
||||
@@ -5,7 +5,16 @@ namespace YooAsset
|
||||
{
|
||||
internal class UnityWebTextRequestOperation : UnityWebRequestOperation
|
||||
{
|
||||
protected enum ESteps
|
||||
{
|
||||
None,
|
||||
CreateRequest,
|
||||
Download,
|
||||
Done,
|
||||
}
|
||||
|
||||
private UnityWebRequestAsyncOperation _requestOperation;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
/// <summary>
|
||||
/// 请求结果
|
||||
@@ -27,15 +36,15 @@ namespace YooAsset
|
||||
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
_latestDownloadBytes = 0;
|
||||
_latestDownloadRealtime = Time.realtimeSinceStartup;
|
||||
|
||||
ResetTimeout();
|
||||
CreateWebRequest();
|
||||
_steps = ESteps.Download;
|
||||
}
|
||||
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
DownloadProgress = _webRequest.downloadProgress;
|
||||
DownloadedBytes = (long)_webRequest.downloadedBytes;
|
||||
Progress = _requestOperation.progress;
|
||||
if (_requestOperation.isDone == false)
|
||||
{
|
||||
@@ -45,9 +54,19 @@ namespace YooAsset
|
||||
|
||||
if (CheckRequestResult())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Result = _webRequest.downloadHandler.text;
|
||||
Status = EOperationStatus.Succeed;
|
||||
var fileText = _webRequest.downloadHandler.text;
|
||||
if (string.IsNullOrEmpty(fileText))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"URL : {_requestURL} Download handler text is null or empty !";
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Result = fileText;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -59,11 +78,6 @@ namespace YooAsset
|
||||
DisposeRequest();
|
||||
}
|
||||
}
|
||||
internal override void InternalAbort()
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
DisposeRequest();
|
||||
}
|
||||
|
||||
private void CreateWebRequest()
|
||||
{
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace YooAsset
|
||||
}
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
//TODO 场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
|
||||
//注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
|
||||
InternalUpdate();
|
||||
}
|
||||
public override void UnSuspendLoad()
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace YooAsset
|
||||
}
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
//TODO 场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
|
||||
//注意:场景加载不支持异步转同步,为了支持同步加载方法需要实现该方法!
|
||||
InternalUpdate();
|
||||
}
|
||||
public override void UnSuspendLoad()
|
||||
|
||||
@@ -88,6 +88,16 @@ namespace YooAsset
|
||||
/// 自定义参数:解密方法类
|
||||
/// </summary>
|
||||
public IDecryptionServices DecryptionServices { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义参数:资源清单服务类
|
||||
/// </summary>
|
||||
public IManifestServices ManifestServices { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义参数:拷贝内置文件服务类
|
||||
/// </summary>
|
||||
public ICopyLocalFileServices CopyLocalFileServices { private set; get; }
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -115,7 +125,7 @@ namespace YooAsset
|
||||
}
|
||||
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
|
||||
{
|
||||
// 注意:业务层的解压下载器会依赖内置文件系统的下载方法
|
||||
// 注意:业务层的解压器会依赖该方法
|
||||
options.ImportFilePath = GetBuildinFileLoadPath(bundle);
|
||||
return _unpackFileSystem.DownloadFileAsync(bundle, options);
|
||||
}
|
||||
@@ -174,6 +184,14 @@ namespace YooAsset
|
||||
{
|
||||
DecryptionServices = (IDecryptionServices)value;
|
||||
}
|
||||
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES)
|
||||
{
|
||||
ManifestServices = (IManifestServices)value;
|
||||
}
|
||||
else if (name == FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES)
|
||||
{
|
||||
CopyLocalFileServices = (ICopyLocalFileServices)value;
|
||||
}
|
||||
else
|
||||
{
|
||||
YooLogger.Warning($"Invalid parameter : {name}");
|
||||
@@ -196,6 +214,7 @@ namespace YooAsset
|
||||
_unpackFileSystem.SetParameter(FileSystemParametersDefine.INSTALL_CLEAR_MODE, InstallClearMode);
|
||||
_unpackFileSystem.SetParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, AppendFileExtension);
|
||||
_unpackFileSystem.SetParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, DecryptionServices);
|
||||
_unpackFileSystem.SetParameter(FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES, CopyLocalFileServices);
|
||||
_unpackFileSystem.OnCreate(packageName, null);
|
||||
}
|
||||
public virtual void OnDestroy()
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace YooAsset
|
||||
|
||||
/// <summary>
|
||||
/// 在构建应用程序前自动生成内置资源目录文件。
|
||||
/// 原理:搜索StreamingAssets目录下的所有资源文件,然后将这些文件信息写入文件,并存储在Resources目录下。
|
||||
/// 原理:搜索StreamingAssets目录下的所有资源文件,将这些文件信息写入文件,然后在运行时做查询用途。
|
||||
/// </summary>
|
||||
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
|
||||
{
|
||||
@@ -21,7 +21,7 @@ namespace YooAsset
|
||||
DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);
|
||||
if (rootDirectory.Exists == false)
|
||||
{
|
||||
UnityEngine.Debug.LogWarning($"Can not found StreamingAssets root directory : {rootPath}");
|
||||
Debug.LogWarning($"Can not found StreamingAssets root directory : {rootPath}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,10 +31,17 @@ namespace YooAsset
|
||||
{
|
||||
string packageName = subDirectory.Name;
|
||||
string pacakgeDirectory = subDirectory.FullName;
|
||||
bool result = CreateBuildinCatalogFile(packageName, pacakgeDirectory);
|
||||
if (result == false)
|
||||
try
|
||||
{
|
||||
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,13 +49,13 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 生成包裹的内置资源目录文件
|
||||
/// </summary>
|
||||
public static bool CreateBuildinCatalogFile(string packageName, string pacakgeDirectory)
|
||||
public static bool CreateBuildinCatalogFile(IManifestServices services, string packageName, string packageDirectory)
|
||||
{
|
||||
// 获取资源清单版本
|
||||
string packageVersion;
|
||||
{
|
||||
string versionFileName = YooAssetSettingsData.GetPackageVersionFileName(packageName);
|
||||
string versionFilePath = $"{pacakgeDirectory}/{versionFileName}";
|
||||
string versionFilePath = $"{packageDirectory}/{versionFileName}";
|
||||
if (File.Exists(versionFilePath) == false)
|
||||
{
|
||||
Debug.LogError($"Can not found package version file : {versionFilePath}");
|
||||
@@ -62,7 +69,7 @@ namespace YooAsset
|
||||
PackageManifest packageManifest;
|
||||
{
|
||||
string manifestFileName = YooAssetSettingsData.GetManifestBinaryFileName(packageName, packageVersion);
|
||||
string manifestFilePath = $"{pacakgeDirectory}/{manifestFileName}";
|
||||
string manifestFilePath = $"{packageDirectory}/{manifestFileName}";
|
||||
if (File.Exists(manifestFilePath) == false)
|
||||
{
|
||||
Debug.LogError($"Can not found package manifest file : {manifestFilePath}");
|
||||
@@ -70,7 +77,7 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
var binaryData = FileUtility.ReadAllBytes(manifestFilePath);
|
||||
packageManifest = ManifestTools.DeserializeFromBinary(binaryData);
|
||||
packageManifest = ManifestTools.DeserializeFromBinary(binaryData, services);
|
||||
}
|
||||
|
||||
// 获取文件名映射关系
|
||||
@@ -103,7 +110,7 @@ namespace YooAsset
|
||||
};
|
||||
|
||||
// 记录所有内置资源文件
|
||||
DirectoryInfo rootDirectory = new DirectoryInfo(pacakgeDirectory);
|
||||
DirectoryInfo rootDirectory = new DirectoryInfo(packageDirectory);
|
||||
FileInfo[] fileInfos = rootDirectory.GetFiles();
|
||||
foreach (var fileInfo in fileInfos)
|
||||
{
|
||||
@@ -128,13 +135,13 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
// 创建输出文件
|
||||
string jsonFilePath = $"{pacakgeDirectory}/{DefaultBuildinFileSystemDefine.BuildinCatalogJsonFileName}";
|
||||
string jsonFilePath = $"{packageDirectory}/{DefaultBuildinFileSystemDefine.BuildinCatalogJsonFileName}";
|
||||
if (File.Exists(jsonFilePath))
|
||||
File.Delete(jsonFilePath);
|
||||
CatalogTools.SerializeToJson(jsonFilePath, buildinFileCatalog);
|
||||
|
||||
// 创建输出文件
|
||||
string binaryFilePath = $"{pacakgeDirectory}/{DefaultBuildinFileSystemDefine.BuildinCatalogBinaryFileName}";
|
||||
string binaryFilePath = $"{packageDirectory}/{DefaultBuildinFileSystemDefine.BuildinCatalogBinaryFileName}";
|
||||
if (File.Exists(binaryFilePath))
|
||||
File.Delete(binaryFilePath);
|
||||
CatalogTools.SerializeToBinary(binaryFilePath, buildinFileCatalog);
|
||||
|
||||
@@ -106,10 +106,11 @@ namespace YooAsset
|
||||
if (_loadCatalogFileOp == null)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
/*
|
||||
// 兼容性初始化
|
||||
// 说明:内置文件系统在编辑器下运行时需要动态生成
|
||||
string packageRoot = _fileSystem.FileRoot;
|
||||
bool result = DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(_fileSystem.PackageName, packageRoot);
|
||||
bool result = DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(_fileSystem.ManifestServices, _fileSystem.PackageName, packageRoot);
|
||||
if (result == false)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
@@ -117,6 +118,7 @@ namespace YooAsset
|
||||
Error = $"Create package catalog file failed ! See the detail error in console !";
|
||||
return;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
_loadCatalogFileOp = new LoadBuildinCatalogFileOperation(_fileSystem);
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace YooAsset
|
||||
{
|
||||
if (_deserializer == null)
|
||||
{
|
||||
_deserializer = new DeserializeManifestOperation(_webDataRequestOp.Result);
|
||||
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _webDataRequestOp.Result);
|
||||
_deserializer.StartOperation();
|
||||
AddChildOperation(_deserializer);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 自定义参数:远程服务接口
|
||||
/// </summary>
|
||||
public IRemoteServices RemoteServices { private set; get; } = null;
|
||||
public IRemoteServices RemoteServices { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义参数:初始化的时候缓存文件校验级别
|
||||
@@ -99,6 +99,16 @@ namespace YooAsset
|
||||
/// 自定义参数:解密方法类
|
||||
/// </summary>
|
||||
public IDecryptionServices DecryptionServices { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义参数:资源清单服务类
|
||||
/// </summary>
|
||||
public IManifestServices ManifestServices { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义参数:拷贝内置文件服务类
|
||||
/// </summary>
|
||||
public ICopyLocalFileServices CopyLocalFileServices { private set; get; }
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -156,12 +166,23 @@ namespace YooAsset
|
||||
}
|
||||
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
|
||||
{
|
||||
var downloader = DownloadCenter.DownloadFileAsync(bundle, options);
|
||||
downloader.Reference(); //增加下载器的引用计数
|
||||
// 获取下载地址
|
||||
if (string.IsNullOrEmpty(options.ImportFilePath))
|
||||
{
|
||||
// 注意:如果是解压文件系统类,这里会返回本地内置文件的下载路径
|
||||
string mainURL = RemoteServices.GetRemoteMainURL(bundle.FileName);
|
||||
string fallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName);
|
||||
options.SetURL(mainURL, fallbackURL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 注意:把本地导入文件路径转换为下载器请求地址
|
||||
string mainURL = DownloadSystemHelper.ConvertToWWWPath(options.ImportFilePath);
|
||||
options.SetURL(mainURL, mainURL);
|
||||
}
|
||||
|
||||
// 注意:将下载器进行包裹,可以避免父类任务终止的时候,连带子任务里的下载器也一起被终止!
|
||||
var wrapper = new DownloadFileWrapper(downloader);
|
||||
return wrapper;
|
||||
var downloader = new DownloadPackageBundleOperation(this, bundle, options);
|
||||
return downloader;
|
||||
}
|
||||
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)
|
||||
{
|
||||
@@ -221,6 +242,14 @@ namespace YooAsset
|
||||
{
|
||||
DecryptionServices = (IDecryptionServices)value;
|
||||
}
|
||||
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES)
|
||||
{
|
||||
ManifestServices = (IManifestServices)value;
|
||||
}
|
||||
else if (name == FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES)
|
||||
{
|
||||
CopyLocalFileServices = (ICopyLocalFileServices)value;
|
||||
}
|
||||
else
|
||||
{
|
||||
YooLogger.Warning($"Invalid parameter : {name}");
|
||||
@@ -559,6 +588,21 @@ namespace YooAsset
|
||||
};
|
||||
return DecryptionServices.LoadAssetBundleAsync(fileInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载加密资源文件
|
||||
/// </summary>
|
||||
public DecryptResult LoadEncryptedAssetBundleFallback(PackageBundle bundle)
|
||||
{
|
||||
string filePath = GetCacheBundleFileLoadPath(bundle);
|
||||
var fileInfo = new DecryptFileInfo()
|
||||
{
|
||||
BundleName = bundle.BundleName,
|
||||
FileLoadCRC = bundle.UnityCRC,
|
||||
FileLoadPath = filePath,
|
||||
};
|
||||
return DecryptionServices.LoadAssetBundleFallback(fileInfo);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,6 @@ namespace YooAsset
|
||||
|
||||
if (_steps == ESteps.DownloadFile)
|
||||
{
|
||||
// 注意:边玩边下下载器引用计数没有Release
|
||||
if (_downloadFileOp == null)
|
||||
{
|
||||
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
|
||||
@@ -164,11 +163,23 @@ namespace YooAsset
|
||||
{
|
||||
if (_bundle.Encrypted)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"Failed to load encrypted asset bundle file : {_bundle.BundleName}";
|
||||
YooLogger.Error(Error);
|
||||
return;
|
||||
var decryptResult = _fileSystem.LoadEncryptedAssetBundleFallback(_bundle);
|
||||
_assetBundle = decryptResult.Result;
|
||||
if (_assetBundle != null)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Result = new AssetBundleResult(_fileSystem, _bundle, _assetBundle, _managedStream);
|
||||
Status = EOperationStatus.Succeed;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"Failed to load encrypted asset bundle file : {_bundle.BundleName}";
|
||||
YooLogger.Error(Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 注意:在安卓移动平台,华为和三星真机上有极小概率加载资源包失败。
|
||||
@@ -216,9 +227,6 @@ namespace YooAsset
|
||||
{
|
||||
if (ExecuteWhileDone())
|
||||
{
|
||||
if (_downloadFileOp != null && _downloadFileOp.Status == EOperationStatus.Failed)
|
||||
YooLogger.Error($"Try load bundle {_bundle.BundleName} from remote !");
|
||||
|
||||
_steps = ESteps.Done;
|
||||
break;
|
||||
}
|
||||
@@ -294,7 +302,6 @@ namespace YooAsset
|
||||
|
||||
if (_steps == ESteps.DownloadFile)
|
||||
{
|
||||
// 注意:边玩边下下载器引用计数没有Release
|
||||
if (_downloadFileOp == null)
|
||||
{
|
||||
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
|
||||
@@ -348,10 +355,6 @@ namespace YooAsset
|
||||
{
|
||||
if (ExecuteWhileDone())
|
||||
{
|
||||
//TODO 拷贝本地文件失败也会触发该错误!
|
||||
if (_downloadFileOp != null && _downloadFileOp.Status == EOperationStatus.Failed)
|
||||
YooLogger.Error($"Try load bundle {_bundle.BundleName} from remote !");
|
||||
|
||||
_steps = ESteps.Done;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,21 @@ using System.Collections.Generic;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 下载器单元测试
|
||||
/// 1. 下载失败重试机制
|
||||
/// 2. 下载引用计数机制
|
||||
/// 3. 最大下载并发机制
|
||||
/// 4. 异步下载远端资源
|
||||
/// 5. 同步下载远端资源
|
||||
/// 6. 异步拷贝本地资源
|
||||
/// 7. 同步拷贝本地资源
|
||||
/// 9. 断点续传下载器
|
||||
/// </summary>
|
||||
internal class DownloadCenterOperation : AsyncOperationBase
|
||||
{
|
||||
private readonly DefaultCacheFileSystem _fileSystem;
|
||||
protected readonly Dictionary<string, DefaultDownloadFileOperation> _downloaders = new Dictionary<string, DefaultDownloadFileOperation>(1000);
|
||||
protected readonly Dictionary<string, UnityDownloadFileOperation> _downloaders = new Dictionary<string, UnityDownloadFileOperation>(1000);
|
||||
protected readonly List<string> _removeDownloadList = new List<string>(1000);
|
||||
|
||||
public DownloadCenterOperation(DefaultCacheFileSystem fileSystem)
|
||||
@@ -74,41 +85,41 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 创建下载任务
|
||||
/// </summary>
|
||||
public FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
|
||||
public UnityDownloadFileOperation DownloadFileAsync(PackageBundle bundle, string url, int timeout)
|
||||
{
|
||||
// 查询旧的下载器
|
||||
if (_downloaders.TryGetValue(bundle.BundleGUID, out var oldDownloader))
|
||||
{
|
||||
oldDownloader.Reference();
|
||||
return oldDownloader;
|
||||
}
|
||||
|
||||
// 设置请求URL
|
||||
if (string.IsNullOrEmpty(options.ImportFilePath))
|
||||
// 创建新的下载器
|
||||
UnityDownloadFileOperation newDownloader;
|
||||
bool isRequestLocalFile = DownloadSystemHelper.IsRequestLocalFile(url);
|
||||
if (isRequestLocalFile)
|
||||
{
|
||||
options.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(bundle.FileName);
|
||||
options.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(bundle.FileName);
|
||||
newDownloader = new UnityDownloadLocalFileOperation(_fileSystem, bundle, url, timeout);
|
||||
AddChildOperation(newDownloader);
|
||||
_downloaders.Add(bundle.BundleGUID, newDownloader);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 注意:把本地文件路径指定为远端下载地址
|
||||
options.MainURL = DownloadSystemHelper.ConvertToWWWPath(options.ImportFilePath);
|
||||
options.FallbackURL = options.MainURL;
|
||||
if (bundle.FileSize >= _fileSystem.ResumeDownloadMinimumSize)
|
||||
{
|
||||
newDownloader = new UnityDownloadResumeFileOperation(_fileSystem, bundle, url, timeout);
|
||||
AddChildOperation(newDownloader);
|
||||
_downloaders.Add(bundle.BundleGUID, newDownloader);
|
||||
}
|
||||
else
|
||||
{
|
||||
newDownloader = new UnityDownloadNormalFileOperation(_fileSystem, bundle, url, timeout);
|
||||
AddChildOperation(newDownloader);
|
||||
_downloaders.Add(bundle.BundleGUID, newDownloader);
|
||||
}
|
||||
}
|
||||
|
||||
// 创建新的下载器
|
||||
DefaultDownloadFileOperation newDownloader;
|
||||
if (bundle.FileSize >= _fileSystem.ResumeDownloadMinimumSize)
|
||||
{
|
||||
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);
|
||||
}
|
||||
newDownloader.Reference();
|
||||
return newDownloader;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 支持Unity2018版本的断点续传下载器
|
||||
/// </summary>
|
||||
internal class DownloadHandlerFileRange : DownloadHandlerScript
|
||||
{
|
||||
private string _fileSavePath;
|
||||
private long _fileTotalSize;
|
||||
private UnityWebRequest _webRequest;
|
||||
private FileStream _fileStream;
|
||||
|
||||
private long _localFileSize = 0;
|
||||
private long _curFileSize = 0;
|
||||
|
||||
|
||||
public DownloadHandlerFileRange(string fileSavePath, long fileTotalSize, UnityWebRequest webRequest) : base(new byte[1024 * 1024])
|
||||
{
|
||||
_fileSavePath = fileSavePath;
|
||||
_fileTotalSize = fileTotalSize;
|
||||
_webRequest = webRequest;
|
||||
|
||||
if (File.Exists(fileSavePath))
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(fileSavePath);
|
||||
_localFileSize = fileInfo.Length;
|
||||
}
|
||||
|
||||
_fileStream = new FileStream(_fileSavePath, FileMode.Append, FileAccess.Write);
|
||||
_curFileSize = _localFileSize;
|
||||
}
|
||||
protected override bool ReceiveData(byte[] data, int dataLength)
|
||||
{
|
||||
if (data == null || dataLength == 0 || _webRequest.responseCode >= 400)
|
||||
return false;
|
||||
|
||||
if (_fileStream == null)
|
||||
return false;
|
||||
|
||||
_fileStream.Write(data, 0, dataLength);
|
||||
_curFileSize += dataLength;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UnityWebRequest.downloadHandler.data
|
||||
/// </summary>
|
||||
protected override byte[] GetData()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UnityWebRequest.downloadHandler.text
|
||||
/// </summary>
|
||||
protected override string GetText()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UnityWebRequest.downloadProgress
|
||||
/// </summary>
|
||||
protected override float GetProgress()
|
||||
{
|
||||
return _fileTotalSize == 0 ? 0 : ((float)_curFileSize) / _fileTotalSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放下载句柄
|
||||
/// </summary>
|
||||
public void Cleanup()
|
||||
{
|
||||
if (_fileStream != null)
|
||||
{
|
||||
_fileStream.Flush();
|
||||
_fileStream.Dispose();
|
||||
_fileStream = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class DownloadPackageBundleOperation : FSDownloadFileOperation
|
||||
{
|
||||
protected enum ESteps
|
||||
{
|
||||
None,
|
||||
CheckExists,
|
||||
CreateRequest,
|
||||
CheckRequest,
|
||||
TryAgain,
|
||||
Done,
|
||||
}
|
||||
|
||||
// 下载参数
|
||||
protected readonly DefaultCacheFileSystem _fileSystem;
|
||||
protected readonly DownloadFileOptions _options;
|
||||
private UnityDownloadFileOperation _unityDownloadFileOp;
|
||||
|
||||
protected int _requestCount = 0;
|
||||
protected float _tryAgainTimer;
|
||||
protected int _failedTryAgain;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
|
||||
internal DownloadPackageBundleOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_options = options;
|
||||
_failedTryAgain = options.FailedTryAgain;
|
||||
}
|
||||
internal override void InternalStart()
|
||||
{
|
||||
_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
|
||||
{
|
||||
_steps = ESteps.CreateRequest;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建下载器
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
if (_options.IsValid() == false)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = "Download file options is invalid !";
|
||||
Debug.Log(Error);
|
||||
return;
|
||||
}
|
||||
|
||||
string url = GetRequestURL();
|
||||
_unityDownloadFileOp = _fileSystem.DownloadCenter.DownloadFileAsync(Bundle, url, _options.Timeout);
|
||||
_steps = ESteps.CheckRequest;
|
||||
}
|
||||
|
||||
// 检测下载结果
|
||||
if (_steps == ESteps.CheckRequest)
|
||||
{
|
||||
if (IsWaitForAsyncComplete)
|
||||
_unityDownloadFileOp.WaitForAsyncComplete();
|
||||
|
||||
// 因为并发数量限制,下载器可能被挂起!
|
||||
if (_unityDownloadFileOp.Status == EOperationStatus.None)
|
||||
return;
|
||||
|
||||
_unityDownloadFileOp.UpdateOperation();
|
||||
Progress = _unityDownloadFileOp.Progress;
|
||||
DownloadedBytes = _unityDownloadFileOp.DownloadedBytes;
|
||||
DownloadProgress = _unityDownloadFileOp.DownloadProgress;
|
||||
if (_unityDownloadFileOp.IsDone == false)
|
||||
return;
|
||||
|
||||
if (_unityDownloadFileOp.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsWaitForAsyncComplete == false && _failedTryAgain > 0)
|
||||
{
|
||||
_steps = ESteps.TryAgain;
|
||||
YooLogger.Warning($"Failed download : {_unityDownloadFileOp.URL} Try again !");
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _unityDownloadFileOp.Error;
|
||||
YooLogger.Error(Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重新尝试下载
|
||||
if (_steps == ESteps.TryAgain)
|
||||
{
|
||||
_tryAgainTimer += Time.unscaledDeltaTime;
|
||||
if (_tryAgainTimer > 1f)
|
||||
{
|
||||
_tryAgainTimer = 0f;
|
||||
_failedTryAgain--;
|
||||
Progress = 0f;
|
||||
DownloadProgress = 0f;
|
||||
DownloadedBytes = 0;
|
||||
_steps = ESteps.CreateRequest;
|
||||
}
|
||||
}
|
||||
}
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (ExecuteWhileDone())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
internal override void InternalAbort()
|
||||
{
|
||||
// 注意:取消下载任务的时候引用计数减一
|
||||
if (_steps != ESteps.Done)
|
||||
{
|
||||
if (_unityDownloadFileOp != null)
|
||||
{
|
||||
_unityDownloadFileOp.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络请求地址
|
||||
/// </summary>
|
||||
protected string GetRequestURL()
|
||||
{
|
||||
// 轮流返回请求地址
|
||||
_requestCount++;
|
||||
if (_requestCount % 2 == 0)
|
||||
return _options.FallbackURL;
|
||||
else
|
||||
return _options.MainURL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ namespace YooAsset
|
||||
{
|
||||
if (_deserializer == null)
|
||||
{
|
||||
_deserializer = new DeserializeManifestOperation(_fileData);
|
||||
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _fileData);
|
||||
_deserializer.StartOperation();
|
||||
AddChildOperation(_deserializer);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal abstract class UnityDownloadFileOperation : UnityWebRequestOperation
|
||||
{
|
||||
protected enum ESteps
|
||||
{
|
||||
None,
|
||||
CreateRequest,
|
||||
Download,
|
||||
CopyLocalFile,
|
||||
VerifyFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
protected readonly DefaultCacheFileSystem _fileSystem;
|
||||
protected readonly PackageBundle _bundle;
|
||||
protected readonly string _tempFilePath;
|
||||
|
||||
/// <summary>
|
||||
/// 引用计数
|
||||
/// </summary>
|
||||
public int RefCount { private set; get; }
|
||||
|
||||
internal UnityDownloadFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url, int timeout) : base(url, timeout)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
_bundle = bundle;
|
||||
_tempFilePath = _fileSystem.GetTempFilePath(bundle);
|
||||
}
|
||||
internal override string InternalGetDesc()
|
||||
{
|
||||
return $"RefCount : {RefCount}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 减少引用计数
|
||||
/// </summary>
|
||||
public void Release()
|
||||
{
|
||||
RefCount--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加引用计数
|
||||
/// </summary>
|
||||
public void Reference()
|
||||
{
|
||||
RefCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40bb5e9391f413c42ae70e48ca90c4b7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -4,66 +4,41 @@ using UnityEngine.Networking;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal sealed class DownloadNormalFileOperation : DefaultDownloadFileOperation
|
||||
internal class UnityDownloadLocalFileOperation : UnityDownloadFileOperation
|
||||
{
|
||||
private readonly DefaultCacheFileSystem _fileSystem;
|
||||
private VerifyTempFileOperation _verifyOperation;
|
||||
private bool _isReuqestLocalFile;
|
||||
private string _tempFilePath;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal DownloadNormalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
|
||||
internal UnityDownloadLocalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url, int timeout = 60)
|
||||
: base(fileSystem, bundle, url, timeout)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
internal override void InternalStart()
|
||||
{
|
||||
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Options.MainURL);
|
||||
_tempFilePath = _fileSystem.GetTempFilePath(Bundle);
|
||||
_steps = ESteps.CheckExists;
|
||||
if (_fileSystem.CopyLocalFileServices != null)
|
||||
_steps = ESteps.CopyLocalFile;
|
||||
else
|
||||
_steps = ESteps.CreateRequest;
|
||||
}
|
||||
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
|
||||
{
|
||||
_steps = ESteps.CreateRequest;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建下载器
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
FileUtility.CreateFileDirectory(_tempFilePath);
|
||||
|
||||
// 删除临时文件
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
|
||||
// 获取请求地址
|
||||
_requestURL = GetRequestURL();
|
||||
|
||||
// 重置请求
|
||||
ResetRequestFiled();
|
||||
|
||||
// 创建下载器
|
||||
ResetTimeout();
|
||||
CreateWebRequest();
|
||||
|
||||
_steps = ESteps.CheckRequest;
|
||||
_steps = ESteps.Download;
|
||||
}
|
||||
|
||||
// 检测下载结果
|
||||
if (_steps == ESteps.CheckRequest)
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
DownloadProgress = _webRequest.downloadProgress;
|
||||
DownloadedBytes = (long)_webRequest.downloadedBytes;
|
||||
@@ -76,27 +51,67 @@ namespace YooAsset
|
||||
|
||||
// 检查网络错误
|
||||
if (CheckRequestResult())
|
||||
_steps = ESteps.VerifyTempFile;
|
||||
{
|
||||
_steps = ESteps.VerifyFile;
|
||||
}
|
||||
else
|
||||
_steps = ESteps.TryAgain;
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
}
|
||||
|
||||
// 注意:最终释放请求器
|
||||
DisposeWebRequest();
|
||||
DisposeRequest();
|
||||
}
|
||||
|
||||
// 拷贝内置文件
|
||||
if (_steps == ESteps.CopyLocalFile)
|
||||
{
|
||||
FileUtility.CreateFileDirectory(_tempFilePath);
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
|
||||
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.VerifyFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"Failed copy local file : {_requestURL}";
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"Failed copy local file : {ex.Message}";
|
||||
}
|
||||
}
|
||||
|
||||
// 验证下载文件
|
||||
if (_steps == ESteps.VerifyTempFile)
|
||||
if (_steps == ESteps.VerifyFile)
|
||||
{
|
||||
var element = new TempFileElement(_tempFilePath, Bundle.FileCRC, Bundle.FileSize);
|
||||
_verifyOperation = new VerifyTempFileOperation(element);
|
||||
_verifyOperation.StartOperation();
|
||||
AddChildOperation(_verifyOperation);
|
||||
_steps = ESteps.CheckVerifyTempFile;
|
||||
}
|
||||
if (_verifyOperation == null)
|
||||
{
|
||||
var element = new TempFileElement(_tempFilePath, _bundle.FileCRC, _bundle.FileSize);
|
||||
_verifyOperation = new VerifyTempFileOperation(element);
|
||||
_verifyOperation.StartOperation();
|
||||
AddChildOperation(_verifyOperation);
|
||||
}
|
||||
|
||||
// 等待验证完成
|
||||
if (_steps == ESteps.CheckVerifyTempFile)
|
||||
{
|
||||
if (IsWaitForAsyncComplete)
|
||||
_verifyOperation.WaitForAsyncComplete();
|
||||
|
||||
@@ -106,7 +121,7 @@ namespace YooAsset
|
||||
|
||||
if (_verifyOperation.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
if (_fileSystem.WriteCacheBundleFile(Bundle, _tempFilePath))
|
||||
if (_fileSystem.WriteCacheBundleFile(_bundle, _tempFilePath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
@@ -116,12 +131,12 @@ namespace YooAsset
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"{_fileSystem.GetType().FullName} failed to write file !";
|
||||
YooLogger.Error(Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.TryAgain;
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _verifyOperation.Error;
|
||||
}
|
||||
|
||||
@@ -129,60 +144,18 @@ namespace YooAsset
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
|
||||
// 重新尝试下载
|
||||
if (_steps == ESteps.TryAgain)
|
||||
{
|
||||
//TODO 拷贝本地文件失败后不再尝试!
|
||||
if (_isReuqestLocalFile)
|
||||
{
|
||||
Status = EOperationStatus.Failed;
|
||||
_steps = ESteps.Done;
|
||||
YooLogger.Error(Error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (FailedTryAgain <= 0)
|
||||
{
|
||||
Status = EOperationStatus.Failed;
|
||||
_steps = ESteps.Done;
|
||||
YooLogger.Error(Error);
|
||||
return;
|
||||
}
|
||||
|
||||
_tryAgainTimer += Time.unscaledDeltaTime;
|
||||
if (_tryAgainTimer > 1f)
|
||||
{
|
||||
FailedTryAgain--;
|
||||
_steps = ESteps.CreateRequest;
|
||||
YooLogger.Warning(Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
internal override void InternalAbort()
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
DisposeWebRequest();
|
||||
}
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
//TODO 如果是导入或解压本地文件,执行等待完毕
|
||||
if (_isReuqestLocalFile)
|
||||
{
|
||||
InternalUpdate();
|
||||
if (IsDone)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ExecuteWhileDone())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//TODO 等待导入或解压本地文件完毕,该操作会挂起主线程!
|
||||
InternalUpdate();
|
||||
if (IsDone)
|
||||
break;
|
||||
|
||||
// 短暂休眠避免完全卡死
|
||||
System.Threading.Thread.Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,14 +168,5 @@ namespace YooAsset
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
_webRequest.SendWebRequest();
|
||||
}
|
||||
private void DisposeWebRequest()
|
||||
{
|
||||
if (_webRequest != null)
|
||||
{
|
||||
//注意:引擎底层会自动调用Abort方法
|
||||
_webRequest.Dispose();
|
||||
_webRequest = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c68640bb1d36552469024324e3357bc2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,126 @@
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal sealed class UnityDownloadNormalFileOperation : UnityDownloadFileOperation
|
||||
{
|
||||
private VerifyTempFileOperation _verifyOperation;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal UnityDownloadNormalFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url, int timeout = 60)
|
||||
: base(fileSystem, bundle, url, timeout)
|
||||
{
|
||||
}
|
||||
internal override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.CreateRequest;
|
||||
}
|
||||
internal override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
// 创建下载器
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
FileUtility.CreateFileDirectory(_tempFilePath);
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
|
||||
ResetTimeout();
|
||||
CreateWebRequest();
|
||||
_steps = ESteps.Download;
|
||||
}
|
||||
|
||||
// 检测下载结果
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
DownloadProgress = _webRequest.downloadProgress;
|
||||
DownloadedBytes = (long)_webRequest.downloadedBytes;
|
||||
Progress = DownloadProgress;
|
||||
if (_webRequest.isDone == false)
|
||||
{
|
||||
CheckRequestTimeout();
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查网络错误
|
||||
if (CheckRequestResult())
|
||||
{
|
||||
_steps = ESteps.VerifyFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
}
|
||||
|
||||
// 注意:最终释放请求器
|
||||
DisposeRequest();
|
||||
}
|
||||
|
||||
// 验证下载文件
|
||||
if (_steps == ESteps.VerifyFile)
|
||||
{
|
||||
if (_verifyOperation == null)
|
||||
{
|
||||
var element = new TempFileElement(_tempFilePath, _bundle.FileCRC, _bundle.FileSize);
|
||||
_verifyOperation = new VerifyTempFileOperation(element);
|
||||
_verifyOperation.StartOperation();
|
||||
AddChildOperation(_verifyOperation);
|
||||
}
|
||||
|
||||
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 ! {_tempFilePath}";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _verifyOperation.Error;
|
||||
}
|
||||
|
||||
// 注意:验证完成后直接删除文件
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
}
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
if (_steps != ESteps.Done)
|
||||
{
|
||||
YooLogger.Error($"Try load bundle {_bundle.BundleName} from remote : {_requestURL} !");
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateWebRequest()
|
||||
{
|
||||
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
|
||||
DownloadHandlerFile handler = new DownloadHandlerFile(_tempFilePath);
|
||||
handler.removeFileOnAbort = true;
|
||||
_webRequest.downloadHandler = handler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
_webRequest.SendWebRequest();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,66 +4,38 @@ using UnityEngine.Networking;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal sealed class DownloadResumeFileOperation : DefaultDownloadFileOperation
|
||||
internal sealed class UnityDownloadResumeFileOperation : UnityDownloadFileOperation
|
||||
{
|
||||
private readonly DefaultCacheFileSystem _fileSystem;
|
||||
private DownloadHandlerFileRange _downloadHandle;
|
||||
private VerifyTempFileOperation _verifyOperation;
|
||||
private bool _isReuqestLocalFile;
|
||||
private long _fileOriginLength = 0;
|
||||
private string _tempFilePath;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
|
||||
internal DownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
|
||||
internal UnityDownloadResumeFileOperation(DefaultCacheFileSystem fileSystem, PackageBundle bundle, string url, int timeout = 60)
|
||||
: base(fileSystem, bundle, url, timeout)
|
||||
{
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
internal override void InternalStart()
|
||||
{
|
||||
_isReuqestLocalFile = DownloadSystemHelper.IsRequestLocalFile(Options.MainURL);
|
||||
_tempFilePath = _fileSystem.GetTempFilePath(Bundle);
|
||||
_steps = ESteps.CheckExists;
|
||||
_steps = ESteps.CreateRequest;
|
||||
}
|
||||
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
|
||||
{
|
||||
_steps = ESteps.CreateRequest;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建下载器
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
FileUtility.CreateFileDirectory(_tempFilePath);
|
||||
|
||||
// 获取请求地址
|
||||
_requestURL = GetRequestURL();
|
||||
|
||||
// 重置变量
|
||||
ResetRequestFiled();
|
||||
|
||||
// 获取下载起始位置
|
||||
_fileOriginLength = 0;
|
||||
long fileBeginLength = -1;
|
||||
if (File.Exists(_tempFilePath))
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(_tempFilePath);
|
||||
if (fileInfo.Length >= Bundle.FileSize)
|
||||
if (fileInfo.Length >= _bundle.FileSize)
|
||||
{
|
||||
// 删除临时文件
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
else
|
||||
@@ -74,17 +46,17 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
// 创建下载器
|
||||
ResetTimeout();
|
||||
CreateWebRequest(fileBeginLength);
|
||||
|
||||
_steps = ESteps.CheckRequest;
|
||||
_steps = ESteps.Download;
|
||||
}
|
||||
|
||||
// 检测下载结果
|
||||
if (_steps == ESteps.CheckRequest)
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
DownloadProgress = _webRequest.downloadProgress;
|
||||
DownloadedBytes = _fileOriginLength + (long)_webRequest.downloadedBytes;
|
||||
Progress = DownloadProgress;
|
||||
if (_webRequest.isDone == false)
|
||||
{
|
||||
CheckRequestTimeout();
|
||||
@@ -93,30 +65,33 @@ namespace YooAsset
|
||||
|
||||
// 检查网络错误
|
||||
if (CheckRequestResult())
|
||||
_steps = ESteps.VerifyTempFile;
|
||||
{
|
||||
_steps = ESteps.VerifyFile;
|
||||
}
|
||||
else
|
||||
_steps = ESteps.TryAgain;
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
}
|
||||
|
||||
// 在遇到特殊错误的时候删除文件
|
||||
ClearTempFileWhenError();
|
||||
|
||||
// 注意:最终释放请求器
|
||||
DisposeWebRequest();
|
||||
DisposeRequest();
|
||||
}
|
||||
|
||||
// 验证下载文件
|
||||
if (_steps == ESteps.VerifyTempFile)
|
||||
if (_steps == ESteps.VerifyFile)
|
||||
{
|
||||
var element = new TempFileElement(_tempFilePath, Bundle.FileCRC, Bundle.FileSize);
|
||||
_verifyOperation = new VerifyTempFileOperation(element);
|
||||
_verifyOperation.StartOperation();
|
||||
AddChildOperation(_verifyOperation);
|
||||
_steps = ESteps.CheckVerifyTempFile;
|
||||
}
|
||||
if (_verifyOperation == null)
|
||||
{
|
||||
var element = new TempFileElement(_tempFilePath, _bundle.FileCRC, _bundle.FileSize);
|
||||
_verifyOperation = new VerifyTempFileOperation(element);
|
||||
_verifyOperation.StartOperation();
|
||||
AddChildOperation(_verifyOperation);
|
||||
}
|
||||
|
||||
// 等待验证完成
|
||||
if (_steps == ESteps.CheckVerifyTempFile)
|
||||
{
|
||||
if (IsWaitForAsyncComplete)
|
||||
_verifyOperation.WaitForAsyncComplete();
|
||||
|
||||
@@ -126,116 +101,38 @@ namespace YooAsset
|
||||
|
||||
if (_verifyOperation.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
if (_fileSystem.WriteCacheBundleFile(Bundle, _tempFilePath))
|
||||
if (_fileSystem.WriteCacheBundleFile(_bundle, _tempFilePath))
|
||||
{
|
||||
Status = EOperationStatus.Succeed;
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
Error = $"{_fileSystem.GetType().FullName} failed to write file !";
|
||||
Status = EOperationStatus.Failed;
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"{_fileSystem.GetType().FullName} failed to write file !";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _verifyOperation.Error;
|
||||
_steps = ESteps.TryAgain;
|
||||
}
|
||||
|
||||
// 注意:验证完成后直接删除文件
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
|
||||
// 重新尝试下载
|
||||
if (_steps == ESteps.TryAgain)
|
||||
{
|
||||
//TODO 拷贝本地文件失败后不再尝试!
|
||||
if (_isReuqestLocalFile)
|
||||
{
|
||||
Status = EOperationStatus.Failed;
|
||||
_steps = ESteps.Done;
|
||||
YooLogger.Error(Error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (FailedTryAgain <= 0)
|
||||
{
|
||||
Status = EOperationStatus.Failed;
|
||||
_steps = ESteps.Done;
|
||||
YooLogger.Error(Error);
|
||||
return;
|
||||
}
|
||||
|
||||
_tryAgainTimer += Time.unscaledDeltaTime;
|
||||
if (_tryAgainTimer > 1f)
|
||||
{
|
||||
FailedTryAgain--;
|
||||
_steps = ESteps.CreateRequest;
|
||||
YooLogger.Warning(Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
internal override void InternalAbort()
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
DisposeWebRequest();
|
||||
}
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
while (true)
|
||||
if (_steps != ESteps.Done)
|
||||
{
|
||||
//TODO 如果是导入或解压本地文件,执行等待完毕
|
||||
if (_isReuqestLocalFile)
|
||||
{
|
||||
InternalUpdate();
|
||||
if (IsDone)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ExecuteWhileDone())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
break;
|
||||
}
|
||||
}
|
||||
YooLogger.Error($"Try load bundle {_bundle.BundleName} from remote : {_requestURL} !");
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateWebRequest(long beginLength)
|
||||
{
|
||||
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
var handler = new DownloadHandlerFile(_tempFilePath, true);
|
||||
handler.removeFileOnAbort = false;
|
||||
#else
|
||||
var handler = new DownloadHandlerFileRange(FileSavePath, Bundle.FileSize, _webRequest);
|
||||
_downloadHandle = handler;
|
||||
#endif
|
||||
_webRequest.downloadHandler = handler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
if (beginLength > 0)
|
||||
_webRequest.SetRequestHeader("Range", $"bytes={beginLength}-");
|
||||
_webRequest.SendWebRequest();
|
||||
}
|
||||
private void DisposeWebRequest()
|
||||
{
|
||||
if (_downloadHandle != null)
|
||||
{
|
||||
_downloadHandle.Cleanup();
|
||||
_downloadHandle = null;
|
||||
}
|
||||
|
||||
if (_webRequest != null)
|
||||
{
|
||||
//注意:引擎底层会自动调用Abort方法
|
||||
_webRequest.Dispose();
|
||||
_webRequest = null;
|
||||
}
|
||||
}
|
||||
private void ClearTempFileWhenError()
|
||||
{
|
||||
if (_fileSystem.ResumeDownloadResponseCodes == null)
|
||||
@@ -248,5 +145,16 @@ namespace YooAsset
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
}
|
||||
private void CreateWebRequest(long fileBeginLength)
|
||||
{
|
||||
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
|
||||
var handler = new DownloadHandlerFile(_tempFilePath, true);
|
||||
handler.removeFileOnAbort = false;
|
||||
_webRequest.downloadHandler = handler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
if (fileBeginLength > 0)
|
||||
_webRequest.SetRequestHeader("Range", $"bytes={fileBeginLength}-");
|
||||
_webRequest.SendWebRequest();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,10 +71,13 @@ namespace YooAsset
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
//TODO 等待子线程验证文件完毕,该操作会挂起主线程
|
||||
//TODO 等待子线程验证文件完毕,该操作会挂起主线程!
|
||||
InternalUpdate();
|
||||
if (IsDone)
|
||||
break;
|
||||
|
||||
// 短暂休眠避免完全卡死
|
||||
System.Threading.Thread.Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace YooAsset
|
||||
{
|
||||
if (_deserializer == null)
|
||||
{
|
||||
_deserializer = new DeserializeManifestOperation(_fileData);
|
||||
_deserializer = new DeserializeManifestOperation(null, _fileData);
|
||||
_deserializer.StartOperation();
|
||||
AddChildOperation(_deserializer);
|
||||
}
|
||||
|
||||
@@ -3,11 +3,6 @@ namespace YooAsset
|
||||
{
|
||||
internal class DefaultUnpackFileSystemDefine
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件系统的优先级
|
||||
/// </summary>
|
||||
public const int DefaultPriority = 11;
|
||||
|
||||
/// <summary>
|
||||
/// 保存的资源文件的文件夹名称
|
||||
/// </summary>
|
||||
|
||||
@@ -46,12 +46,17 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 自定义参数:跨域下载服务接口
|
||||
/// </summary>
|
||||
public IRemoteServices RemoteServices { private set; get; } = null;
|
||||
public IRemoteServices RemoteServices { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义参数:解密方法类
|
||||
/// </summary>
|
||||
public IWebDecryptionServices DecryptionServices { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义参数:资源清单服务类
|
||||
/// </summary>
|
||||
public IManifestServices ManifestServices { private set; get; }
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -111,6 +116,10 @@ namespace YooAsset
|
||||
{
|
||||
DecryptionServices = (IWebDecryptionServices)value;
|
||||
}
|
||||
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES)
|
||||
{
|
||||
ManifestServices = (IManifestServices)value;
|
||||
}
|
||||
else
|
||||
{
|
||||
YooLogger.Warning($"Invalid parameter : {name}");
|
||||
|
||||
@@ -34,19 +34,20 @@ namespace YooAsset
|
||||
{
|
||||
if (_downloadAssetBundleOp == null)
|
||||
{
|
||||
string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
|
||||
string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
|
||||
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
|
||||
options.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
|
||||
options.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
|
||||
|
||||
options.SetURL(mainURL, fallbackURL);
|
||||
|
||||
if (_bundle.Encrypted)
|
||||
{
|
||||
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, options);
|
||||
_downloadAssetBundleOp = new DownloadEncryptAssetBundleOperation(_bundle, options, true, _fileSystem.DecryptionServices);
|
||||
_downloadAssetBundleOp.StartOperation();
|
||||
AddChildOperation(_downloadAssetBundleOp);
|
||||
}
|
||||
else
|
||||
{
|
||||
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, options);
|
||||
_downloadAssetBundleOp = new DownloadNormalAssetBundleOperation(_bundle, options, _fileSystem.DisableUnityWebCache);
|
||||
_downloadAssetBundleOp.StartOperation();
|
||||
AddChildOperation(_downloadAssetBundleOp);
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace YooAsset
|
||||
{
|
||||
if (_deserializer == null)
|
||||
{
|
||||
_deserializer = new DeserializeManifestOperation(_webDataRequestOp.Result);
|
||||
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _webDataRequestOp.Result);
|
||||
_deserializer.StartOperation();
|
||||
AddChildOperation(_deserializer);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,11 @@ namespace YooAsset
|
||||
/// 自定义参数:解密方法类
|
||||
/// </summary>
|
||||
public IWebDecryptionServices DecryptionServices { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 自定义参数:资源清单服务类
|
||||
/// </summary>
|
||||
public IManifestServices ManifestServices { private set; get; }
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -116,6 +121,10 @@ namespace YooAsset
|
||||
{
|
||||
DecryptionServices = (IWebDecryptionServices)value;
|
||||
}
|
||||
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES)
|
||||
{
|
||||
ManifestServices = (IManifestServices)value;
|
||||
}
|
||||
else
|
||||
{
|
||||
YooLogger.Warning($"Invalid parameter : {name}");
|
||||
|
||||
@@ -33,10 +33,11 @@ namespace YooAsset
|
||||
if (_loadCatalogFileOp == null)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
/*
|
||||
// 兼容性初始化
|
||||
// 说明:内置文件系统在编辑器下运行时需要动态生成
|
||||
string packageRoot = _fileSystem.FileRoot;
|
||||
bool result = DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(_fileSystem.PackageName, packageRoot);
|
||||
bool result = DefaultBuildinFileSystemBuild.CreateBuildinCatalogFile(_fileSystem.ManifestServices, _fileSystem.PackageName, packageRoot);
|
||||
if (result == false)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
@@ -44,6 +45,7 @@ namespace YooAsset
|
||||
Error = $"Create package catalog file failed ! See the detail error in console !";
|
||||
return;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
_loadCatalogFileOp = new LoadWebServerCatalogFileOperation(_fileSystem);
|
||||
|
||||
@@ -34,20 +34,20 @@ namespace YooAsset
|
||||
{
|
||||
if (_downloadAssetBundleOp == null)
|
||||
{
|
||||
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
|
||||
string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle);
|
||||
options.MainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath);
|
||||
options.FallbackURL = options.MainURL;
|
||||
string mainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath);
|
||||
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue, 60);
|
||||
options.SetURL(mainURL, mainURL);
|
||||
|
||||
if (_bundle.Encrypted)
|
||||
{
|
||||
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, options);
|
||||
_downloadAssetBundleOp = new DownloadEncryptAssetBundleOperation(_bundle, options, true, _fileSystem.DecryptionServices);
|
||||
_downloadAssetBundleOp.StartOperation();
|
||||
AddChildOperation(_downloadAssetBundleOp);
|
||||
}
|
||||
else
|
||||
{
|
||||
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, options);
|
||||
_downloadAssetBundleOp = new DownloadNormalAssetBundleOperation(_bundle, options, _fileSystem.DisableUnityWebCache);
|
||||
_downloadAssetBundleOp.StartOperation();
|
||||
AddChildOperation(_downloadAssetBundleOp);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace YooAsset
|
||||
{
|
||||
if (_deserializer == null)
|
||||
{
|
||||
_deserializer = new DeserializeManifestOperation(_webDataRequestOp.Result);
|
||||
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _webDataRequestOp.Result);
|
||||
_deserializer.StartOperation();
|
||||
AddChildOperation(_deserializer);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace YooAsset
|
||||
public const string INSTALL_CLEAR_MODE = "INSTALL_CLEAR_MODE";
|
||||
public const string REMOTE_SERVICES = "REMOTE_SERVICES";
|
||||
public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES";
|
||||
public const string MANIFEST_SERVICES = "MANIFEST_SERVICES";
|
||||
public const string APPEND_FILE_EXTENSION = "APPEND_FILE_EXTENSION";
|
||||
public const string DISABLE_CATALOG_FILE = "DISABLE_CATALOG_FILE";
|
||||
public const string DISABLE_UNITY_WEB_CACHE = "DISABLE_UNITY_WEB_CACHE";
|
||||
@@ -18,5 +19,6 @@ namespace YooAsset
|
||||
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_DEST_ROOT = "COPY_BUILDIN_PACKAGE_MANIFEST_DEST_ROOT";
|
||||
public const string COPY_LOCAL_FILE_SERVICES = "COPY_LOCAL_FILE_SERVICES";
|
||||
}
|
||||
}
|
||||
@@ -16,15 +16,15 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 主资源地址
|
||||
/// </summary>
|
||||
public string MainURL { set; get; }
|
||||
public string MainURL { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 备用资源地址
|
||||
/// </summary>
|
||||
public string FallbackURL { set; get; }
|
||||
public string FallbackURL { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 导入的本地文件路径
|
||||
/// 拷贝的本地文件路径
|
||||
/// </summary>
|
||||
public string ImportFilePath { set; get; }
|
||||
|
||||
@@ -33,22 +33,32 @@ namespace YooAsset
|
||||
FailedTryAgain = failedTryAgain;
|
||||
Timeout = timeout;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置下载地址
|
||||
/// </summary>
|
||||
public void SetURL(string mainURL, string fallbackURL)
|
||||
{
|
||||
MainURL = mainURL;
|
||||
FallbackURL = fallbackURL;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否有效
|
||||
/// </summary>
|
||||
public bool IsValid()
|
||||
{
|
||||
if (string.IsNullOrEmpty(MainURL) || string.IsNullOrEmpty(FallbackURL))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class FSDownloadFileOperation : AsyncOperationBase
|
||||
{
|
||||
public PackageBundle Bundle { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 引用计数
|
||||
/// </summary>
|
||||
public int RefCount { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// HTTP返回码
|
||||
/// </summary>
|
||||
public long HttpCode { protected set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前下载的字节数
|
||||
/// </summary>
|
||||
@@ -63,31 +73,8 @@ namespace YooAsset
|
||||
public FSDownloadFileOperation(PackageBundle bundle)
|
||||
{
|
||||
Bundle = bundle;
|
||||
RefCount = 0;
|
||||
HttpCode = 0;
|
||||
DownloadedBytes = 0;
|
||||
DownloadProgress = 0;
|
||||
}
|
||||
|
||||
internal override string InternalGetDesc()
|
||||
{
|
||||
return $"RefCount : {RefCount}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 减少引用计数
|
||||
/// </summary>
|
||||
public virtual void Release()
|
||||
{
|
||||
RefCount--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 增加引用计数
|
||||
/// </summary>
|
||||
public virtual void Reference()
|
||||
{
|
||||
RefCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal abstract class DefaultDownloadFileOperation : FSDownloadFileOperation
|
||||
{
|
||||
protected enum ESteps
|
||||
{
|
||||
None,
|
||||
CheckExists,
|
||||
CreateRequest,
|
||||
CheckRequest,
|
||||
VerifyTempFile,
|
||||
CheckVerifyTempFile,
|
||||
TryAgain,
|
||||
Done,
|
||||
}
|
||||
|
||||
// 下载参数
|
||||
protected readonly DownloadFileOptions Options;
|
||||
|
||||
// 请求相关
|
||||
protected UnityWebRequest _webRequest;
|
||||
protected string _requestURL;
|
||||
protected int _requestCount = 0;
|
||||
|
||||
// 超时相关
|
||||
protected bool _isAbort = false;
|
||||
protected long _latestDownloadBytes;
|
||||
protected float _latestDownloadRealtime;
|
||||
protected float _tryAgainTimer;
|
||||
|
||||
// 失败相关
|
||||
protected int FailedTryAgain;
|
||||
|
||||
|
||||
internal DefaultDownloadFileOperation(PackageBundle bundle, DownloadFileOptions options) : base(bundle)
|
||||
{
|
||||
Options = options;
|
||||
FailedTryAgain = options.FailedTryAgain;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络请求地址
|
||||
/// </summary>
|
||||
protected string GetRequestURL()
|
||||
{
|
||||
// 轮流返回请求地址
|
||||
_requestCount++;
|
||||
if (_requestCount % 2 == 0)
|
||||
return Options.FallbackURL;
|
||||
else
|
||||
return Options.MainURL;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置请求字段
|
||||
/// </summary>
|
||||
protected void ResetRequestFiled()
|
||||
{
|
||||
// 重置变量
|
||||
_isAbort = false;
|
||||
_latestDownloadBytes = 0;
|
||||
_latestDownloadRealtime = Time.realtimeSinceStartup;
|
||||
DownloadProgress = 0f;
|
||||
DownloadedBytes = 0;
|
||||
|
||||
// 重置计时器
|
||||
if (_tryAgainTimer > 0f)
|
||||
YooLogger.Warning($"Try again download : {_requestURL}");
|
||||
_tryAgainTimer = 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测请求超时
|
||||
/// </summary>
|
||||
protected void CheckRequestTimeout()
|
||||
{
|
||||
// 注意:在连续时间段内无新增下载数据及判定为超时
|
||||
if (_isAbort == false)
|
||||
{
|
||||
if (_latestDownloadBytes != DownloadedBytes)
|
||||
{
|
||||
_latestDownloadBytes = DownloadedBytes;
|
||||
_latestDownloadRealtime = UnityEngine.Time.realtimeSinceStartup;
|
||||
}
|
||||
|
||||
float offset = UnityEngine.Time.realtimeSinceStartup - _latestDownloadRealtime;
|
||||
if (offset > Options.Timeout)
|
||||
{
|
||||
YooLogger.Warning($"Download request timeout : {_requestURL}");
|
||||
if (_webRequest != null)
|
||||
_webRequest.Abort();
|
||||
_isAbort = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测请求结果
|
||||
/// </summary>
|
||||
protected bool CheckRequestResult()
|
||||
{
|
||||
HttpCode = _webRequest.responseCode;
|
||||
|
||||
#if UNITY_2020_3_OR_NEWER
|
||||
if (_webRequest.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
Error = _webRequest.error;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
if (_webRequest.isNetworkError || _webRequest.isHttpError)
|
||||
{
|
||||
Error = _webRequest.error;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,21 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal abstract class DownloadAssetBundleOperation : DefaultDownloadFileOperation
|
||||
internal abstract class DownloadAssetBundleOperation : AsyncOperationBase
|
||||
{
|
||||
internal DownloadAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AssetBundle对象
|
||||
/// </summary>
|
||||
public AssetBundle Result;
|
||||
|
||||
/// <summary>
|
||||
/// 下载进度
|
||||
/// </summary>
|
||||
public float DownloadProgress { protected set; get; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 下载大小
|
||||
/// </summary>
|
||||
public long DownloadedBytes { protected set; get; } = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class DownloadFileWrapper : FSDownloadFileOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Download,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly FSDownloadFileOperation _downloadFileOp;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal DownloadFileWrapper(FSDownloadFileOperation downloadFileOp) : base(downloadFileOp.Bundle)
|
||||
{
|
||||
_downloadFileOp = downloadFileOp;
|
||||
}
|
||||
internal override void InternalStart()
|
||||
{
|
||||
_steps = ESteps.Download;
|
||||
}
|
||||
internal override void InternalUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
if (IsWaitForAsyncComplete)
|
||||
_downloadFileOp.WaitForAsyncComplete();
|
||||
|
||||
if (_downloadFileOp.Status == EOperationStatus.None)
|
||||
return;
|
||||
|
||||
_downloadFileOp.UpdateOperation();
|
||||
Progress = _downloadFileOp.Progress;
|
||||
DownloadedBytes = _downloadFileOp.DownloadedBytes;
|
||||
DownloadProgress = _downloadFileOp.DownloadProgress;
|
||||
if (_downloadFileOp.IsDone == false)
|
||||
return;
|
||||
|
||||
_steps = ESteps.Done;
|
||||
Status = _downloadFileOp.Status;
|
||||
Error = _downloadFileOp.Error;
|
||||
HttpCode = _downloadFileOp.HttpCode;
|
||||
}
|
||||
}
|
||||
internal override void InternalWaitForAsyncComplete()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (ExecuteWhileDone())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Release()
|
||||
{
|
||||
_downloadFileOp.Release();
|
||||
}
|
||||
public override void Reference()
|
||||
{
|
||||
_downloadFileOp.Reference();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,33 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class DownloadWebEncryptAssetBundleOperation : DownloadAssetBundleOperation
|
||||
internal class DownloadEncryptAssetBundleOperation : DownloadAssetBundleOperation
|
||||
{
|
||||
protected enum ESteps
|
||||
{
|
||||
None,
|
||||
CreateRequest,
|
||||
CheckRequest,
|
||||
TryAgain,
|
||||
Done,
|
||||
}
|
||||
|
||||
private UnityWebDataRequestOperation _unityWebDataRequestOp;
|
||||
private readonly PackageBundle _bundle;
|
||||
private readonly DownloadFileOptions _options;
|
||||
private readonly bool _checkTimeout;
|
||||
private readonly IWebDecryptionServices _decryptionServices;
|
||||
private DownloadHandlerBuffer _downloadhandler;
|
||||
|
||||
protected int _requestCount = 0;
|
||||
protected float _tryAgainTimer;
|
||||
protected int _failedTryAgain;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal DownloadWebEncryptAssetBundleOperation(bool checkTimeout, IWebDecryptionServices decryptionServices, PackageBundle bundle, DownloadFileOptions options) : base(bundle, options)
|
||||
internal DownloadEncryptAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options, bool checkTimeout, IWebDecryptionServices decryptionServices)
|
||||
{
|
||||
_bundle = bundle;
|
||||
_options = options;
|
||||
_checkTimeout = checkTimeout;
|
||||
_decryptionServices = decryptionServices;
|
||||
}
|
||||
@@ -27,118 +43,87 @@ namespace YooAsset
|
||||
// 创建下载器
|
||||
if (_steps == ESteps.CreateRequest)
|
||||
{
|
||||
// 获取请求地址
|
||||
_requestURL = GetRequestURL();
|
||||
|
||||
// 重置变量
|
||||
ResetRequestFiled();
|
||||
|
||||
// 创建下载器
|
||||
CreateWebRequest();
|
||||
if (_decryptionServices == null)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"The {nameof(IWebDecryptionServices)} is null !";
|
||||
YooLogger.Error(Error);
|
||||
return;
|
||||
}
|
||||
|
||||
string url = GetRequestURL();
|
||||
_unityWebDataRequestOp = new UnityWebDataRequestOperation(url, _options.Timeout);
|
||||
_unityWebDataRequestOp.StartOperation();
|
||||
if (_checkTimeout == false)
|
||||
_unityWebDataRequestOp.DontCheckTimeout();
|
||||
_steps = ESteps.CheckRequest;
|
||||
}
|
||||
|
||||
// 检测下载结果
|
||||
if (_steps == ESteps.CheckRequest)
|
||||
{
|
||||
DownloadProgress = _webRequest.downloadProgress;
|
||||
DownloadedBytes = (long)_webRequest.downloadedBytes;
|
||||
Progress = DownloadProgress;
|
||||
if (_webRequest.isDone == false)
|
||||
{
|
||||
if (_checkTimeout)
|
||||
CheckRequestTimeout();
|
||||
_unityWebDataRequestOp.UpdateOperation();
|
||||
Progress = _unityWebDataRequestOp.Progress;
|
||||
DownloadProgress = _unityWebDataRequestOp.DownloadProgress;
|
||||
DownloadedBytes = _unityWebDataRequestOp.DownloadedBytes;
|
||||
if (_unityWebDataRequestOp.IsDone == false)
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查网络错误
|
||||
if (CheckRequestResult())
|
||||
if (_unityWebDataRequestOp.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
if (_decryptionServices == null)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"The {nameof(IWebDecryptionServices)} is null !";
|
||||
YooLogger.Error(Error);
|
||||
return;
|
||||
}
|
||||
|
||||
var fileData = _downloadhandler.data;
|
||||
if (fileData == null || fileData.Length == 0)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"The download handler data is null or empty !";
|
||||
YooLogger.Error(Error);
|
||||
return;
|
||||
}
|
||||
|
||||
AssetBundle assetBundle = LoadEncryptedAssetBundle(fileData);
|
||||
AssetBundle assetBundle = LoadEncryptedAssetBundle(_unityWebDataRequestOp.Result);
|
||||
if (assetBundle == null)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = "Download handler asset bundle object is null !";
|
||||
Error = "Failed load encrypted AssetBundle !";
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Result = assetBundle;
|
||||
Status = EOperationStatus.Succeed;
|
||||
Result = assetBundle;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.TryAgain;
|
||||
if (_failedTryAgain > 0)
|
||||
{
|
||||
_steps = ESteps.TryAgain;
|
||||
YooLogger.Warning($"Failed download : {_unityWebDataRequestOp.URL} Try again !");
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _unityWebDataRequestOp.Error;
|
||||
YooLogger.Error(Error);
|
||||
}
|
||||
}
|
||||
|
||||
// 注意:最终释放请求器
|
||||
DisposeWebRequest();
|
||||
}
|
||||
|
||||
// 重新尝试下载
|
||||
if (_steps == ESteps.TryAgain)
|
||||
{
|
||||
if (FailedTryAgain <= 0)
|
||||
{
|
||||
Status = EOperationStatus.Failed;
|
||||
_steps = ESteps.Done;
|
||||
YooLogger.Error(Error);
|
||||
return;
|
||||
}
|
||||
|
||||
_tryAgainTimer += Time.unscaledDeltaTime;
|
||||
if (_tryAgainTimer > 1f)
|
||||
{
|
||||
FailedTryAgain--;
|
||||
_tryAgainTimer = 0f;
|
||||
_failedTryAgain--;
|
||||
Progress = 0f;
|
||||
DownloadProgress = 0f;
|
||||
DownloadedBytes = 0;
|
||||
_steps = ESteps.CreateRequest;
|
||||
YooLogger.Warning(Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
internal override void InternalAbort()
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
DisposeWebRequest();
|
||||
}
|
||||
|
||||
private void CreateWebRequest()
|
||||
{
|
||||
_downloadhandler = new DownloadHandlerBuffer();
|
||||
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
|
||||
_webRequest.downloadHandler = _downloadhandler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
_webRequest.SendWebRequest();
|
||||
}
|
||||
private void DisposeWebRequest()
|
||||
{
|
||||
if (_webRequest != null)
|
||||
{
|
||||
//注意:引擎底层会自动调用Abort方法
|
||||
_webRequest.Dispose();
|
||||
_webRequest = null;
|
||||
}
|
||||
if (_unityWebDataRequestOp != null)
|
||||
_unityWebDataRequestOp.AbortOperation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -147,11 +132,24 @@ namespace YooAsset
|
||||
private AssetBundle LoadEncryptedAssetBundle(byte[] fileData)
|
||||
{
|
||||
var fileInfo = new WebDecryptFileInfo();
|
||||
fileInfo.BundleName = Bundle.BundleName;
|
||||
fileInfo.FileLoadCRC = Bundle.UnityCRC;
|
||||
fileInfo.BundleName = _bundle.BundleName;
|
||||
fileInfo.FileLoadCRC = _bundle.UnityCRC;
|
||||
fileInfo.FileData = fileData;
|
||||
var decryptResult = _decryptionServices.LoadAssetBundle(fileInfo);
|
||||
return decryptResult.Result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络请求地址
|
||||
/// </summary>
|
||||
protected string GetRequestURL()
|
||||
{
|
||||
// 轮流返回请求地址
|
||||
_requestCount++;
|
||||
if (_requestCount % 2 == 0)
|
||||
return _options.FallbackURL;
|
||||
else
|
||||
return _options.MainURL;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user