mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-14 19:40:47 +00:00
Compare commits
139 Commits
1.3.4
...
1.4.5-prev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
acca74dce7 | ||
|
|
d8e7892ab7 | ||
|
|
e887bf1fd7 | ||
|
|
145ca936e7 | ||
|
|
69c7a51215 | ||
|
|
c4875d4f80 | ||
|
|
eed3c9768b | ||
|
|
71e8392359 | ||
|
|
9be5ec0f31 | ||
|
|
a8a0c3831b | ||
|
|
ef31d5a938 | ||
|
|
812db6dafe | ||
|
|
66fe2f0995 | ||
|
|
3b40cc7833 | ||
|
|
5a01ca061a | ||
|
|
ef0cc05f5c | ||
|
|
c5c6e4ae23 | ||
|
|
1c2bbfea93 | ||
|
|
8893317f59 | ||
|
|
ca8b5c85dd | ||
|
|
2612764922 | ||
|
|
8ce8e81792 | ||
|
|
33a1b9d4bf | ||
|
|
03abac082c | ||
|
|
3672a7e1fa | ||
|
|
df27e7ba75 | ||
|
|
423655e1ca | ||
|
|
f620223613 | ||
|
|
365a94d7b7 | ||
|
|
a98efd83b6 | ||
|
|
cc75594747 | ||
|
|
e5de104933 | ||
|
|
954e76ab33 | ||
|
|
82bda518c9 | ||
|
|
cdc5bcd31f | ||
|
|
61f6d480ae | ||
|
|
df6df3548c | ||
|
|
ac839450e2 | ||
|
|
4fa01e1a29 | ||
|
|
db2a45ec35 | ||
|
|
76c6f5cc1c | ||
|
|
339b519881 | ||
|
|
de2fab1370 | ||
|
|
fd4b6794cc | ||
|
|
f3e3f7cf85 | ||
|
|
dd824254a9 | ||
|
|
16943d4590 | ||
|
|
a95697088b | ||
|
|
f771a98f25 | ||
|
|
3b1a8beadf | ||
|
|
209e9d7705 | ||
|
|
de09a042e6 | ||
|
|
66cd491493 | ||
|
|
4a158319e5 | ||
|
|
b322a848ba | ||
|
|
4e759134bd | ||
|
|
5c16171781 | ||
|
|
08ad68d4a2 | ||
|
|
2ace30acd8 | ||
|
|
fc55b1be82 | ||
|
|
b287dfedcf | ||
|
|
d6984f0ad4 | ||
|
|
85cb1ed3f6 | ||
|
|
32b5240fcc | ||
|
|
7b9fda2298 | ||
|
|
15a605b677 | ||
|
|
f4a3fcece8 | ||
|
|
d67fc31c26 | ||
|
|
889000d8a8 | ||
|
|
e827e74cc7 | ||
|
|
45ca1ebf02 | ||
|
|
3a81d7babd | ||
|
|
a1d5949177 | ||
|
|
d7ae52160b | ||
|
|
e3fa33b9b5 | ||
|
|
ac251114ff | ||
|
|
824d1c1501 | ||
|
|
ac88fd5cf6 | ||
|
|
5197d42807 | ||
|
|
7a0f4caa9b | ||
|
|
5bf1d29edc | ||
|
|
2687466ed4 | ||
|
|
14512d6470 | ||
|
|
32268f5a4a | ||
|
|
81401ca0b8 | ||
|
|
688cc271d5 | ||
|
|
a290353cfa | ||
|
|
6038e7acd6 | ||
|
|
4abec5a389 | ||
|
|
a2b51a8044 | ||
|
|
19cb239746 | ||
|
|
7aab610be5 | ||
|
|
4ec5a126ac | ||
|
|
32643caf51 | ||
|
|
114ebab6ae | ||
|
|
d1463e1fc6 | ||
|
|
aa49980231 | ||
|
|
2696da092d | ||
|
|
5415d95f36 | ||
|
|
efa71c8bb7 | ||
|
|
d59df4c561 | ||
|
|
140bcb037f | ||
|
|
2a4384e093 | ||
|
|
5aafed85ed | ||
|
|
6ad4b91c60 | ||
|
|
cd62686316 | ||
|
|
dcd606e573 | ||
|
|
f6f326119c | ||
|
|
f31e5e0d22 | ||
|
|
abc12d2a1d | ||
|
|
b7e2f084b1 | ||
|
|
adf1776b1e | ||
|
|
fd1edcdedf | ||
|
|
ebc25c401d | ||
|
|
67574bf759 | ||
|
|
e94923c3c6 | ||
|
|
5718d57b88 | ||
|
|
82cff36194 | ||
|
|
3e4e2d5eb6 | ||
|
|
015f09d27b | ||
|
|
3fedc5b1b3 | ||
|
|
4776ab9bd8 | ||
|
|
3bb01ef9a8 | ||
|
|
0204f5f68f | ||
|
|
217d88beaa | ||
|
|
77080b3934 | ||
|
|
83f6dc2f76 | ||
|
|
29b3ca4e69 | ||
|
|
9394ff49fd | ||
|
|
49949ecda5 | ||
|
|
1dab0f2b19 | ||
|
|
1cf03bf049 | ||
|
|
c00594738f | ||
|
|
d5f601b0eb | ||
|
|
304bff1f19 | ||
|
|
ce9e0cd88c | ||
|
|
40903d9ad5 | ||
|
|
0fc97ad2f1 | ||
|
|
2bb66ea583 |
@@ -2,6 +2,189 @@
|
||||
|
||||
All notable changes to this package will be documented in this file.
|
||||
|
||||
## [1.4.5-preview] - 2023-02-17
|
||||
|
||||
### Fixed
|
||||
|
||||
- (#67)修复了报告查看界面在Unity2021.3上的兼容性问题。
|
||||
- (#66)修复了在Unity2021.3上编辑器模拟模式运行报错的问题。
|
||||
|
||||
### Changed
|
||||
|
||||
- 接口变更:IPackRule
|
||||
|
||||
````c#
|
||||
/// <summary>
|
||||
/// 资源打包规则接口
|
||||
/// </summary>
|
||||
public interface IPackRule
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取打包规则结果
|
||||
/// </summary>
|
||||
PackRuleResult GetPackRuleResult(PackRuleData data);
|
||||
|
||||
/// <summary>
|
||||
/// 是否为原生文件打包规则
|
||||
/// </summary>
|
||||
bool IsRawFilePackRule();
|
||||
}
|
||||
````
|
||||
|
||||
## [1.4.4-preview] - 2023-02-14
|
||||
|
||||
### Fixed
|
||||
|
||||
- (#65)修复了AssetBundle构建宏逻辑错误。
|
||||
- 修复了AssetBundle加载宏逻辑错误。
|
||||
|
||||
## [1.4.3-preview] - 2023-02-10
|
||||
|
||||
全新的缓存系统!
|
||||
|
||||
### Fixed
|
||||
|
||||
- 修复了WebGL平台本地文件验证报错。
|
||||
- 修复了WEBGL平台加载原生文件失败的问题。
|
||||
- 修复了通过Handle句柄查询资源包下载进度为零的问题。
|
||||
|
||||
### Changed
|
||||
|
||||
- 着色器变种收集增加分批次处理功能。
|
||||
- Unity2021版本开始不再支持内置构建管线。
|
||||
|
||||
### Removed
|
||||
|
||||
- 太空战机DEMO移除了BetterStreamingAssets插件。
|
||||
|
||||
## [1.4.2-preview] - 2023-01-03
|
||||
|
||||
### Fixed
|
||||
|
||||
- 修复了清单解析异步操作的进度条变化错误。
|
||||
- 修复了更新资源清单错误计算超时时间的问题。
|
||||
|
||||
## [1.4.1-preview] - 2022-12-26
|
||||
|
||||
### Fixed
|
||||
|
||||
- 修复了开启UniqueBundleName选项后,SBP构建报错的问题。
|
||||
|
||||
### Added
|
||||
|
||||
- 新增了AssetsPackage.PreDownloadPackageAsync()方法
|
||||
|
||||
````c#
|
||||
/// <summary>
|
||||
/// 预下载指定版本的包裹资源
|
||||
/// </summary>
|
||||
/// <param name="packageVersion">下载的包裹版本</param>
|
||||
/// <param name="timeout">超时时间(默认值:60秒)</param>
|
||||
public PreDownloadPackageOperation PreDownloadPackageAsync(string packageVersion, int timeout = 60)
|
||||
````
|
||||
|
||||
- 新增了OperationHandleBase.GetDownloadReport()方法
|
||||
|
||||
````c#
|
||||
/// <summary>
|
||||
/// 获取下载报告
|
||||
/// </summary>
|
||||
public DownloadReport GetDownloadReport();
|
||||
````
|
||||
|
||||
### Changed
|
||||
|
||||
- 优化了资源清单更新流程,支持缓存下载的清单。
|
||||
- 优化了清单文件的解析流程,支持分帧解析避免卡顿。
|
||||
- 优化了缓存文件的验证流程,支持分帧处理。
|
||||
- 初始化的时候支持覆盖安装检测,然后清理所有的缓存清单文件。
|
||||
- ClearPackageUnusedCacheFilesAsync重名为ClearUnusedCacheFilesAsync
|
||||
|
||||
## [1.4.0-preview] - 2022-12-04
|
||||
|
||||
### Fixed
|
||||
|
||||
- (#46)修复了资源包初始化失败之后,再次初始化发生异常的问题。
|
||||
- 修复了在初始化失败的之后,销毁YooAssets会报异常的问题。
|
||||
|
||||
### Changed
|
||||
|
||||
- 优化了资源收集界面,可以选择显示中文别名。
|
||||
- **优化了补丁清单序列化方式,由文本数据修改为二进制数据。**
|
||||
- 资源操作句柄增加using支持。
|
||||
|
||||
## [1.3.7] - 2022-11-26
|
||||
|
||||
全新的太空战机Demo !
|
||||
|
||||
### Fixed
|
||||
|
||||
- (#45)修复了package列表更新触发的异常。
|
||||
|
||||
### Added
|
||||
|
||||
- 新增了YooAssets.Destroy()资源系统销毁方法。
|
||||
|
||||
```C#
|
||||
/// <summary>
|
||||
/// 销毁资源系统
|
||||
/// </summary>
|
||||
public static void Destroy();
|
||||
```
|
||||
|
||||
### Changed
|
||||
|
||||
- 优化了资源收集规则,原生文件打包名称现在已经包含文件后缀名。
|
||||
- 优化了资源收集规则,非原生文件收集器自动移除Unity无法识别的文件。
|
||||
- 优化了调试信息窗口,列表元素的加载状态显示为文本。
|
||||
|
||||
## [1.3.5] - 2022-11-19
|
||||
|
||||
### Fixed
|
||||
|
||||
- 修复了同步接口加载加密文件失败的问题。
|
||||
|
||||
### Added
|
||||
|
||||
- 新增了方法AssetsPackage.ClearPackageUnusedCacheFilesAsync()
|
||||
|
||||
```c#
|
||||
/// <summary>
|
||||
/// 清理本地包裹未使用的缓存文件
|
||||
/// </summary>
|
||||
public ClearPackageUnusedCacheFilesOperation ClearPackageUnusedCacheFilesAsync()
|
||||
```
|
||||
|
||||
- 新增了方法AssetsPackage.LoadRawFileAsync()
|
||||
|
||||
```c#
|
||||
/// <summary>
|
||||
/// 异步加载原生文件
|
||||
/// </summary>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
public RawFileOperationHandle LoadRawFileAsync(string location)
|
||||
```
|
||||
|
||||
- 新增了方法AssetsPackage.LoadRawFileSync()
|
||||
|
||||
```c#
|
||||
/// <summary>
|
||||
/// 同步加载原生文件
|
||||
/// </summary>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
public RawFileOperationHandle LoadRawFileSync(string location)
|
||||
```
|
||||
|
||||
### Changed
|
||||
|
||||
- 重命名AssetsPackage.UpdateStaticVersionAsync()为AssetsPackage.UpdatePackageVersionAsync();
|
||||
- 重命名AssetsPackage.UpdateManifestAsync()为AssetsPackage.UpdatePackageManifestAsync();
|
||||
|
||||
### Removed
|
||||
|
||||
- 移除了方法YooAssets.ClearUnusedCacheFiles()
|
||||
- 移除了方法AssetsPackage.GetRawFileAsync()
|
||||
|
||||
## [1.3.4] - 2022-11-04
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -220,15 +220,27 @@ namespace YooAsset.Editor
|
||||
|
||||
private void RefreshWindow()
|
||||
{
|
||||
var buildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline;
|
||||
var buildMode = AssetBundleBuilderSettingData.Setting.BuildMode;
|
||||
var copyOption = AssetBundleBuilderSettingData.Setting.CopyBuildinFileOption;
|
||||
bool enableElement = buildMode == EBuildMode.ForceRebuild;
|
||||
bool tagsFiledVisible = copyOption == ECopyBuildinFileOption.ClearAndCopyByTags || copyOption == ECopyBuildinFileOption.OnlyCopyByTags;
|
||||
_encryptionField.SetEnabled(enableElement);
|
||||
_compressionField.SetEnabled(enableElement);
|
||||
_outputNameStyleField.SetEnabled(enableElement);
|
||||
_copyBuildinFileOptionField.SetEnabled(enableElement);
|
||||
_copyBuildinFileTagsField.SetEnabled(enableElement);
|
||||
|
||||
if (buildPipeline == EBuildPipeline.BuiltinBuildPipeline)
|
||||
{
|
||||
_compressionField.SetEnabled(enableElement);
|
||||
_outputNameStyleField.SetEnabled(enableElement);
|
||||
_copyBuildinFileOptionField.SetEnabled(enableElement);
|
||||
_copyBuildinFileTagsField.SetEnabled(enableElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
_compressionField.SetEnabled(true);
|
||||
_outputNameStyleField.SetEnabled(true);
|
||||
_copyBuildinFileOptionField.SetEnabled(true);
|
||||
_copyBuildinFileTagsField.SetEnabled(true);
|
||||
}
|
||||
|
||||
_copyBuildinFileTagsField.visible = tagsFiledVisible;
|
||||
}
|
||||
private void SaveBtn_clicked()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
@@ -9,6 +10,7 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
public static string SimulateBuild(string packageName)
|
||||
{
|
||||
Debug.Log($"Begin to create simulate package : {packageName}");
|
||||
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot();
|
||||
BuildParameters buildParameters = new BuildParameters();
|
||||
buildParameters.OutputRoot = defaultOutputRoot;
|
||||
@@ -21,7 +23,7 @@ namespace YooAsset.Editor
|
||||
var buildResult = builder.Run(buildParameters);
|
||||
if (buildResult.Success)
|
||||
{
|
||||
string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||
string manifestFileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||
string manifestFilePath = $"{buildResult.OutputPackageDirectory}/{manifestFileName}";
|
||||
return manifestFilePath;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ namespace YooAsset.Editor
|
||||
{
|
||||
public class BuildAssetInfo
|
||||
{
|
||||
private string _mainBundleName;
|
||||
private string _shareBundleName;
|
||||
private bool _isAddAssetTags = false;
|
||||
private readonly HashSet<string> _referenceBundleNames = new HashSet<string>();
|
||||
|
||||
@@ -17,6 +15,11 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
public ECollectorType CollectorType { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 资源包完整名称
|
||||
/// </summary>
|
||||
public string BundleName { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 可寻址地址
|
||||
/// </summary>
|
||||
@@ -54,10 +57,10 @@ namespace YooAsset.Editor
|
||||
public List<BuildAssetInfo> AllDependAssetInfos { private set; get; }
|
||||
|
||||
|
||||
public BuildAssetInfo(ECollectorType collectorType, string mainBundleName, string address, string assetPath, bool isRawAsset)
|
||||
public BuildAssetInfo(ECollectorType collectorType, string bundleName, string address, string assetPath, bool isRawAsset)
|
||||
{
|
||||
_mainBundleName = mainBundleName;
|
||||
CollectorType = collectorType;
|
||||
BundleName = bundleName;
|
||||
Address = address;
|
||||
AssetPath = assetPath;
|
||||
IsRawAsset = isRawAsset;
|
||||
@@ -133,24 +136,12 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
public bool HasBundleName()
|
||||
{
|
||||
string bundleName = GetBundleName();
|
||||
if (string.IsNullOrEmpty(bundleName))
|
||||
if (string.IsNullOrEmpty(BundleName))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取资源包名称
|
||||
/// </summary>
|
||||
public string GetBundleName()
|
||||
{
|
||||
if (CollectorType == ECollectorType.None)
|
||||
return _shareBundleName;
|
||||
else
|
||||
return _mainBundleName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加关联的资源包名称
|
||||
/// </summary>
|
||||
@@ -164,48 +155,32 @@ namespace YooAsset.Editor
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算主资源或共享资源的完整包名
|
||||
/// 计算共享资源包的完整包名
|
||||
/// </summary>
|
||||
public void CalculateFullBundleName(bool uniqueBundleName, string packageName)
|
||||
public void CalculateShareBundleName(bool uniqueBundleName, string packageName, string shadersBundleName)
|
||||
{
|
||||
if (CollectorType == ECollectorType.None)
|
||||
if (CollectorType != ECollectorType.None)
|
||||
return;
|
||||
|
||||
if (IsRawAsset)
|
||||
throw new Exception("Should never get here !");
|
||||
|
||||
if (IsShaderAsset)
|
||||
{
|
||||
if (IsRawAsset)
|
||||
throw new Exception("Should never get here !");
|
||||
|
||||
if (IsShaderAsset)
|
||||
{
|
||||
string shareBundleName = YooAssetSettingsData.GetUnityShadersBundleFullName();
|
||||
_shareBundleName = EditorTools.GetRegularPath(shareBundleName).ToLower();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_referenceBundleNames.Count > 1)
|
||||
{
|
||||
IPackRule packRule = PackDirectory.StaticPackRule;
|
||||
var bundleName = packRule.GetBundleName(new PackRuleData(AssetPath));
|
||||
var shareBundleName = $"share_{bundleName}.{YooAssetSettingsData.Setting.AssetBundleFileVariant}";
|
||||
_shareBundleName = EditorTools.GetRegularPath(shareBundleName).ToLower();
|
||||
}
|
||||
}
|
||||
|
||||
if (uniqueBundleName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_shareBundleName) == false)
|
||||
_shareBundleName = $"{packageName.ToLower()}_{_shareBundleName}";
|
||||
}
|
||||
BundleName = shadersBundleName;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsRawAsset)
|
||||
if (_referenceBundleNames.Count > 1)
|
||||
{
|
||||
string mainBundleName = $"{_mainBundleName}.{YooAssetSettingsData.Setting.RawFileVariant}";
|
||||
_mainBundleName = EditorTools.GetRegularPath(mainBundleName).ToLower();
|
||||
IPackRule packRule = PackDirectory.StaticPackRule;
|
||||
PackRuleResult packRuleResult = packRule.GetPackRuleResult(new PackRuleData(AssetPath));
|
||||
BundleName = packRuleResult.GetShareBundleName(packageName, uniqueBundleName);
|
||||
}
|
||||
else
|
||||
{
|
||||
string mainBundleName = $"{_mainBundleName}.{YooAssetSettingsData.Setting.AssetBundleFileVariant}";
|
||||
_mainBundleName = EditorTools.GetRegularPath(mainBundleName).ToLower(); ;
|
||||
// 注意:被引用次数小于1的资源不需要设置资源包名称
|
||||
BundleName = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,13 +182,14 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
internal PatchBundle CreatePatchBundle()
|
||||
{
|
||||
string fileHash = PatchInfo.PatchFileHash;
|
||||
string fileCRC = PatchInfo.PatchFileCRC;
|
||||
long fileSize = PatchInfo.PatchFileSize;
|
||||
bool isRawFile = IsRawFile;
|
||||
byte loadMethod = (byte)LoadMethod;
|
||||
string[] tags = GetBundleTags();
|
||||
PatchBundle patchBundle = new PatchBundle(BundleName, fileHash, fileCRC, fileSize, isRawFile, loadMethod, tags);
|
||||
PatchBundle patchBundle = new PatchBundle();
|
||||
patchBundle.BundleName = BundleName;
|
||||
patchBundle.FileHash = PatchInfo.PatchFileHash;
|
||||
patchBundle.FileCRC = PatchInfo.PatchFileCRC;
|
||||
patchBundle.FileSize = PatchInfo.PatchFileSize;
|
||||
patchBundle.IsRawFile = IsRawFile;
|
||||
patchBundle.LoadMethod = (byte)LoadMethod;
|
||||
patchBundle.Tags = GetBundleTags();
|
||||
return patchBundle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,11 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
public bool UniqueBundleName;
|
||||
|
||||
/// <summary>
|
||||
/// 着色器统一的全名称
|
||||
/// </summary>
|
||||
public string ShadersBundleName;
|
||||
|
||||
/// <summary>
|
||||
/// 资源包列表
|
||||
/// </summary>
|
||||
@@ -35,7 +40,7 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
public void PackAsset(BuildAssetInfo assetInfo)
|
||||
{
|
||||
string bundleName = assetInfo.GetBundleName();
|
||||
string bundleName = assetInfo.BundleName;
|
||||
if (string.IsNullOrEmpty(bundleName))
|
||||
throw new Exception("Should never get here !");
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@ namespace YooAsset.Editor
|
||||
/// 执行资源构建上下文
|
||||
/// </summary>
|
||||
public static BuildMapContext CreateBuildMap(EBuildMode buildMode, string packageName)
|
||||
{
|
||||
BuildMapContext context = new BuildMapContext();
|
||||
{
|
||||
Dictionary<string, BuildAssetInfo> buildAssetDic = new Dictionary<string, BuildAssetInfo>(1000);
|
||||
|
||||
// 1. 检测配置合法性
|
||||
@@ -22,7 +21,7 @@ namespace YooAsset.Editor
|
||||
var buildResult = AssetBundleCollectorSettingData.Setting.GetPackageAssets(buildMode, packageName);
|
||||
List<CollectAssetInfo> allCollectAssets = buildResult.CollectAssets;
|
||||
|
||||
// 3. 剔除未被引用的依赖资源
|
||||
// 3. 剔除未被引用的依赖项资源
|
||||
List<CollectAssetInfo> removeDependList = new List<CollectAssetInfo>();
|
||||
foreach (var collectAssetInfo in allCollectAssets)
|
||||
{
|
||||
@@ -42,7 +41,8 @@ namespace YooAsset.Editor
|
||||
{
|
||||
if (buildAssetDic.ContainsKey(collectAssetInfo.AssetPath) == false)
|
||||
{
|
||||
var buildAssetInfo = new BuildAssetInfo(collectAssetInfo.CollectorType, collectAssetInfo.BundleName,
|
||||
var buildAssetInfo = new BuildAssetInfo(
|
||||
collectAssetInfo.CollectorType, collectAssetInfo.BundleName,
|
||||
collectAssetInfo.Address, collectAssetInfo.AssetPath, collectAssetInfo.IsRawAsset);
|
||||
buildAssetInfo.AddAssetTags(collectAssetInfo.AssetTags);
|
||||
buildAssetInfo.AddBundleTags(collectAssetInfo.AssetTags);
|
||||
@@ -54,32 +54,28 @@ namespace YooAsset.Editor
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 录入相关依赖的资源
|
||||
// 5. 录入所有收集资源的依赖资源
|
||||
foreach (var collectAssetInfo in allCollectAssets)
|
||||
{
|
||||
string collectAssetBundleName = collectAssetInfo.BundleName;
|
||||
foreach (var dependAssetPath in collectAssetInfo.DependAssets)
|
||||
{
|
||||
if (buildAssetDic.ContainsKey(dependAssetPath))
|
||||
{
|
||||
buildAssetDic[dependAssetPath].AddBundleTags(collectAssetInfo.AssetTags);
|
||||
buildAssetDic[dependAssetPath].AddReferenceBundleName(collectAssetInfo.BundleName);
|
||||
buildAssetDic[dependAssetPath].AddReferenceBundleName(collectAssetBundleName);
|
||||
}
|
||||
else
|
||||
{
|
||||
var buildAssetInfo = new BuildAssetInfo(dependAssetPath);
|
||||
buildAssetInfo.AddBundleTags(collectAssetInfo.AssetTags);
|
||||
buildAssetInfo.AddReferenceBundleName(collectAssetInfo.BundleName);
|
||||
buildAssetInfo.AddReferenceBundleName(collectAssetBundleName);
|
||||
buildAssetDic.Add(dependAssetPath, buildAssetInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 6. 记录关键信息
|
||||
context.AssetFileCount = buildAssetDic.Count;
|
||||
context.EnableAddressable = buildResult.EnableAddressable;
|
||||
context.UniqueBundleName = buildResult.UniqueBundleName;
|
||||
|
||||
// 7. 填充主动收集资源的依赖列表
|
||||
// 6. 填充所有收集资源的依赖列表
|
||||
foreach (var collectAssetInfo in allCollectAssets)
|
||||
{
|
||||
var dependAssetInfos = new List<BuildAssetInfo>(collectAssetInfo.DependAssets.Count);
|
||||
@@ -93,10 +89,18 @@ namespace YooAsset.Editor
|
||||
buildAssetDic[collectAssetInfo.AssetPath].SetAllDependAssetInfos(dependAssetInfos);
|
||||
}
|
||||
|
||||
// 8. 计算完整的资源包名
|
||||
// 7. 记录关键信息
|
||||
BuildMapContext context = new BuildMapContext();
|
||||
context.AssetFileCount = buildAssetDic.Count;
|
||||
context.EnableAddressable = buildResult.Command.EnableAddressable;
|
||||
context.UniqueBundleName = buildResult.Command.UniqueBundleName;
|
||||
context.ShadersBundleName = buildResult.ShadersBundleName;
|
||||
|
||||
// 8. 计算共享的资源包名
|
||||
var command = buildResult.Command;
|
||||
foreach (KeyValuePair<string, BuildAssetInfo> pair in buildAssetDic)
|
||||
{
|
||||
pair.Value.CalculateFullBundleName(buildResult.UniqueBundleName, buildResult.PackageName);
|
||||
pair.Value.CalculateShareBundleName(command.UniqueBundleName, command.PackageName, buildResult.ShadersBundleName);
|
||||
}
|
||||
|
||||
// 9. 移除不参与构建的资源
|
||||
|
||||
@@ -33,8 +33,7 @@ namespace YooAsset.Editor
|
||||
// 开始构建
|
||||
IBundleBuildResults buildResults;
|
||||
var buildParameters = buildParametersContext.GetSBPBuildParameters();
|
||||
var shadersBunldeName = YooAssetSettingsData.GetUnityShadersBundleFullName();
|
||||
var taskList = SBPBuildTasks.Create(shadersBunldeName);
|
||||
var taskList = SBPBuildTasks.Create(buildMapContext.ShadersBundleName);
|
||||
ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParameters, buildContent, out buildResults, taskList);
|
||||
if (exitCode < 0)
|
||||
{
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace YooAsset.Editor
|
||||
|
||||
// 拷贝补丁清单文件
|
||||
{
|
||||
string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildPackageName, buildPackageVersion);
|
||||
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildPackageName, buildPackageVersion);
|
||||
string sourcePath = $"{packageOutputDirectory}/{fileName}";
|
||||
string destPath = $"{streamingAssetsDirectory}/{fileName}";
|
||||
EditorTools.CopyFile(sourcePath, destPath, true);
|
||||
@@ -53,7 +53,7 @@ namespace YooAsset.Editor
|
||||
|
||||
// 拷贝补丁清单哈希文件
|
||||
{
|
||||
string fileName = YooAssetSettingsData.GetPatchManifestHashFileName(buildPackageName, buildPackageVersion);
|
||||
string fileName = YooAssetSettingsData.GetPackageHashFileName(buildPackageName, buildPackageVersion);
|
||||
string sourcePath = $"{packageOutputDirectory}/{fileName}";
|
||||
string destPath = $"{streamingAssetsDirectory}/{fileName}";
|
||||
EditorTools.CopyFile(sourcePath, destPath, true);
|
||||
@@ -61,7 +61,7 @@ namespace YooAsset.Editor
|
||||
|
||||
// 拷贝补丁清单版本文件
|
||||
{
|
||||
string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(buildPackageName);
|
||||
string fileName = YooAssetSettingsData.GetPackageVersionFileName(buildPackageName);
|
||||
string sourcePath = $"{packageOutputDirectory}/{fileName}";
|
||||
string destPath = $"{streamingAssetsDirectory}/{fileName}";
|
||||
EditorTools.CopyFile(sourcePath, destPath, true);
|
||||
|
||||
@@ -47,28 +47,36 @@ namespace YooAsset.Editor
|
||||
if (buildParameters.BuildMode == EBuildMode.IncrementalBuild)
|
||||
{
|
||||
var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
|
||||
UpdateBuiltInBundleReference(patchManifest, buildResultContext.Results);
|
||||
UpdateBuiltInBundleReference(patchManifest, buildResultContext.Results, buildMapContext.ShadersBundleName);
|
||||
}
|
||||
}
|
||||
|
||||
// 创建补丁清单文件
|
||||
// 创建补丁清单文本文件
|
||||
{
|
||||
string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||
string filePath = $"{packageOutputDirectory}/{fileName}";
|
||||
PatchManifestTools.SerializeToJson(filePath, patchManifest);
|
||||
BuildRunner.Log($"创建补丁清单文件:{filePath}");
|
||||
}
|
||||
|
||||
// 创建补丁清单二进制文件
|
||||
string packageHash;
|
||||
{
|
||||
string fileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||
string filePath = $"{packageOutputDirectory}/{fileName}";
|
||||
PatchManifest.Serialize(filePath, patchManifest);
|
||||
PatchManifestTools.SerializeToBinary(filePath, patchManifest);
|
||||
packageHash = HashUtility.FileMD5(filePath);
|
||||
BuildRunner.Log($"创建补丁清单文件:{filePath}");
|
||||
|
||||
var patchManifestContext = new PatchManifestContext();
|
||||
string jsonData = FileUtility.ReadFile(filePath);
|
||||
patchManifestContext.Manifest = PatchManifest.Deserialize(jsonData);
|
||||
PatchManifestContext patchManifestContext = new PatchManifestContext();
|
||||
byte[] bytesData = FileUtility.ReadAllBytes(filePath);
|
||||
patchManifestContext.Manifest = PatchManifestTools.DeserializeFromBinary(bytesData);
|
||||
context.SetContextObject(patchManifestContext);
|
||||
}
|
||||
|
||||
// 创建补丁清单哈希文件
|
||||
{
|
||||
string fileName = YooAssetSettingsData.GetPatchManifestHashFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||
string fileName = YooAssetSettingsData.GetPackageHashFileName(buildParameters.PackageName, buildParameters.PackageVersion);
|
||||
string filePath = $"{packageOutputDirectory}/{fileName}";
|
||||
FileUtility.CreateFile(filePath, packageHash);
|
||||
BuildRunner.Log($"创建补丁清单哈希文件:{filePath}");
|
||||
@@ -76,7 +84,7 @@ namespace YooAsset.Editor
|
||||
|
||||
// 创建补丁清单版本文件
|
||||
{
|
||||
string fileName = YooAssetSettingsData.GetPatchManifestVersionFileName(buildParameters.PackageName);
|
||||
string fileName = YooAssetSettingsData.GetPackageVersionFileName(buildParameters.PackageName);
|
||||
string filePath = $"{packageOutputDirectory}/{fileName}";
|
||||
FileUtility.CreateFile(filePath, buildParameters.PackageVersion);
|
||||
BuildRunner.Log($"创建补丁清单版本文件:{filePath}");
|
||||
@@ -89,7 +97,6 @@ namespace YooAsset.Editor
|
||||
private List<PatchBundle> GetAllPatchBundle(BuildContext context)
|
||||
{
|
||||
var buildMapContext = context.GetContextObject<BuildMapContext>();
|
||||
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
|
||||
|
||||
List<PatchBundle> result = new List<PatchBundle>(1000);
|
||||
foreach (var bundleInfo in buildMapContext.BundleInfos)
|
||||
@@ -120,7 +127,7 @@ namespace YooAsset.Editor
|
||||
patchAsset.Address = string.Empty;
|
||||
patchAsset.AssetPath = assetInfo.AssetPath;
|
||||
patchAsset.AssetTags = assetInfo.AssetTags.ToArray();
|
||||
patchAsset.BundleID = GetAssetBundleID(assetInfo.GetBundleName(), patchManifest);
|
||||
patchAsset.BundleID = GetAssetBundleID(assetInfo.BundleName, patchManifest);
|
||||
patchAsset.DependIDs = GetAssetBundleDependIDs(patchAsset.BundleID, assetInfo, patchManifest);
|
||||
result.Add(patchAsset);
|
||||
}
|
||||
@@ -134,7 +141,7 @@ namespace YooAsset.Editor
|
||||
{
|
||||
if (dependAssetInfo.HasBundleName())
|
||||
{
|
||||
int bundleID = GetAssetBundleID(dependAssetInfo.GetBundleName(), patchManifest);
|
||||
int bundleID = GetAssetBundleID(dependAssetInfo.BundleName, patchManifest);
|
||||
if (mainBundleID != bundleID)
|
||||
{
|
||||
if (result.Contains(bundleID) == false)
|
||||
@@ -157,10 +164,9 @@ namespace YooAsset.Editor
|
||||
/// <summary>
|
||||
/// 更新Unity内置资源包的引用关系
|
||||
/// </summary>
|
||||
private void UpdateBuiltInBundleReference(PatchManifest patchManifest, IBundleBuildResults buildResults)
|
||||
private void UpdateBuiltInBundleReference(PatchManifest patchManifest, IBundleBuildResults buildResults, string shadersBunldeName)
|
||||
{
|
||||
// 获取所有依赖着色器资源包的资源包列表
|
||||
string shadersBunldeName = YooAssetSettingsData.GetUnityShadersBundleFullName();
|
||||
List<string> shaderBundleReferenceList = new List<string>();
|
||||
foreach (var valuePair in buildResults.BundleInfos)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace YooAsset.Editor
|
||||
throw new Exception("请选择目标平台");
|
||||
if (string.IsNullOrEmpty(buildParameters.PackageName))
|
||||
throw new Exception("包裹名称不能为空");
|
||||
if(string.IsNullOrEmpty(buildParameters.PackageVersion))
|
||||
if (string.IsNullOrEmpty(buildParameters.PackageVersion))
|
||||
throw new Exception("包裹版本不能为空");
|
||||
|
||||
if (buildParameters.BuildMode != EBuildMode.SimulateBuild)
|
||||
|
||||
@@ -48,7 +48,8 @@ namespace YooAsset.Editor
|
||||
// 4.更新补丁包输出的文件路径
|
||||
foreach (var bundleInfo in buildMapContext.BundleInfos)
|
||||
{
|
||||
string patchFileName = PatchManifest.CreateBundleFileName(outputNameStyle, bundleInfo.BundleName, bundleInfo.PatchInfo.PatchFileHash);
|
||||
string patchFileExtension = PatchManifestTools.GetRemoteBundleFileExtension(bundleInfo.BundleName);
|
||||
string patchFileName = PatchManifestTools.GetRemoteBundleFileName(outputNameStyle, bundleInfo.BundleName, patchFileExtension, bundleInfo.PatchInfo.PatchFileHash);
|
||||
bundleInfo.PatchInfo.PatchOutputFilePath = $"{packageOutputDirectory}/{patchFileName}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,23 +7,13 @@ namespace YooAsset.Editor
|
||||
public enum EOutputNameStyle
|
||||
{
|
||||
/// <summary>
|
||||
/// 000000000000000f000000000000000
|
||||
/// 哈希值名称
|
||||
/// </summary>
|
||||
HashName = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 000000000000000f000000000000000.bundle
|
||||
/// 资源包名称 + 哈希值名称
|
||||
/// </summary>
|
||||
HashName_Extension = 2,
|
||||
|
||||
/// <summary>
|
||||
/// bundle_name_000000000000000f000000000000000
|
||||
/// </summary>
|
||||
BundleName_HashName = 3,
|
||||
|
||||
/// <summary>
|
||||
/// bundle_name_000000000000000f000000000000000.bundle
|
||||
/// </summary>
|
||||
BundleName_HashName_Extension = 4,
|
||||
BundleName_HashName = 4,
|
||||
}
|
||||
}
|
||||
@@ -142,11 +142,14 @@ namespace YooAsset.Editor
|
||||
}
|
||||
|
||||
Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(1000);
|
||||
bool isRawAsset = PackRuleName == nameof(PackRawFile);
|
||||
|
||||
// 检测是否为原生资源打包规则
|
||||
IPackRule packRuleInstance = AssetBundleCollectorSettingData.GetPackRuleInstance(PackRuleName);
|
||||
bool isRawFilePackRule = packRuleInstance.IsRawFilePackRule();
|
||||
|
||||
// 检测原生资源包的收集器类型
|
||||
if (isRawAsset && CollectorType != ECollectorType.MainAssetCollector)
|
||||
throw new Exception($"The raw file must be set to {nameof(ECollectorType)}.{ECollectorType.MainAssetCollector} : {CollectPath}");
|
||||
if (isRawFilePackRule && CollectorType != ECollectorType.MainAssetCollector)
|
||||
throw new Exception($"The raw file pack rule must be set to {nameof(ECollectorType)}.{ECollectorType.MainAssetCollector} : {CollectPath}");
|
||||
|
||||
if (string.IsNullOrEmpty(CollectPath))
|
||||
throw new Exception($"The collect path is null or empty in group : {group.GroupName}");
|
||||
@@ -158,11 +161,11 @@ namespace YooAsset.Editor
|
||||
string[] findAssets = EditorTools.FindAssets(EAssetSearchType.All, collectDirectory);
|
||||
foreach (string assetPath in findAssets)
|
||||
{
|
||||
if (IsValidateAsset(assetPath) && IsCollectAsset(assetPath))
|
||||
if (IsValidateAsset(assetPath, isRawFilePackRule) && IsCollectAsset(assetPath))
|
||||
{
|
||||
if (result.ContainsKey(assetPath) == false)
|
||||
{
|
||||
var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawAsset);
|
||||
var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawFilePackRule);
|
||||
result.Add(assetPath, collectAssetInfo);
|
||||
}
|
||||
else
|
||||
@@ -175,9 +178,9 @@ namespace YooAsset.Editor
|
||||
else
|
||||
{
|
||||
string assetPath = CollectPath;
|
||||
if (IsValidateAsset(assetPath) && IsCollectAsset(assetPath))
|
||||
if (IsValidateAsset(assetPath, isRawFilePackRule) && IsCollectAsset(assetPath))
|
||||
{
|
||||
var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawAsset);
|
||||
var collectAssetInfo = CreateCollectAssetInfo(command, group, assetPath, isRawFilePackRule);
|
||||
result.Add(assetPath, collectAssetInfo);
|
||||
}
|
||||
else
|
||||
@@ -207,22 +210,22 @@ namespace YooAsset.Editor
|
||||
return result.Values.ToList();
|
||||
}
|
||||
|
||||
private CollectAssetInfo CreateCollectAssetInfo(CollectCommand command, AssetBundleCollectorGroup group, string assetPath, bool isRawAsset)
|
||||
private CollectAssetInfo CreateCollectAssetInfo(CollectCommand command, AssetBundleCollectorGroup group, string assetPath, bool isRawFilePackRule)
|
||||
{
|
||||
string address = GetAddress(group, assetPath);
|
||||
string bundleName = GetBundleName(group, assetPath);
|
||||
string bundleName = GetBundleName(command, group, assetPath);
|
||||
List<string> assetTags = GetAssetTags(group);
|
||||
CollectAssetInfo collectAssetInfo = new CollectAssetInfo(CollectorType, bundleName, address, assetPath, assetTags, isRawAsset);
|
||||
CollectAssetInfo collectAssetInfo = new CollectAssetInfo(CollectorType, bundleName, address, assetPath, isRawFilePackRule, assetTags);
|
||||
|
||||
// 注意:模拟构建模式下不需要收集依赖资源
|
||||
if (command.BuildMode == EBuildMode.SimulateBuild)
|
||||
collectAssetInfo.DependAssets = new List<string>();
|
||||
else
|
||||
collectAssetInfo.DependAssets = GetAllDependencies(assetPath);
|
||||
collectAssetInfo.DependAssets = GetAllDependencies(assetPath, isRawFilePackRule);
|
||||
|
||||
return collectAssetInfo;
|
||||
}
|
||||
private bool IsValidateAsset(string assetPath)
|
||||
private bool IsValidateAsset(string assetPath, bool isRawFilePackRule)
|
||||
{
|
||||
if (assetPath.StartsWith("Assets/") == false && assetPath.StartsWith("Packages/") == false)
|
||||
{
|
||||
@@ -239,14 +242,37 @@ namespace YooAsset.Editor
|
||||
if (type == typeof(LightingDataAsset))
|
||||
return false;
|
||||
|
||||
// 忽略Unity无法识别的无效文件
|
||||
/*
|
||||
if (type == typeof(UnityEditor.DefaultAsset))
|
||||
// 检测原生文件是否合规
|
||||
if (isRawFilePackRule)
|
||||
{
|
||||
UnityEngine.Debug.LogWarning($"Cannot pack default asset : {assetPath}");
|
||||
return false;
|
||||
string extension = StringUtility.RemoveFirstChar(System.IO.Path.GetExtension(assetPath));
|
||||
if (extension == EAssetFileExtension.unity.ToString() || extension == EAssetFileExtension.prefab.ToString() ||
|
||||
extension == EAssetFileExtension.mat.ToString() || extension == EAssetFileExtension.controller.ToString() ||
|
||||
extension == EAssetFileExtension.fbx.ToString() || extension == EAssetFileExtension.anim.ToString() ||
|
||||
extension == EAssetFileExtension.shader.ToString())
|
||||
{
|
||||
UnityEngine.Debug.LogWarning($"Raw file pack rule can not support file estension : {extension}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 注意:原生文件只支持无依赖关系的资源
|
||||
string[] depends = AssetDatabase.GetDependencies(assetPath, true);
|
||||
if (depends.Length != 1)
|
||||
{
|
||||
UnityEngine.Debug.LogWarning($"Raw file pack rule can not support estension : {extension}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 忽略Unity无法识别的无效文件
|
||||
// 注意:只对非原生文件收集器处理
|
||||
if (type == typeof(UnityEditor.DefaultAsset))
|
||||
{
|
||||
UnityEngine.Debug.LogWarning($"Cannot pack default asset : {assetPath}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
string fileExtension = System.IO.Path.GetExtension(assetPath);
|
||||
if (IsIgnoreFile(fileExtension))
|
||||
@@ -256,7 +282,7 @@ namespace YooAsset.Editor
|
||||
}
|
||||
private bool IsIgnoreFile(string fileExtension)
|
||||
{
|
||||
foreach (var extension in YooAssetSettings.IgnoreFileExtensions)
|
||||
foreach (var extension in DefaultFilterRule.IgnoreFileExtensions)
|
||||
{
|
||||
if (extension == fileExtension)
|
||||
return true;
|
||||
@@ -282,31 +308,37 @@ namespace YooAsset.Editor
|
||||
string adressValue = addressRuleInstance.GetAssetAddress(new AddressRuleData(assetPath, CollectPath, group.GroupName));
|
||||
return adressValue;
|
||||
}
|
||||
private string GetBundleName(AssetBundleCollectorGroup group, string assetPath)
|
||||
private string GetBundleName(CollectCommand command, AssetBundleCollectorGroup group, string assetPath)
|
||||
{
|
||||
System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
|
||||
if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection))
|
||||
return EditorTools.GetRegularPath(YooAssetSettings.UnityShadersBundleName).ToLower();
|
||||
|
||||
// 根据规则设置获取资源包名称
|
||||
IPackRule packRuleInstance = AssetBundleCollectorSettingData.GetPackRuleInstance(PackRuleName);
|
||||
string bundleName = packRuleInstance.GetBundleName(new PackRuleData(assetPath, CollectPath, group.GroupName));
|
||||
return EditorTools.GetRegularPath(bundleName).ToLower();
|
||||
{
|
||||
// 获取着色器打包规则结果
|
||||
PackRuleResult packRuleResult = DefaultPackRule.CreateShadersPackRuleResult();
|
||||
return packRuleResult.GetMainBundleName(command.PackageName, command.UniqueBundleName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 获取其它资源打包规则结果
|
||||
IPackRule packRuleInstance = AssetBundleCollectorSettingData.GetPackRuleInstance(PackRuleName);
|
||||
PackRuleResult packRuleResult = packRuleInstance.GetPackRuleResult(new PackRuleData(assetPath, CollectPath, group.GroupName));
|
||||
return packRuleResult.GetMainBundleName(command.PackageName, command.UniqueBundleName);
|
||||
}
|
||||
}
|
||||
private List<string> GetAssetTags(AssetBundleCollectorGroup group)
|
||||
{
|
||||
List<string> tags = StringUtility.StringToStringList(group.AssetTags, ';');
|
||||
List<string> temper = StringUtility.StringToStringList(AssetTags, ';');
|
||||
List<string> tags = EditorTools.StringToStringList(group.AssetTags, ';');
|
||||
List<string> temper = EditorTools.StringToStringList(AssetTags, ';');
|
||||
tags.AddRange(temper);
|
||||
return tags;
|
||||
}
|
||||
private List<string> GetAllDependencies(string mainAssetPath)
|
||||
private List<string> GetAllDependencies(string mainAssetPath, bool isRawFilePackRule)
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
string[] depends = AssetDatabase.GetDependencies(mainAssetPath, true);
|
||||
foreach (string assetPath in depends)
|
||||
{
|
||||
if (IsValidateAsset(assetPath))
|
||||
if (IsValidateAsset(assetPath, isRawFilePackRule))
|
||||
{
|
||||
// 注意:排除主资源对象
|
||||
if (assetPath != mainAssetPath)
|
||||
|
||||
@@ -10,13 +10,14 @@ namespace YooAsset.Editor
|
||||
{
|
||||
public class AssetBundleCollectorConfig
|
||||
{
|
||||
public const string ConfigVersion = "2.1";
|
||||
public const string ConfigVersion = "2.2";
|
||||
|
||||
public const string XmlVersion = "Version";
|
||||
public const string XmlCommon = "Common";
|
||||
public const string XmlEnableAddressable = "AutoAddressable";
|
||||
public const string XmlUniqueBundleName = "UniqueBundleName";
|
||||
public const string XmlShowPackageView = "ShowPackageView";
|
||||
public const string XmlShowEditorAlias = "ShowEditorAlias";
|
||||
|
||||
public const string XmlPackage = "Package";
|
||||
public const string XmlPackageName = "PackageName";
|
||||
@@ -65,6 +66,7 @@ namespace YooAsset.Editor
|
||||
bool enableAddressable = false;
|
||||
bool uniqueBundleName = false;
|
||||
bool showPackageView = false;
|
||||
bool showEditorAlias = false;
|
||||
var commonNodeList = root.GetElementsByTagName(XmlCommon);
|
||||
if (commonNodeList.Count > 0)
|
||||
{
|
||||
@@ -75,10 +77,13 @@ namespace YooAsset.Editor
|
||||
throw new Exception($"Not found attribute {XmlUniqueBundleName} in {XmlCommon}");
|
||||
if (commonElement.HasAttribute(XmlShowPackageView) == false)
|
||||
throw new Exception($"Not found attribute {XmlShowPackageView} in {XmlCommon}");
|
||||
if (commonElement.HasAttribute(XmlShowEditorAlias) == false)
|
||||
throw new Exception($"Not found attribute {XmlShowEditorAlias} in {XmlCommon}");
|
||||
|
||||
enableAddressable = commonElement.GetAttribute(XmlEnableAddressable) == "True" ? true : false;
|
||||
uniqueBundleName = commonElement.GetAttribute(XmlUniqueBundleName) == "True" ? true : false;
|
||||
showPackageView = commonElement.GetAttribute(XmlShowPackageView) == "True" ? true : false;
|
||||
showEditorAlias = commonElement.GetAttribute(XmlShowEditorAlias) == "True" ? true : false;
|
||||
}
|
||||
|
||||
// 读取包裹配置
|
||||
@@ -138,7 +143,7 @@ namespace YooAsset.Editor
|
||||
AssetBundleCollector collector = new AssetBundleCollector();
|
||||
collector.CollectPath = collectorElement.GetAttribute(XmlCollectPath);
|
||||
collector.CollectorGUID = collectorElement.GetAttribute(XmlCollectorGUID);
|
||||
collector.CollectorType = StringUtility.NameToEnum<ECollectorType>(collectorElement.GetAttribute(XmlCollectorType));
|
||||
collector.CollectorType = EditorTools.NameToEnum<ECollectorType>(collectorElement.GetAttribute(XmlCollectorType));
|
||||
collector.AddressRuleName = collectorElement.GetAttribute(XmlAddressRule);
|
||||
collector.PackRuleName = collectorElement.GetAttribute(XmlPackRule);
|
||||
collector.FilterRuleName = collectorElement.GetAttribute(XmlFilterRule);
|
||||
@@ -153,6 +158,7 @@ namespace YooAsset.Editor
|
||||
AssetBundleCollectorSettingData.Setting.EnableAddressable = enableAddressable;
|
||||
AssetBundleCollectorSettingData.Setting.UniqueBundleName = uniqueBundleName;
|
||||
AssetBundleCollectorSettingData.Setting.ShowPackageView = showPackageView;
|
||||
AssetBundleCollectorSettingData.Setting.ShowEditorAlias = showEditorAlias;
|
||||
AssetBundleCollectorSettingData.Setting.Packages.AddRange(packages);
|
||||
AssetBundleCollectorSettingData.SaveFile();
|
||||
Debug.Log($"导入配置完毕!");
|
||||
@@ -183,6 +189,7 @@ namespace YooAsset.Editor
|
||||
commonElement.SetAttribute(XmlEnableAddressable, AssetBundleCollectorSettingData.Setting.EnableAddressable.ToString());
|
||||
commonElement.SetAttribute(XmlUniqueBundleName, AssetBundleCollectorSettingData.Setting.UniqueBundleName.ToString());
|
||||
commonElement.SetAttribute(XmlShowPackageView, AssetBundleCollectorSettingData.Setting.ShowPackageView.ToString());
|
||||
commonElement.SetAttribute(XmlShowEditorAlias, AssetBundleCollectorSettingData.Setting.ShowEditorAlias.ToString());
|
||||
root.AppendChild(commonElement);
|
||||
|
||||
// 设置Package配置
|
||||
@@ -296,6 +303,23 @@ namespace YooAsset.Editor
|
||||
return UpdateXmlConfig(xmlDoc);
|
||||
}
|
||||
|
||||
// 2.1 -> 2.2
|
||||
if (configVersion == "2.1")
|
||||
{
|
||||
// 添加公共元素属性
|
||||
var commonNodeList = root.GetElementsByTagName(XmlCommon);
|
||||
if (commonNodeList.Count > 0)
|
||||
{
|
||||
XmlElement commonElement = commonNodeList[0] as XmlElement;
|
||||
if (commonElement.HasAttribute(XmlShowEditorAlias) == false)
|
||||
commonElement.SetAttribute(XmlShowEditorAlias, "False");
|
||||
}
|
||||
|
||||
// 更新版本
|
||||
root.SetAttribute(XmlVersion, "2.2");
|
||||
return UpdateXmlConfig(xmlDoc);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace YooAsset.Editor
|
||||
HashSet<string> result = new HashSet<string>();
|
||||
foreach (var group in Groups)
|
||||
{
|
||||
List<string> groupTags = StringUtility.StringToStringList(group.AssetTags, ';');
|
||||
List<string> groupTags = EditorTools.StringToStringList(group.AssetTags, ';');
|
||||
foreach (var tag in groupTags)
|
||||
{
|
||||
if (result.Contains(tag) == false)
|
||||
@@ -111,7 +111,7 @@ namespace YooAsset.Editor
|
||||
|
||||
foreach (var collector in group.Collectors)
|
||||
{
|
||||
List<string> collectorTags = StringUtility.StringToStringList(collector.AssetTags, ';');
|
||||
List<string> collectorTags = EditorTools.StringToStringList(collector.AssetTags, ';');
|
||||
foreach (var tag in collectorTags)
|
||||
{
|
||||
if (result.Contains(tag) == false)
|
||||
|
||||
@@ -23,6 +23,12 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
public bool UniqueBundleName = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否显示编辑器别名
|
||||
/// </summary>
|
||||
public bool ShowEditorAlias = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 包裹列表
|
||||
/// </summary>
|
||||
@@ -94,8 +100,8 @@ namespace YooAsset.Editor
|
||||
{
|
||||
if (package.PackageName == packageName)
|
||||
{
|
||||
CollectCommand command = new CollectCommand(buildMode, EnableAddressable);
|
||||
CollectResult collectResult = new CollectResult(package.PackageName, EnableAddressable, UniqueBundleName);
|
||||
CollectCommand command = new CollectCommand(buildMode, package.PackageName, EnableAddressable, UniqueBundleName);
|
||||
CollectResult collectResult = new CollectResult(command);
|
||||
collectResult.SetCollectAssets(package.GetAllCollectAssets(command));
|
||||
return collectResult;
|
||||
}
|
||||
@@ -112,8 +118,8 @@ namespace YooAsset.Editor
|
||||
List<CollectResult> collectResultList = new List<CollectResult>(1000);
|
||||
foreach (var package in Packages)
|
||||
{
|
||||
CollectCommand command = new CollectCommand(buildMode, EnableAddressable);
|
||||
CollectResult collectResult = new CollectResult(package.PackageName, EnableAddressable, UniqueBundleName);
|
||||
CollectCommand command = new CollectCommand(buildMode, package.PackageName, EnableAddressable, UniqueBundleName);
|
||||
CollectResult collectResult = new CollectResult(command);
|
||||
collectResult.SetCollectAssets(package.GetAllCollectAssets(command));
|
||||
collectResultList.Add(collectResult);
|
||||
}
|
||||
|
||||
@@ -38,92 +38,6 @@ namespace YooAsset.Editor
|
||||
}
|
||||
}
|
||||
|
||||
public static List<string> GetActiveRuleNames()
|
||||
{
|
||||
if (_setting == null)
|
||||
LoadSettingData();
|
||||
|
||||
List<string> names = new List<string>();
|
||||
foreach (var pair in _cacheActiveRuleTypes)
|
||||
{
|
||||
names.Add(pair.Key);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
public static List<string> GetAddressRuleNames()
|
||||
{
|
||||
if (_setting == null)
|
||||
LoadSettingData();
|
||||
|
||||
List<string> names = new List<string>();
|
||||
foreach (var pair in _cacheAddressRuleTypes)
|
||||
{
|
||||
names.Add(pair.Key);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
public static List<string> GetPackRuleNames()
|
||||
{
|
||||
if (_setting == null)
|
||||
LoadSettingData();
|
||||
|
||||
List<string> names = new List<string>();
|
||||
foreach (var pair in _cachePackRuleTypes)
|
||||
{
|
||||
names.Add(pair.Key);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
public static List<string> GetFilterRuleNames()
|
||||
{
|
||||
if (_setting == null)
|
||||
LoadSettingData();
|
||||
|
||||
List<string> names = new List<string>();
|
||||
foreach (var pair in _cacheFilterRuleTypes)
|
||||
{
|
||||
names.Add(pair.Key);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
public static bool HasActiveRuleName(string ruleName)
|
||||
{
|
||||
foreach (var pair in _cacheActiveRuleTypes)
|
||||
{
|
||||
if (pair.Key == ruleName)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool HasAddressRuleName(string ruleName)
|
||||
{
|
||||
foreach (var pair in _cacheAddressRuleTypes)
|
||||
{
|
||||
if (pair.Key == ruleName)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool HasPackRuleName(string ruleName)
|
||||
{
|
||||
foreach (var pair in _cachePackRuleTypes)
|
||||
{
|
||||
if (pair.Key == ruleName)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool HasFilterRuleName(string ruleName)
|
||||
{
|
||||
foreach (var pair in _cacheFilterRuleTypes)
|
||||
{
|
||||
if (pair.Key == ruleName)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 加载配置文件
|
||||
/// </summary>
|
||||
@@ -146,6 +60,7 @@ namespace YooAsset.Editor
|
||||
typeof(PackCollector),
|
||||
typeof(PackGroup),
|
||||
typeof(PackRawFile),
|
||||
typeof(PackShaderVariants)
|
||||
};
|
||||
|
||||
var customTypes = EditorTools.GetAssignableTypes(typeof(IPackRule));
|
||||
@@ -266,7 +181,92 @@ namespace YooAsset.Editor
|
||||
SaveFile();
|
||||
}
|
||||
|
||||
// 实例类相关
|
||||
public static List<RuleDisplayName> GetActiveRuleNames()
|
||||
{
|
||||
if (_setting == null)
|
||||
LoadSettingData();
|
||||
|
||||
List<RuleDisplayName> names = new List<RuleDisplayName>();
|
||||
foreach (var pair in _cacheActiveRuleTypes)
|
||||
{
|
||||
RuleDisplayName ruleName = new RuleDisplayName();
|
||||
ruleName.ClassName = pair.Key;
|
||||
ruleName.DisplayName = GetRuleDisplayName(pair.Key, pair.Value);
|
||||
names.Add(ruleName);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
public static List<RuleDisplayName> GetAddressRuleNames()
|
||||
{
|
||||
if (_setting == null)
|
||||
LoadSettingData();
|
||||
|
||||
List<RuleDisplayName> names = new List<RuleDisplayName>();
|
||||
foreach (var pair in _cacheAddressRuleTypes)
|
||||
{
|
||||
RuleDisplayName ruleName = new RuleDisplayName();
|
||||
ruleName.ClassName = pair.Key;
|
||||
ruleName.DisplayName = GetRuleDisplayName(pair.Key, pair.Value);
|
||||
names.Add(ruleName);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
public static List<RuleDisplayName> GetPackRuleNames()
|
||||
{
|
||||
if (_setting == null)
|
||||
LoadSettingData();
|
||||
|
||||
List<RuleDisplayName> names = new List<RuleDisplayName>();
|
||||
foreach (var pair in _cachePackRuleTypes)
|
||||
{
|
||||
RuleDisplayName ruleName = new RuleDisplayName();
|
||||
ruleName.ClassName = pair.Key;
|
||||
ruleName.DisplayName = GetRuleDisplayName(pair.Key, pair.Value);
|
||||
names.Add(ruleName);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
public static List<RuleDisplayName> GetFilterRuleNames()
|
||||
{
|
||||
if (_setting == null)
|
||||
LoadSettingData();
|
||||
|
||||
List<RuleDisplayName> names = new List<RuleDisplayName>();
|
||||
foreach (var pair in _cacheFilterRuleTypes)
|
||||
{
|
||||
RuleDisplayName ruleName = new RuleDisplayName();
|
||||
ruleName.ClassName = pair.Key;
|
||||
ruleName.DisplayName = GetRuleDisplayName(pair.Key, pair.Value);
|
||||
names.Add(ruleName);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
private static string GetRuleDisplayName(string name, Type type)
|
||||
{
|
||||
var attribute = EditorAttribute.GetAttribute<DisplayNameAttribute>(type);
|
||||
if (attribute != null && string.IsNullOrEmpty(attribute.DisplayName) == false)
|
||||
return attribute.DisplayName;
|
||||
else
|
||||
return name;
|
||||
}
|
||||
|
||||
public static bool HasActiveRuleName(string ruleName)
|
||||
{
|
||||
return _cacheActiveRuleTypes.Keys.Contains(ruleName);
|
||||
}
|
||||
public static bool HasAddressRuleName(string ruleName)
|
||||
{
|
||||
return _cacheAddressRuleTypes.Keys.Contains(ruleName);
|
||||
}
|
||||
public static bool HasPackRuleName(string ruleName)
|
||||
{
|
||||
return _cachePackRuleTypes.Keys.Contains(ruleName);
|
||||
}
|
||||
public static bool HasFilterRuleName(string ruleName)
|
||||
{
|
||||
return _cacheFilterRuleTypes.Keys.Contains(ruleName);
|
||||
}
|
||||
|
||||
public static IActiveRule GetActiveRuleInstance(string ruleName)
|
||||
{
|
||||
if (_cacheActiveRuleInstance.TryGetValue(ruleName, out IActiveRule instance))
|
||||
@@ -352,6 +352,11 @@ namespace YooAsset.Editor
|
||||
Setting.UniqueBundleName = uniqueBundleName;
|
||||
IsDirty = true;
|
||||
}
|
||||
public static void ModifyShowEditorAlias(bool showAlias)
|
||||
{
|
||||
Setting.ShowEditorAlias = showAlias;
|
||||
IsDirty = true;
|
||||
}
|
||||
|
||||
// 资源包裹编辑相关
|
||||
public static AssetBundleCollectorPackage CreatePackage(string packageName)
|
||||
|
||||
@@ -20,14 +20,15 @@ namespace YooAsset.Editor
|
||||
|
||||
private Button _saveButton;
|
||||
private List<string> _collectorTypeList;
|
||||
private List<string> _activeRuleList;
|
||||
private List<string> _addressRuleList;
|
||||
private List<string> _packRuleList;
|
||||
private List<string> _filterRuleList;
|
||||
|
||||
private List<RuleDisplayName> _activeRuleList;
|
||||
private List<RuleDisplayName> _addressRuleList;
|
||||
private List<RuleDisplayName> _packRuleList;
|
||||
private List<RuleDisplayName> _filterRuleList;
|
||||
|
||||
private Toggle _showPackageToogle;
|
||||
private Toggle _enableAddressableToogle;
|
||||
private Toggle _uniqueBundleNameToogle;
|
||||
private Toggle _showEditorAliasToggle;
|
||||
|
||||
private VisualElement _packageContainer;
|
||||
private ListView _packageListView;
|
||||
@@ -42,7 +43,7 @@ namespace YooAsset.Editor
|
||||
|
||||
private VisualElement _collectorContainer;
|
||||
private ScrollView _collectorScrollView;
|
||||
private PopupField<string> _activeRulePopupField;
|
||||
private PopupField<RuleDisplayName> _activeRulePopupField;
|
||||
|
||||
private int _lastModifyPackageIndex = 0;
|
||||
private int _lastModifyGroupIndex = 0;
|
||||
@@ -95,6 +96,13 @@ namespace YooAsset.Editor
|
||||
RefreshWindow();
|
||||
});
|
||||
|
||||
_showEditorAliasToggle = root.Q<Toggle>("ShowEditorAlias");
|
||||
_showEditorAliasToggle.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
AssetBundleCollectorSettingData.ModifyShowEditorAlias(evt.newValue);
|
||||
RefreshWindow();
|
||||
});
|
||||
|
||||
// 配置修复按钮
|
||||
var fixBtn = root.Q<Button>("FixButton");
|
||||
fixBtn.clicked += FixBtn_clicked;
|
||||
@@ -236,21 +244,23 @@ namespace YooAsset.Editor
|
||||
// 分组激活规则
|
||||
var activeRuleContainer = root.Q("ActiveRuleContainer");
|
||||
{
|
||||
_activeRulePopupField = new PopupField<string>("Active Rule", _activeRuleList, 0);
|
||||
_activeRulePopupField = new PopupField<RuleDisplayName>("Active Rule", _activeRuleList, 0);
|
||||
_activeRulePopupField.name = "ActiveRuleMaskField";
|
||||
_activeRulePopupField.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
activeRuleContainer.Add(_activeRulePopupField);
|
||||
_activeRulePopupField.formatListItemCallback = FormatListItemCallback;
|
||||
_activeRulePopupField.formatSelectedValueCallback = FormatSelectedValueCallback;
|
||||
_activeRulePopupField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
|
||||
var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
|
||||
if (selectPackage != null && selectGroup != null)
|
||||
{
|
||||
selectGroup.ActiveRuleName = evt.newValue;
|
||||
selectGroup.ActiveRuleName = evt.newValue.ClassName;
|
||||
AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup);
|
||||
FillGroupViewData();
|
||||
}
|
||||
});
|
||||
activeRuleContainer.Add(_activeRulePopupField);
|
||||
}
|
||||
|
||||
// 刷新窗体
|
||||
@@ -290,6 +300,9 @@ namespace YooAsset.Editor
|
||||
{
|
||||
_showPackageToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowPackageView);
|
||||
_enableAddressableToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.EnableAddressable);
|
||||
_uniqueBundleNameToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.UniqueBundleName);
|
||||
_showEditorAliasToggle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowEditorAlias);
|
||||
|
||||
_groupContainer.visible = false;
|
||||
_collectorContainer.visible = false;
|
||||
|
||||
@@ -321,6 +334,20 @@ namespace YooAsset.Editor
|
||||
{
|
||||
AssetBundleCollectorSettingData.SaveFile();
|
||||
}
|
||||
private string FormatListItemCallback(RuleDisplayName ruleDisplayName)
|
||||
{
|
||||
if (_showEditorAliasToggle.value)
|
||||
return ruleDisplayName.DisplayName;
|
||||
else
|
||||
return ruleDisplayName.ClassName;
|
||||
}
|
||||
private string FormatSelectedValueCallback(RuleDisplayName ruleDisplayName)
|
||||
{
|
||||
if (_showEditorAliasToggle.value)
|
||||
return ruleDisplayName.DisplayName;
|
||||
else
|
||||
return ruleDisplayName.ClassName;
|
||||
}
|
||||
|
||||
// 包裹列表相关
|
||||
private void FillPackageViewData()
|
||||
@@ -334,7 +361,7 @@ namespace YooAsset.Editor
|
||||
{
|
||||
_packageListView.selectedIndex = _lastModifyPackageIndex;
|
||||
}
|
||||
|
||||
|
||||
if (_showPackageToogle.value)
|
||||
_packageContainer.style.display = DisplayStyle.Flex;
|
||||
else
|
||||
@@ -410,7 +437,7 @@ namespace YooAsset.Editor
|
||||
_groupListView.itemsSource = selectPackage.Groups;
|
||||
_groupListView.Rebuild();
|
||||
|
||||
if(_lastModifyGroupIndex >=0 && _lastModifyGroupIndex < _groupListView.itemsSource.Count)
|
||||
if (_lastModifyGroupIndex >= 0 && _lastModifyGroupIndex < _groupListView.itemsSource.Count)
|
||||
{
|
||||
_groupListView.selectedIndex = _lastModifyGroupIndex;
|
||||
}
|
||||
@@ -460,7 +487,7 @@ namespace YooAsset.Editor
|
||||
|
||||
_collectorContainer.visible = true;
|
||||
_lastModifyGroupIndex = _groupListView.selectedIndex;
|
||||
_activeRulePopupField.SetValueWithoutNotify(selectGroup.ActiveRuleName);
|
||||
_activeRulePopupField.SetValueWithoutNotify(GetActiveRuleIndex(selectGroup.ActiveRuleName));
|
||||
_groupNameTxt.SetValueWithoutNotify(selectGroup.GroupName);
|
||||
_groupDescTxt.SetValueWithoutNotify(selectGroup.GroupDesc);
|
||||
_groupAssetTagsTxt.SetValueWithoutNotify(selectGroup.AssetTags);
|
||||
@@ -564,21 +591,21 @@ namespace YooAsset.Editor
|
||||
}
|
||||
if (_enableAddressableToogle.value)
|
||||
{
|
||||
var popupField = new PopupField<string>(_addressRuleList, 0);
|
||||
var popupField = new PopupField<RuleDisplayName>(_addressRuleList, 0);
|
||||
popupField.name = "PopupField1";
|
||||
popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
popupField.style.width = 200;
|
||||
elementBottom.Add(popupField);
|
||||
}
|
||||
{
|
||||
var popupField = new PopupField<string>(_packRuleList, 0);
|
||||
var popupField = new PopupField<RuleDisplayName>(_packRuleList, 0);
|
||||
popupField.name = "PopupField2";
|
||||
popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
popupField.style.width = 150;
|
||||
popupField.style.width = 230;
|
||||
elementBottom.Add(popupField);
|
||||
}
|
||||
{
|
||||
var popupField = new PopupField<string>(_filterRuleList, 0);
|
||||
var popupField = new PopupField<RuleDisplayName>(_filterRuleList, 0);
|
||||
popupField.name = "PopupField3";
|
||||
popupField.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
popupField.style.width = 150;
|
||||
@@ -667,7 +694,7 @@ namespace YooAsset.Editor
|
||||
popupField0.index = GetCollectorTypeIndex(collector.CollectorType.ToString());
|
||||
popupField0.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
collector.CollectorType = StringUtility.NameToEnum<ECollectorType>(evt.newValue);
|
||||
collector.CollectorType = EditorTools.NameToEnum<ECollectorType>(evt.newValue);
|
||||
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
|
||||
if (foldout.value)
|
||||
{
|
||||
@@ -676,13 +703,15 @@ namespace YooAsset.Editor
|
||||
});
|
||||
|
||||
// Address Rule
|
||||
var popupField1 = element.Q<PopupField<string>>("PopupField1");
|
||||
var popupField1 = element.Q<PopupField<RuleDisplayName>>("PopupField1");
|
||||
if (popupField1 != null)
|
||||
{
|
||||
popupField1.index = GetAddressRuleIndex(collector.AddressRuleName);
|
||||
popupField1.formatListItemCallback = FormatListItemCallback;
|
||||
popupField1.formatSelectedValueCallback = FormatSelectedValueCallback;
|
||||
popupField1.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
collector.AddressRuleName = evt.newValue;
|
||||
collector.AddressRuleName = evt.newValue.ClassName;
|
||||
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
|
||||
if (foldout.value)
|
||||
{
|
||||
@@ -692,11 +721,13 @@ namespace YooAsset.Editor
|
||||
}
|
||||
|
||||
// Pack Rule
|
||||
var popupField2 = element.Q<PopupField<string>>("PopupField2");
|
||||
var popupField2 = element.Q<PopupField<RuleDisplayName>>("PopupField2");
|
||||
popupField2.index = GetPackRuleIndex(collector.PackRuleName);
|
||||
popupField2.formatListItemCallback = FormatListItemCallback;
|
||||
popupField2.formatSelectedValueCallback = FormatSelectedValueCallback;
|
||||
popupField2.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
collector.PackRuleName = evt.newValue;
|
||||
collector.PackRuleName = evt.newValue.ClassName;
|
||||
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
|
||||
if (foldout.value)
|
||||
{
|
||||
@@ -705,11 +736,13 @@ namespace YooAsset.Editor
|
||||
});
|
||||
|
||||
// Filter Rule
|
||||
var popupField3 = element.Q<PopupField<string>>("PopupField3");
|
||||
var popupField3 = element.Q<PopupField<RuleDisplayName>>("PopupField3");
|
||||
popupField3.index = GetFilterRuleIndex(collector.FilterRuleName);
|
||||
popupField3.formatListItemCallback = FormatListItemCallback;
|
||||
popupField3.formatSelectedValueCallback = FormatSelectedValueCallback;
|
||||
popupField3.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
collector.FilterRuleName = evt.newValue;
|
||||
collector.FilterRuleName = evt.newValue.ClassName;
|
||||
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
|
||||
if (foldout.value)
|
||||
{
|
||||
@@ -743,7 +776,7 @@ namespace YooAsset.Editor
|
||||
|
||||
try
|
||||
{
|
||||
CollectCommand command = new CollectCommand(EBuildMode.DryRunBuild, _enableAddressableToogle.value);
|
||||
CollectCommand command = new CollectCommand(EBuildMode.DryRunBuild, _packageNameTxt.value, _enableAddressableToogle.value, _uniqueBundleNameToogle.value);
|
||||
collectAssetInfos = collector.GetAllCollectAssets(command, group);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
@@ -815,7 +848,7 @@ namespace YooAsset.Editor
|
||||
{
|
||||
for (int i = 0; i < _addressRuleList.Count; i++)
|
||||
{
|
||||
if (_addressRuleList[i] == ruleName)
|
||||
if (_addressRuleList[i].ClassName == ruleName)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
@@ -824,7 +857,7 @@ namespace YooAsset.Editor
|
||||
{
|
||||
for (int i = 0; i < _packRuleList.Count; i++)
|
||||
{
|
||||
if (_packRuleList[i] == ruleName)
|
||||
if (_packRuleList[i].ClassName == ruleName)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
@@ -833,11 +866,20 @@ namespace YooAsset.Editor
|
||||
{
|
||||
for (int i = 0; i < _filterRuleList.Count; i++)
|
||||
{
|
||||
if (_filterRuleList[i] == ruleName)
|
||||
if (_filterRuleList[i].ClassName == ruleName)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
private RuleDisplayName GetActiveRuleIndex(string ruleName)
|
||||
{
|
||||
for (int i = 0; i < _activeRuleList.Count; i++)
|
||||
{
|
||||
if (_activeRuleList[i].ClassName == ruleName)
|
||||
return _activeRuleList[i];
|
||||
}
|
||||
return _activeRuleList[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
<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:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
|
||||
<uie:Toolbar name="Toolbar" style="display: flex; flex-direction: row-reverse;">
|
||||
<ui:Button text="Save" display-tooltip-when-elided="true" name="SaveButton" style="width: 50px; background-color: rgb(56, 147, 58);" />
|
||||
<ui:Button text="导出" display-tooltip-when-elided="true" name="ExportButton" style="width: 50px; background-color: rgb(56, 147, 58);" />
|
||||
@@ -7,6 +7,7 @@
|
||||
</uie:Toolbar>
|
||||
<ui:VisualElement name="PublicContainer" style="height: 30px; background-color: rgb(67, 67, 67); flex-direction: row; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
|
||||
<ui:Toggle label="Show Packages" name="ShowPackages" style="width: 196px; -unity-text-align: middle-left;" />
|
||||
<ui:Toggle label="Show Editor Alias" name="ShowEditorAlias" style="width: 196px; -unity-text-align: middle-left;" />
|
||||
<ui:Toggle label="Enable Addressable" name="EnableAddressable" style="width: 196px; -unity-text-align: middle-left;" />
|
||||
<ui:Toggle label="Unique Bundle Name" name="UniqueBundleName" style="width: 196px; -unity-text-align: middle-left;" />
|
||||
</ui:VisualElement>
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace YooAsset.Editor
|
||||
/// 资源包名称
|
||||
/// </summary>
|
||||
public string BundleName { private set; get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 可寻址地址
|
||||
/// </summary>
|
||||
@@ -25,38 +25,30 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
public string AssetPath { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 资源分类标签
|
||||
/// </summary>
|
||||
public List<string> AssetTags { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否为原生资源
|
||||
/// </summary>
|
||||
public bool IsRawAsset { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 资源分类标签
|
||||
/// </summary>
|
||||
public List<string> AssetTags { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 依赖的资源列表
|
||||
/// </summary>
|
||||
public List<string> DependAssets = new List<string>();
|
||||
|
||||
|
||||
public CollectAssetInfo(ECollectorType collectorType, string bundleName, string address, string assetPath, List<string> assetTags, bool isRawAsset)
|
||||
public CollectAssetInfo(ECollectorType collectorType, string bundleName, string address, string assetPath, bool isRawAsset, List<string> assetTags)
|
||||
{
|
||||
CollectorType = collectorType;
|
||||
BundleName = bundleName;
|
||||
Address = address;
|
||||
AssetPath = assetPath;
|
||||
AssetTags = assetTags;
|
||||
IsRawAsset = isRawAsset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资源包名称追加包裹名
|
||||
/// </summary>
|
||||
public void BundleNameAppendPackageName(string packageName)
|
||||
{
|
||||
BundleName = $"{packageName.ToLower()}_{BundleName}";
|
||||
AssetTags = assetTags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,15 +8,27 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
public EBuildMode BuildMode { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 包裹名称
|
||||
/// </summary>
|
||||
public string PackageName { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用可寻址资源定位
|
||||
/// </summary>
|
||||
public bool EnableAddressable { private set; get; }
|
||||
|
||||
public CollectCommand(EBuildMode buildMode, bool enableAddressable)
|
||||
/// <summary>
|
||||
/// 资源包名唯一化
|
||||
/// </summary>
|
||||
public bool UniqueBundleName { private set; get; }
|
||||
|
||||
public CollectCommand(EBuildMode buildMode, string packageName, bool enableAddressable, bool uniqueBundleName)
|
||||
{
|
||||
BuildMode = buildMode;
|
||||
PackageName = packageName;
|
||||
EnableAddressable = enableAddressable;
|
||||
UniqueBundleName = uniqueBundleName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,19 +6,14 @@ namespace YooAsset.Editor
|
||||
public class CollectResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 包裹名称
|
||||
/// 收集命令
|
||||
/// </summary>
|
||||
public string PackageName { private set; get; }
|
||||
public CollectCommand Command { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用可寻址资源定位
|
||||
/// 着色器统一全名称
|
||||
/// </summary>
|
||||
public bool EnableAddressable { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 资源包名唯一化
|
||||
/// </summary>
|
||||
public bool UniqueBundleName { private set; get; }
|
||||
public string ShadersBundleName { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 收集的资源信息列表
|
||||
@@ -26,24 +21,18 @@ namespace YooAsset.Editor
|
||||
public List<CollectAssetInfo> CollectAssets { private set; get; }
|
||||
|
||||
|
||||
public CollectResult(string packageName, bool enableAddressable, bool uniqueBundleName)
|
||||
public CollectResult(CollectCommand command)
|
||||
{
|
||||
PackageName = packageName;
|
||||
EnableAddressable = enableAddressable;
|
||||
UniqueBundleName = uniqueBundleName;
|
||||
Command = command;
|
||||
|
||||
// 着色器统一全名称
|
||||
var packRuleResult = DefaultPackRule.CreateShadersPackRuleResult();
|
||||
ShadersBundleName = packRuleResult.GetMainBundleName(command.PackageName, command.UniqueBundleName);
|
||||
}
|
||||
|
||||
public void SetCollectAssets(List<CollectAssetInfo> collectAssets)
|
||||
{
|
||||
CollectAssets = collectAssets;
|
||||
|
||||
if (UniqueBundleName)
|
||||
{
|
||||
foreach (var collectAsset in CollectAssets)
|
||||
{
|
||||
collectAsset.BundleNameAppendPackageName(PackageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 启用分组
|
||||
/// </summary>
|
||||
[DisplayName("启用分组")]
|
||||
public class EnableGroup : IActiveRule
|
||||
{
|
||||
public bool IsActiveGroup()
|
||||
@@ -12,9 +10,7 @@ namespace YooAsset.Editor
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 禁用分组
|
||||
/// </summary>
|
||||
[DisplayName("禁用分组")]
|
||||
public class DisableGroup : IActiveRule
|
||||
{
|
||||
public bool IsActiveGroup()
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 以文件名为定位地址
|
||||
/// </summary>
|
||||
[DisplayName("以文件名称为定位地址")]
|
||||
public class AddressByFileName : IAddressRule
|
||||
{
|
||||
string IAddressRule.GetAssetAddress(AddressRuleData data)
|
||||
@@ -13,9 +11,7 @@ namespace YooAsset.Editor
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以组名+文件名为定位地址
|
||||
/// </summary>
|
||||
[DisplayName("以分组名称+文件名称为定位地址")]
|
||||
public class AddressByGroupAndFileName : IAddressRule
|
||||
{
|
||||
string IAddressRule.GetAssetAddress(AddressRuleData data)
|
||||
@@ -25,9 +21,7 @@ namespace YooAsset.Editor
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以收集器名+文件名为定位地址
|
||||
/// </summary>
|
||||
[DisplayName("以收集器名称+文件名称为定位地址")]
|
||||
public class AddressByCollectorAndFileName : IAddressRule
|
||||
{
|
||||
string IAddressRule.GetAssetAddress(AddressRuleData data)
|
||||
|
||||
@@ -4,9 +4,15 @@ using System.IO;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 收集所有资源
|
||||
/// </summary>
|
||||
public class DefaultFilterRule
|
||||
{
|
||||
/// <summary>
|
||||
/// 忽略的文件类型
|
||||
/// </summary>
|
||||
public static readonly string[] IgnoreFileExtensions = { "", ".so", ".dll", ".cs", ".js", ".boo", ".meta", ".cginc", ".hlsl" };
|
||||
}
|
||||
|
||||
[DisplayName("收集所有资源")]
|
||||
public class CollectAll : IFilterRule
|
||||
{
|
||||
public bool IsCollectAsset(FilterRuleData data)
|
||||
@@ -15,9 +21,7 @@ namespace YooAsset.Editor
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 只收集场景
|
||||
/// </summary>
|
||||
[DisplayName("收集场景")]
|
||||
public class CollectScene : IFilterRule
|
||||
{
|
||||
public bool IsCollectAsset(FilterRuleData data)
|
||||
@@ -25,10 +29,8 @@ namespace YooAsset.Editor
|
||||
return Path.GetExtension(data.AssetPath) == ".unity";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 只收集预制体
|
||||
/// </summary>
|
||||
|
||||
[DisplayName("收集预制体")]
|
||||
public class CollectPrefab : IFilterRule
|
||||
{
|
||||
public bool IsCollectAsset(FilterRuleData data)
|
||||
@@ -37,15 +39,13 @@ namespace YooAsset.Editor
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 只收集精灵类型的资源
|
||||
/// </summary>
|
||||
[DisplayName("收集精灵类型的纹理")]
|
||||
public class CollectSprite : IFilterRule
|
||||
{
|
||||
public bool IsCollectAsset(FilterRuleData data)
|
||||
{
|
||||
var mainAssetType = AssetDatabase.GetMainAssetTypeAtPath(data.AssetPath);
|
||||
if(mainAssetType == typeof(Texture2D))
|
||||
if (mainAssetType == typeof(Texture2D))
|
||||
{
|
||||
var texImporter = AssetImporter.GetAtPath(data.AssetPath) as TextureImporter;
|
||||
if (texImporter != null && texImporter.textureType == TextureImporterType.Sprite)
|
||||
@@ -60,9 +60,7 @@ namespace YooAsset.Editor
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 只收集着色器变种收集文件
|
||||
/// </summary>
|
||||
[DisplayName("收集着色器变种集合")]
|
||||
public class CollectShaderVariants : IFilterRule
|
||||
{
|
||||
public bool IsCollectAsset(FilterRuleData data)
|
||||
|
||||
@@ -4,37 +4,74 @@ using UnityEditor;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class DefaultPackRule
|
||||
{
|
||||
/// <summary>
|
||||
/// AssetBundle文件的后缀名
|
||||
/// </summary>
|
||||
public const string AssetBundleFileExtension = "bundle";
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件的后缀名
|
||||
/// </summary>
|
||||
public const string RawFileExtension = "rawfile";
|
||||
|
||||
/// <summary>
|
||||
/// Unity着色器资源包名称
|
||||
/// </summary>
|
||||
public const string ShadersBundleName = "unityshaders";
|
||||
|
||||
|
||||
public static PackRuleResult CreateShadersPackRuleResult()
|
||||
{
|
||||
PackRuleResult result = new PackRuleResult(ShadersBundleName, AssetBundleFileExtension);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以文件路径作为资源包名
|
||||
/// 注意:每个文件独自打资源包
|
||||
/// 例如:收集器路径为 "Assets/UIPanel"
|
||||
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets/uipanel/shop/image/backgroud.bundle"
|
||||
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets/uipanel/shop/view/main.bundle"
|
||||
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop_image_backgroud.bundle"
|
||||
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop_view_main.bundle"
|
||||
/// </summary>
|
||||
[DisplayName("以文件路径作为资源包名")]
|
||||
public class PackSeparately : IPackRule
|
||||
{
|
||||
string IPackRule.GetBundleName(PackRuleData data)
|
||||
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
|
||||
{
|
||||
string bundleName = StringUtility.RemoveExtension(data.AssetPath);
|
||||
return EditorTools.GetRegularPath(bundleName).Replace('/', '_');
|
||||
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IPackRule.IsRawFilePackRule()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以父类文件夹路径作为资源包名
|
||||
/// 注意:文件夹下所有文件打进一个资源包
|
||||
/// 例如:收集器路径为 "Assets/UIPanel"
|
||||
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets/uipanel/shop/image.bundle"
|
||||
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets/uipanel/shop/view.bundle"
|
||||
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop_image.bundle"
|
||||
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop_view.bundle"
|
||||
/// </summary>
|
||||
[DisplayName("以父类文件夹路径作为资源包名")]
|
||||
public class PackDirectory : IPackRule
|
||||
{
|
||||
public static PackDirectory StaticPackRule = new PackDirectory();
|
||||
|
||||
string IPackRule.GetBundleName(PackRuleData data)
|
||||
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
|
||||
{
|
||||
string bundleName = Path.GetDirectoryName(data.AssetPath);
|
||||
return EditorTools.GetRegularPath(bundleName).Replace('/', '_');
|
||||
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IPackRule.IsRawFilePackRule()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,12 +79,13 @@ namespace YooAsset.Editor
|
||||
/// 以收集器路径下顶级文件夹为资源包名
|
||||
/// 注意:文件夹下所有文件打进一个资源包
|
||||
/// 例如:收集器路径为 "Assets/UIPanel"
|
||||
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets/uipanel/shop.bundle"
|
||||
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets/uipanel/shop.bundle"
|
||||
/// 例如:"Assets/UIPanel/Shop/Image/backgroud.png" --> "assets_uipanel_shop.bundle"
|
||||
/// 例如:"Assets/UIPanel/Shop/View/main.prefab" --> "assets_uipanel_shop.bundle"
|
||||
/// </summary>
|
||||
[DisplayName("以收集器路径下顶级文件夹为资源包名")]
|
||||
public class PackTopDirectory : IPackRule
|
||||
{
|
||||
string IPackRule.GetBundleName(PackRuleData data)
|
||||
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
|
||||
{
|
||||
string assetPath = data.AssetPath.Replace(data.CollectPath, string.Empty);
|
||||
assetPath = assetPath.TrimStart('/');
|
||||
@@ -57,25 +95,48 @@ namespace YooAsset.Editor
|
||||
if (Path.HasExtension(splits[0]))
|
||||
throw new Exception($"Not found root directory : {assetPath}");
|
||||
string bundleName = $"{data.CollectPath}/{splits[0]}";
|
||||
return EditorTools.GetRegularPath(bundleName).Replace('/', '_');
|
||||
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Not found root directory : {assetPath}");
|
||||
}
|
||||
}
|
||||
|
||||
bool IPackRule.IsRawFilePackRule()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以收集器路径作为资源包名
|
||||
/// 注意:收集的所有文件打进一个资源包
|
||||
/// </summary>
|
||||
[DisplayName("以收集器路径作为资源包名")]
|
||||
public class PackCollector : IPackRule
|
||||
{
|
||||
string IPackRule.GetBundleName(PackRuleData data)
|
||||
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
|
||||
{
|
||||
string bundleName = StringUtility.RemoveExtension(data.CollectPath);
|
||||
return EditorTools.GetRegularPath(bundleName).Replace('/', '_');
|
||||
string bundleName;
|
||||
string collectPath = data.CollectPath;
|
||||
if (AssetDatabase.IsValidFolder(collectPath))
|
||||
{
|
||||
bundleName = collectPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
bundleName = StringUtility.RemoveExtension(collectPath);
|
||||
}
|
||||
|
||||
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IPackRule.IsRawFilePackRule()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,49 +144,56 @@ namespace YooAsset.Editor
|
||||
/// 以分组名称作为资源包名
|
||||
/// 注意:收集的所有文件打进一个资源包
|
||||
/// </summary>
|
||||
[DisplayName("以分组名称作为资源包名")]
|
||||
public class PackGroup : IPackRule
|
||||
{
|
||||
string IPackRule.GetBundleName(PackRuleData data)
|
||||
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
|
||||
{
|
||||
return data.GroupName;
|
||||
string bundleName = data.GroupName;
|
||||
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IPackRule.IsRawFilePackRule()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件打包模式
|
||||
/// 打包原生文件
|
||||
/// 注意:原生文件打包支持:图片,音频,视频,文本
|
||||
/// </summary>
|
||||
[DisplayName("打包原生文件")]
|
||||
public class PackRawFile : IPackRule
|
||||
{
|
||||
string IPackRule.GetBundleName(PackRuleData data)
|
||||
PackRuleResult IPackRule.GetPackRuleResult(PackRuleData data)
|
||||
{
|
||||
string extension = StringUtility.RemoveFirstChar(Path.GetExtension(data.AssetPath));
|
||||
if (extension == EAssetFileExtension.unity.ToString() || extension == EAssetFileExtension.prefab.ToString() ||
|
||||
extension == EAssetFileExtension.mat.ToString() || extension == EAssetFileExtension.controller.ToString() ||
|
||||
extension == EAssetFileExtension.fbx.ToString() || extension == EAssetFileExtension.anim.ToString() ||
|
||||
extension == EAssetFileExtension.shader.ToString())
|
||||
{
|
||||
throw new Exception($"{nameof(PackRawFile)} is not support file estension : {extension}");
|
||||
}
|
||||
string bundleName = data.AssetPath;
|
||||
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.RawFileExtension);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 注意:原生文件只支持无依赖关系的资源
|
||||
string[] depends = AssetDatabase.GetDependencies(data.AssetPath, true);
|
||||
if (depends.Length != 1)
|
||||
throw new Exception($"{nameof(PackRawFile)} is not support estension : {extension}");
|
||||
|
||||
string bundleName = StringUtility.RemoveExtension(data.AssetPath);
|
||||
return EditorTools.GetRegularPath(bundleName).Replace('/', '_');
|
||||
bool IPackRule.IsRawFilePackRule()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 着色器变种收集文件
|
||||
/// 打包着色器变种集合
|
||||
/// </summary>
|
||||
[DisplayName("打包着色器变种集合")]
|
||||
public class PackShaderVariants : IPackRule
|
||||
{
|
||||
public string GetBundleName(PackRuleData data)
|
||||
public PackRuleResult GetPackRuleResult(PackRuleData data)
|
||||
{
|
||||
return YooAssetSettings.UnityShadersBundleName;
|
||||
return DefaultPackRule.CreateShadersPackRuleResult();
|
||||
}
|
||||
|
||||
bool IPackRule.IsRawFilePackRule()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ namespace YooAsset.Editor
|
||||
{
|
||||
public struct PackRuleData
|
||||
{
|
||||
public string AssetPath;
|
||||
public string AssetPath;
|
||||
public string CollectPath;
|
||||
public string GroupName;
|
||||
|
||||
@@ -21,14 +21,59 @@ namespace YooAsset.Editor
|
||||
}
|
||||
}
|
||||
|
||||
public struct PackRuleResult
|
||||
{
|
||||
private readonly string _bundleName;
|
||||
private readonly string _bundleExtension;
|
||||
|
||||
public PackRuleResult(string bundleName, string bundleExtension)
|
||||
{
|
||||
_bundleName = bundleName;
|
||||
_bundleExtension = bundleExtension;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取主资源包全名称
|
||||
/// </summary>
|
||||
public string GetMainBundleName(string packageName, bool uniqueBundleName)
|
||||
{
|
||||
string fullName;
|
||||
string bundleName = EditorTools.GetRegularPath(_bundleName).Replace('/', '_').Replace('.', '_').ToLower();
|
||||
if (uniqueBundleName)
|
||||
fullName = $"{packageName}_{bundleName}.{_bundleExtension}";
|
||||
else
|
||||
fullName = $"{bundleName}.{_bundleExtension}";
|
||||
return fullName.ToLower();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取共享资源包全名称
|
||||
/// </summary>
|
||||
public string GetShareBundleName(string packageName, bool uniqueBundleName)
|
||||
{
|
||||
string fullName;
|
||||
string bundleName = EditorTools.GetRegularPath(_bundleName).Replace('/', '_').Replace('.', '_').ToLower();
|
||||
if (uniqueBundleName)
|
||||
fullName = $"{packageName}_share_{bundleName}.{_bundleExtension}";
|
||||
else
|
||||
fullName = $"share_{bundleName}.{_bundleExtension}";
|
||||
return fullName.ToLower();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资源打包规则接口
|
||||
/// </summary>
|
||||
public interface IPackRule
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取资源打包所属的资源包名称
|
||||
/// 获取打包规则结果
|
||||
/// </summary>
|
||||
string GetBundleName(PackRuleData data);
|
||||
PackRuleResult GetPackRuleResult(PackRuleData data);
|
||||
|
||||
/// <summary>
|
||||
/// 是否为原生文件打包规则
|
||||
/// </summary>
|
||||
bool IsRawFilePackRule();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
public class RuleDisplayName
|
||||
{
|
||||
public string ClassName;
|
||||
public string DisplayName;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 223f217ed81460541b5ea7eb7a7d82a4
|
||||
guid: df712711c3830af419b7ada8fee53dda
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -220,7 +220,7 @@ namespace YooAsset.Editor
|
||||
|
||||
// Status
|
||||
StyleColor textColor;
|
||||
if (providerInfo.Status == (int)ProviderBase.EStatus.Fail)
|
||||
if (providerInfo.Status == ProviderBase.EStatus.Failed.ToString())
|
||||
textColor = new StyleColor(Color.yellow);
|
||||
else
|
||||
textColor = label1.style.color;
|
||||
|
||||
@@ -185,7 +185,7 @@ namespace YooAsset.Editor
|
||||
|
||||
// Status
|
||||
StyleColor textColor;
|
||||
if (bundleInfo.Status == (int)AssetBundleLoaderBase.EStatus.Failed)
|
||||
if (bundleInfo.Status == BundleLoaderBase.EStatus.Failed.ToString())
|
||||
textColor = new StyleColor(Color.yellow);
|
||||
else
|
||||
textColor = label1.style.color;
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace YooAsset.Editor
|
||||
return;
|
||||
|
||||
_reportFilePath = selectFilePath;
|
||||
string jsonData = FileUtility.ReadFile(_reportFilePath);
|
||||
string jsonData = FileUtility.ReadAllText(_reportFilePath);
|
||||
_buildReport = BuildReport.Deserialize(jsonData);
|
||||
_assetListViewer.FillViewData(_buildReport, _searchKeyWord);
|
||||
_bundleListViewer.FillViewData(_buildReport, _reportFilePath, _searchKeyWord);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
|
||||
<ui:VisualElement name="TopGroup" style="flex-grow: 1; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 2px; margin-bottom: 1px; display: flex;">
|
||||
<uie:Toolbar name="TopBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
||||
<uie:ToolbarButton text="Asset Path" display-tooltip-when-elided="true" name="TopBar1" style="width: 280px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||
<uie:ToolbarButton text="Main Bundle" display-tooltip-when-elided="true" name="TopBar2" style="width: 145px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||
</uie:Toolbar>
|
||||
<ui:ListView focusable="true" name="TopListView" item-height="18" virtualization-method="DynamicHeight" style="flex-grow: 1;" />
|
||||
<ui:ListView focusable="true" name="TopListView" item-height="18" virtualization-method="DynamicHeight" style="flex-grow: 1; flex-basis: 60px;" />
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement name="BottomGroup" style="height: 200px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex;">
|
||||
<uie:Toolbar name="BottomBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
|
||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
|
||||
<ui:VisualElement name="Viewer" style="flex-grow: 1; display: flex;">
|
||||
<ui:VisualElement name="TopGroup" style="flex-grow: 1; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 2px; margin-bottom: 1px; display: flex;">
|
||||
<uie:Toolbar name="TopBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
||||
@@ -8,7 +8,7 @@
|
||||
<uie:ToolbarButton text="LoadMethod" display-tooltip-when-elided="true" name="TopBar4" style="width: 150px; -unity-text-align: middle-left; flex-grow: 0;" />
|
||||
<uie:ToolbarButton text="Tags" display-tooltip-when-elided="true" name="TopBar5" style="width: 80px; -unity-text-align: middle-left; flex-grow: 1;" />
|
||||
</uie:Toolbar>
|
||||
<ui:ListView focusable="true" name="TopListView" item-height="18" virtualization-method="DynamicHeight" style="flex-grow: 1;" />
|
||||
<ui:ListView focusable="true" name="TopListView" item-height="18" virtualization-method="DynamicHeight" style="flex-grow: 1; flex-basis: 60px;" />
|
||||
</ui:VisualElement>
|
||||
<ui:VisualElement name="BottomGroup" style="height: 200px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex;">
|
||||
<uie:Toolbar name="BottomBar" style="height: 25px; margin-left: 1px; margin-right: 1px;">
|
||||
|
||||
36
Assets/YooAsset/Editor/EditorAttribute.cs
Normal file
36
Assets/YooAsset/Editor/EditorAttribute.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// 编辑器显示名字
|
||||
/// </summary>
|
||||
public class DisplayNameAttribute : Attribute
|
||||
{
|
||||
public string DisplayName;
|
||||
|
||||
public DisplayNameAttribute(string name)
|
||||
{
|
||||
this.DisplayName = name;
|
||||
}
|
||||
}
|
||||
|
||||
public static class EditorAttribute
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6296859f09655c4191594304ddf378f
|
||||
guid: 92d5f73b21059af43b7f56165b7acd63
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -285,6 +285,35 @@ namespace YooAsset.Editor
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region StringUtility
|
||||
public static List<string> StringToStringList(string str, char separator)
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
if (!String.IsNullOrEmpty(str))
|
||||
{
|
||||
string[] splits = str.Split(separator);
|
||||
foreach (string split in splits)
|
||||
{
|
||||
string value = split.Trim(); //移除首尾空格
|
||||
if (!String.IsNullOrEmpty(value))
|
||||
{
|
||||
result.Add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static T NameToEnum<T>(string name)
|
||||
{
|
||||
if (Enum.IsDefined(typeof(T), name) == false)
|
||||
{
|
||||
throw new ArgumentException($"Enum {typeof(T)} is not defined name {name}");
|
||||
}
|
||||
return (T)Enum.Parse(typeof(T), name);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 文件
|
||||
/// <summary>
|
||||
/// 创建文件所在的目录
|
||||
|
||||
@@ -12,134 +12,169 @@ namespace YooAsset.Editor
|
||||
{
|
||||
public static class ShaderVariantCollector
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Prepare,
|
||||
CollectAllMaterial,
|
||||
CollectVariants,
|
||||
CollectSleeping,
|
||||
WaitingDone,
|
||||
}
|
||||
|
||||
private const float WaitMilliseconds = 1000f;
|
||||
private static string _saveFilePath;
|
||||
private static bool _isStarted = false;
|
||||
private static readonly Stopwatch _elapsedTime = new Stopwatch();
|
||||
private const float SleepMilliseconds = 100f;
|
||||
private static string _savePath;
|
||||
private static string _packageName;
|
||||
private static int _processMaxNum;
|
||||
private static Action _completedCallback;
|
||||
|
||||
private static void EditorUpdate()
|
||||
{
|
||||
// 注意:一定要延迟保存才会起效
|
||||
if (_isStarted && _elapsedTime.ElapsedMilliseconds > WaitMilliseconds)
|
||||
{
|
||||
_isStarted = false;
|
||||
_elapsedTime.Stop();
|
||||
EditorApplication.update -= EditorUpdate;
|
||||
private static ESteps _steps = ESteps.None;
|
||||
private static Stopwatch _elapsedTime;
|
||||
private static List<string> _allMaterials;
|
||||
private static List<GameObject> _allSpheres = new List<GameObject>(1000);
|
||||
|
||||
// 保存结果
|
||||
ShaderVariantCollectionHelper.SaveCurrentShaderVariantCollection(_saveFilePath);
|
||||
|
||||
// 创建清单
|
||||
CreateManifest();
|
||||
|
||||
Debug.Log($"搜集SVC完毕!");
|
||||
_completedCallback?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始收集
|
||||
/// </summary>
|
||||
public static void Run(string saveFilePath, Action completedCallback)
|
||||
public static void Run(string savePath, string packageName, int processMaxNum, Action completedCallback)
|
||||
{
|
||||
if (_isStarted)
|
||||
if (_steps != ESteps.None)
|
||||
return;
|
||||
|
||||
if (Path.HasExtension(saveFilePath) == false)
|
||||
saveFilePath = $"{saveFilePath}.shadervariants";
|
||||
if (Path.GetExtension(saveFilePath) != ".shadervariants")
|
||||
if (Path.HasExtension(savePath) == false)
|
||||
savePath = $"{savePath}.shadervariants";
|
||||
if (Path.GetExtension(savePath) != ".shadervariants")
|
||||
throw new System.Exception("Shader variant file extension is invalid.");
|
||||
if (string.IsNullOrEmpty(packageName))
|
||||
throw new System.Exception("Package name is null or empty !");
|
||||
|
||||
// 注意:先删除再保存,否则ShaderVariantCollection内容将无法及时刷新
|
||||
AssetDatabase.DeleteAsset(ShaderVariantCollectorSettingData.Setting.SavePath);
|
||||
EditorTools.CreateFileDirectory(saveFilePath);
|
||||
_saveFilePath = saveFilePath;
|
||||
AssetDatabase.DeleteAsset(savePath);
|
||||
EditorTools.CreateFileDirectory(savePath);
|
||||
_savePath = savePath;
|
||||
_packageName = packageName;
|
||||
_processMaxNum = processMaxNum;
|
||||
_completedCallback = completedCallback;
|
||||
|
||||
// 聚焦到游戏窗口
|
||||
EditorTools.FocusUnityGameWindow();
|
||||
|
||||
// 清空旧数据
|
||||
ShaderVariantCollectionHelper.ClearCurrentShaderVariantCollection();
|
||||
|
||||
// 创建临时测试场景
|
||||
CreateTempScene();
|
||||
|
||||
// 收集着色器变种
|
||||
var materials = GetAllMaterials();
|
||||
CollectVariants(materials);
|
||||
|
||||
_steps = ESteps.Prepare;
|
||||
EditorApplication.update += EditorUpdate;
|
||||
_isStarted = true;
|
||||
_elapsedTime.Reset();
|
||||
_elapsedTime.Start();
|
||||
}
|
||||
|
||||
private static void EditorUpdate()
|
||||
{
|
||||
if (_steps == ESteps.None)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.Prepare)
|
||||
{
|
||||
ShaderVariantCollectionHelper.ClearCurrentShaderVariantCollection();
|
||||
_steps = ESteps.CollectAllMaterial;
|
||||
return; //等待一帧
|
||||
}
|
||||
|
||||
if (_steps == ESteps.CollectAllMaterial)
|
||||
{
|
||||
_allMaterials = GetAllMaterials();
|
||||
_steps = ESteps.CollectVariants;
|
||||
return; //等待一帧
|
||||
}
|
||||
|
||||
if (_steps == ESteps.CollectVariants)
|
||||
{
|
||||
int count = Mathf.Min(_processMaxNum, _allMaterials.Count);
|
||||
List<string> range = _allMaterials.GetRange(0, count);
|
||||
_allMaterials.RemoveRange(0, count);
|
||||
CollectVariants(range);
|
||||
|
||||
if (_allMaterials.Count > 0)
|
||||
{
|
||||
_elapsedTime = Stopwatch.StartNew();
|
||||
_steps = ESteps.CollectSleeping;
|
||||
}
|
||||
else
|
||||
{
|
||||
_elapsedTime = Stopwatch.StartNew();
|
||||
_steps = ESteps.WaitingDone;
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.CollectSleeping)
|
||||
{
|
||||
if (_elapsedTime.ElapsedMilliseconds > SleepMilliseconds)
|
||||
{
|
||||
DestroyAllSpheres();
|
||||
_elapsedTime.Stop();
|
||||
_steps = ESteps.CollectVariants;
|
||||
}
|
||||
}
|
||||
|
||||
if (_steps == ESteps.WaitingDone)
|
||||
{
|
||||
// 注意:一定要延迟保存才会起效
|
||||
if (_elapsedTime.ElapsedMilliseconds > WaitMilliseconds)
|
||||
{
|
||||
_elapsedTime.Stop();
|
||||
_steps = ESteps.None;
|
||||
|
||||
// 保存结果并创建清单
|
||||
ShaderVariantCollectionHelper.SaveCurrentShaderVariantCollection(_savePath);
|
||||
CreateManifest();
|
||||
|
||||
Debug.Log($"搜集SVC完毕!");
|
||||
EditorApplication.update -= EditorUpdate;
|
||||
_completedCallback?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
private static void CreateTempScene()
|
||||
{
|
||||
EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects);
|
||||
}
|
||||
private static List<Material> GetAllMaterials()
|
||||
private static List<string> GetAllMaterials()
|
||||
{
|
||||
int progressValue = 0;
|
||||
List<string> allAssets = new List<string>(1000);
|
||||
|
||||
// 获取所有打包的资源
|
||||
List<CollectAssetInfo> allCollectAssetInfos = new List<CollectAssetInfo>();
|
||||
List<CollectResult> collectResults = AssetBundleCollectorSettingData.Setting.GetAllPackageAssets(EBuildMode.DryRunBuild);
|
||||
foreach (var collectResult in collectResults)
|
||||
CollectResult collectResult = AssetBundleCollectorSettingData.Setting.GetPackageAssets(EBuildMode.DryRunBuild, _packageName);
|
||||
foreach (var assetInfo in collectResult.CollectAssets)
|
||||
{
|
||||
allCollectAssetInfos.AddRange(collectResult.CollectAssets);
|
||||
}
|
||||
List<string> allAssetPath = allCollectAssetInfos.Select(t => t.AssetPath).ToList();
|
||||
foreach (var assetPath in allAssetPath)
|
||||
{
|
||||
string[] depends = AssetDatabase.GetDependencies(assetPath, true);
|
||||
foreach (var depend in depends)
|
||||
string[] depends = AssetDatabase.GetDependencies(assetInfo.AssetPath, true);
|
||||
foreach (var dependAsset in depends)
|
||||
{
|
||||
if (allAssets.Contains(depend) == false)
|
||||
allAssets.Add(depend);
|
||||
if (allAssets.Contains(dependAsset) == false)
|
||||
allAssets.Add(dependAsset);
|
||||
}
|
||||
EditorTools.DisplayProgressBar("获取所有打包资源", ++progressValue, allAssetPath.Count);
|
||||
EditorTools.DisplayProgressBar("获取所有打包资源", ++progressValue, collectResult.CollectAssets.Count);
|
||||
}
|
||||
EditorTools.ClearProgressBar();
|
||||
|
||||
// 搜集所有材质球
|
||||
progressValue = 0;
|
||||
var shaderDic = new Dictionary<Shader, List<Material>>(100);
|
||||
List<string> allMaterial = new List<string>(1000);
|
||||
foreach (var assetPath in allAssets)
|
||||
{
|
||||
System.Type assetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
|
||||
if (assetType == typeof(UnityEngine.Material))
|
||||
{
|
||||
var material = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
|
||||
var shader = material.shader;
|
||||
if (shader == null)
|
||||
continue;
|
||||
|
||||
if (shaderDic.ContainsKey(shader) == false)
|
||||
{
|
||||
shaderDic.Add(shader, new List<Material>());
|
||||
}
|
||||
if (shaderDic[shader].Contains(material) == false)
|
||||
{
|
||||
shaderDic[shader].Add(material);
|
||||
}
|
||||
allMaterial.Add(assetPath);
|
||||
}
|
||||
EditorTools.DisplayProgressBar("搜集所有材质球", ++progressValue, allAssets.Count);
|
||||
}
|
||||
EditorTools.ClearProgressBar();
|
||||
|
||||
// 返回结果
|
||||
var materials = new List<Material>(1000);
|
||||
foreach (var valuePair in shaderDic)
|
||||
{
|
||||
materials.AddRange(valuePair.Value);
|
||||
}
|
||||
return materials;
|
||||
return allMaterial;
|
||||
}
|
||||
private static void CollectVariants(List<Material> materials)
|
||||
private static void CollectVariants(List<string> materials)
|
||||
{
|
||||
Camera camera = Camera.main;
|
||||
if (camera == null)
|
||||
@@ -164,7 +199,9 @@ namespace YooAsset.Editor
|
||||
{
|
||||
var material = materials[i];
|
||||
var position = new Vector3(x - halfWidth + 1f, y - halfHeight + 1f, 0f);
|
||||
CreateSphere(material, position, i);
|
||||
var go = CreateSphere(material, position, i);
|
||||
if (go != null)
|
||||
_allSpheres.Add(go);
|
||||
if (x == xMax)
|
||||
{
|
||||
x = 0;
|
||||
@@ -174,27 +211,44 @@ namespace YooAsset.Editor
|
||||
{
|
||||
x++;
|
||||
}
|
||||
EditorTools.DisplayProgressBar("测试所有材质球", ++progressValue, materials.Count);
|
||||
EditorTools.DisplayProgressBar("照射所有材质球", ++progressValue, materials.Count);
|
||||
}
|
||||
EditorTools.ClearProgressBar();
|
||||
}
|
||||
private static void CreateSphere(Material material, Vector3 position, int index)
|
||||
private static GameObject CreateSphere(string assetPath, Vector3 position, int index)
|
||||
{
|
||||
var material = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
|
||||
var shader = material.shader;
|
||||
if (shader == null)
|
||||
return null;
|
||||
|
||||
var go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
||||
go.GetComponent<Renderer>().material = material;
|
||||
go.GetComponent<Renderer>().sharedMaterial = material;
|
||||
go.transform.position = position;
|
||||
go.name = $"Sphere_{index}|{material.name}";
|
||||
go.name = $"Sphere_{index} | {material.name}";
|
||||
return go;
|
||||
}
|
||||
private static void DestroyAllSpheres()
|
||||
{
|
||||
foreach(var go in _allSpheres)
|
||||
{
|
||||
GameObject.DestroyImmediate(go);
|
||||
}
|
||||
_allSpheres.Clear();
|
||||
|
||||
// 尝试释放编辑器加载的资源
|
||||
EditorUtility.UnloadUnusedAssetsImmediate(true);
|
||||
}
|
||||
private static void CreateManifest()
|
||||
{
|
||||
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
|
||||
|
||||
ShaderVariantCollection svc = AssetDatabase.LoadAssetAtPath<ShaderVariantCollection>(_saveFilePath);
|
||||
ShaderVariantCollection svc = AssetDatabase.LoadAssetAtPath<ShaderVariantCollection>(_savePath);
|
||||
if (svc != null)
|
||||
{
|
||||
var wrapper = ShaderVariantCollectionManifest.Extract(svc);
|
||||
string jsonData = JsonUtility.ToJson(wrapper, true);
|
||||
string savePath = _saveFilePath.Replace(".shadervariants", ".json");
|
||||
string savePath = _savePath.Replace(".shadervariants", ".json");
|
||||
File.WriteAllText(savePath, jsonData);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,5 +8,10 @@ namespace YooAsset.Editor
|
||||
/// 文件存储路径
|
||||
/// </summary>
|
||||
public string SavePath = "Assets/MyShaderVariants.shadervariants";
|
||||
|
||||
/// <summary>
|
||||
/// 收集的包裹名称
|
||||
/// </summary>
|
||||
public string CollectPackage = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -18,10 +18,13 @@ namespace YooAsset.Editor
|
||||
window.minSize = new Vector2(800, 600);
|
||||
}
|
||||
|
||||
private List<string> _packageNames;
|
||||
|
||||
private Button _collectButton;
|
||||
private TextField _collectOutputField;
|
||||
private Label _currentShaderCountField;
|
||||
private Label _currentVariantCountField;
|
||||
private PopupField<string> _packageField;
|
||||
|
||||
public void CreateGUI()
|
||||
{
|
||||
@@ -36,6 +39,9 @@ namespace YooAsset.Editor
|
||||
|
||||
visualAsset.CloneTree(root);
|
||||
|
||||
// 包裹名称列表
|
||||
_packageNames = GetBuildPackageNames();
|
||||
|
||||
// 文件输出目录
|
||||
_collectOutputField = root.Q<TextField>("CollectOutput");
|
||||
_collectOutputField.SetValueWithoutNotify(ShaderVariantCollectorSettingData.Setting.SavePath);
|
||||
@@ -44,14 +50,34 @@ namespace YooAsset.Editor
|
||||
ShaderVariantCollectorSettingData.Setting.SavePath = _collectOutputField.value;
|
||||
});
|
||||
|
||||
// 收集的包裹
|
||||
var packageContainer = root.Q("PackageContainer");
|
||||
if (_packageNames.Count > 0)
|
||||
{
|
||||
int defaultIndex = GetDefaultPackageIndex(ShaderVariantCollectorSettingData.Setting.CollectPackage);
|
||||
_packageField = new PopupField<string>(_packageNames, defaultIndex);
|
||||
_packageField.label = "Package";
|
||||
_packageField.style.width = 350;
|
||||
_packageField.RegisterValueChangedCallback(evt =>
|
||||
{
|
||||
ShaderVariantCollectorSettingData.Setting.CollectPackage = _packageField.value;
|
||||
});
|
||||
packageContainer.Add(_packageField);
|
||||
}
|
||||
else
|
||||
{
|
||||
_packageField = new PopupField<string>();
|
||||
_packageField.label = "Package";
|
||||
_packageField.style.width = 350;
|
||||
packageContainer.Add(_packageField);
|
||||
}
|
||||
|
||||
_currentShaderCountField = root.Q<Label>("CurrentShaderCount");
|
||||
_currentVariantCountField = root.Q<Label>("CurrentVariantCount");
|
||||
|
||||
// 变种收集按钮
|
||||
_collectButton = root.Q<Button>("CollectButton");
|
||||
_collectButton.clicked += CollectButton_clicked;
|
||||
|
||||
//RefreshWindow();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -75,7 +101,33 @@ namespace YooAsset.Editor
|
||||
|
||||
private void CollectButton_clicked()
|
||||
{
|
||||
ShaderVariantCollector.Run(ShaderVariantCollectorSettingData.Setting.SavePath, null);
|
||||
string savePath = ShaderVariantCollectorSettingData.Setting.SavePath;
|
||||
string packageName = ShaderVariantCollectorSettingData.Setting.CollectPackage;
|
||||
ShaderVariantCollector.Run(savePath, packageName, int.MaxValue, null);
|
||||
}
|
||||
|
||||
// 构建包裹相关
|
||||
private int GetDefaultPackageIndex(string packageName)
|
||||
{
|
||||
for (int index = 0; index < _packageNames.Count; index++)
|
||||
{
|
||||
if (_packageNames[index] == packageName)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderVariantCollectorSettingData.Setting.CollectPackage = _packageNames[0];
|
||||
return 0;
|
||||
}
|
||||
private List<string> GetBuildPackageNames()
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
foreach (var package in AssetBundleCollectorSettingData.Setting.Packages)
|
||||
{
|
||||
result.Add(package.PackageName);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<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:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
|
||||
<uie:Toolbar name="Toolbar" style="display: flex; flex-direction: row-reverse;" />
|
||||
<ui:VisualElement name="BuildContainer">
|
||||
<ui:TextField picking-mode="Ignore" label="文件保存路径" name="CollectOutput" />
|
||||
<ui:Label text="Current Shader Count" display-tooltip-when-elided="true" name="CurrentShaderCount" />
|
||||
<ui:Label text="Current Variant Count" display-tooltip-when-elided="true" name="CurrentVariantCount" />
|
||||
<ui:VisualElement name="CollectContainer">
|
||||
<ui:TextField picking-mode="Ignore" label="文件保存路径" name="CollectOutput" style="height: 22px;" />
|
||||
<ui:VisualElement name="PackageContainer" style="height: 24px;" />
|
||||
<ui:Label text="Current Shader Count" display-tooltip-when-elided="true" name="CurrentShaderCount" style="height: 20px; padding-left: 4px;" />
|
||||
<ui:Label text="Current Variant Count" display-tooltip-when-elided="true" name="CurrentVariantCount" style="height: 20px; padding-left: 4px;" />
|
||||
<ui:Button text="开始搜集" display-tooltip-when-elided="true" name="CollectButton" style="height: 50px; background-color: rgb(40, 106, 42); margin-top: 10px;" />
|
||||
</ui:VisualElement>
|
||||
</ui:UXML>
|
||||
|
||||
8
Assets/YooAsset/Runtime/AssetReference.cs
Normal file
8
Assets/YooAsset/Runtime/AssetReference.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
public class AssetReference
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e26f14db9addb4c49b4f0f520bf75d9d
|
||||
guid: 1534f1a1b207ad542bf1fc73da8b4316
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -8,13 +8,12 @@ namespace YooAsset
|
||||
{
|
||||
internal class AssetSystemImpl
|
||||
{
|
||||
private static string SceneRunningPackage = string.Empty;
|
||||
|
||||
private readonly List<AssetBundleLoaderBase> _loaders = new List<AssetBundleLoaderBase>(1000);
|
||||
private readonly List<BundleLoaderBase> _loaders = new List<BundleLoaderBase>(1000);
|
||||
private readonly List<ProviderBase> _providers = new List<ProviderBase>(1000);
|
||||
private readonly Dictionary<string, SceneOperationHandle> _sceneHandles = new Dictionary<string, SceneOperationHandle>(100);
|
||||
private readonly static Dictionary<string, SceneOperationHandle> _sceneHandles = new Dictionary<string, SceneOperationHandle>(100);
|
||||
private static long _sceneCreateCount = 0;
|
||||
|
||||
private long _sceneCreateCount = 0;
|
||||
private string _packageName;
|
||||
private bool _simulationOnEditor;
|
||||
private int _loadingMaxNumber;
|
||||
public IDecryptionServices DecryptionServices { private set; get; }
|
||||
@@ -25,8 +24,9 @@ namespace YooAsset
|
||||
/// 初始化
|
||||
/// 注意:在使用AssetSystem之前需要初始化
|
||||
/// </summary>
|
||||
public void Initialize(bool simulationOnEditor, int loadingMaxNumber, IDecryptionServices decryptionServices, IBundleServices bundleServices)
|
||||
public void Initialize(string packageName, bool simulationOnEditor, int loadingMaxNumber, IDecryptionServices decryptionServices, IBundleServices bundleServices)
|
||||
{
|
||||
_packageName = packageName;
|
||||
_simulationOnEditor = simulationOnEditor;
|
||||
_loadingMaxNumber = loadingMaxNumber;
|
||||
DecryptionServices = decryptionServices;
|
||||
@@ -71,10 +71,19 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public void DestroyAll()
|
||||
{
|
||||
_loaders.Clear();
|
||||
foreach (var provider in _providers)
|
||||
{
|
||||
provider.Destroy();
|
||||
}
|
||||
_providers.Clear();
|
||||
_sceneHandles.Clear();
|
||||
|
||||
foreach (var loader in _loaders)
|
||||
{
|
||||
loader.Destroy(true);
|
||||
}
|
||||
_loaders.Clear();
|
||||
|
||||
ClearSceneHandle();
|
||||
DecryptionServices = null;
|
||||
BundleServices = null;
|
||||
}
|
||||
@@ -83,6 +92,15 @@ namespace YooAsset
|
||||
/// 资源回收(卸载引用计数为零的资源)
|
||||
/// </summary>
|
||||
public void UnloadUnusedAssets()
|
||||
{
|
||||
// 注意:资源包之间可能存在多层深层嵌套,需要多次循环释放。
|
||||
int loopCount = 10;
|
||||
for (int i = 0; i < loopCount; i++)
|
||||
{
|
||||
UnloadUnusedAssetsInternal();
|
||||
}
|
||||
}
|
||||
private void UnloadUnusedAssetsInternal()
|
||||
{
|
||||
if (_simulationOnEditor)
|
||||
{
|
||||
@@ -99,12 +117,12 @@ namespace YooAsset
|
||||
{
|
||||
for (int i = _loaders.Count - 1; i >= 0; i--)
|
||||
{
|
||||
AssetBundleLoaderBase loader = _loaders[i];
|
||||
BundleLoaderBase loader = _loaders[i];
|
||||
loader.TryDestroyAllProviders();
|
||||
}
|
||||
for (int i = _loaders.Count - 1; i >= 0; i--)
|
||||
{
|
||||
AssetBundleLoaderBase loader = _loaders[i];
|
||||
BundleLoaderBase loader = _loaders[i];
|
||||
if (loader.CanDestroy())
|
||||
{
|
||||
loader.Destroy(false);
|
||||
@@ -123,15 +141,14 @@ namespace YooAsset
|
||||
{
|
||||
provider.Destroy();
|
||||
}
|
||||
_providers.Clear();
|
||||
|
||||
foreach (var loader in _loaders)
|
||||
{
|
||||
loader.Destroy(true);
|
||||
}
|
||||
_loaders.Clear();
|
||||
|
||||
_sceneHandles.Clear();
|
||||
_providers.Clear();
|
||||
_loaders.Clear();
|
||||
ClearSceneHandle();
|
||||
|
||||
// 注意:调用底层接口释放所有资源
|
||||
Resources.UnloadUnusedAssets();
|
||||
@@ -144,25 +161,12 @@ namespace YooAsset
|
||||
{
|
||||
if (assetInfo.IsInvalid)
|
||||
{
|
||||
YooLogger.Error($"Failed to load scene. {assetInfo.Error}");
|
||||
YooLogger.Error($"Failed to load scene ! {assetInfo.Error}");
|
||||
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
|
||||
completedProvider.SetCompleted(assetInfo.Error);
|
||||
return completedProvider.CreateHandle<SceneOperationHandle>();
|
||||
}
|
||||
|
||||
// 注意:场景只允许运行在一个资源包内
|
||||
if (string.IsNullOrEmpty(SceneRunningPackage))
|
||||
{
|
||||
SceneRunningPackage = BundleServices.GetPackageName();
|
||||
}
|
||||
if (BundleServices.GetPackageName() != SceneRunningPackage)
|
||||
{
|
||||
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
|
||||
string error = $"Scene are allowed to running within only {SceneRunningPackage}";
|
||||
completedProvider.SetCompleted(error);
|
||||
return completedProvider.CreateHandle<SceneOperationHandle>();
|
||||
}
|
||||
|
||||
// 如果加载的是主场景,则卸载所有缓存的场景
|
||||
if (sceneMode == LoadSceneMode.Single)
|
||||
{
|
||||
@@ -182,6 +186,7 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
var handle = provider.CreateHandle<SceneOperationHandle>();
|
||||
handle.PackageName = _packageName;
|
||||
_sceneHandles.Add(providerGUID, handle);
|
||||
return handle;
|
||||
}
|
||||
@@ -193,7 +198,7 @@ namespace YooAsset
|
||||
{
|
||||
if (assetInfo.IsInvalid)
|
||||
{
|
||||
YooLogger.Error($"Failed to load asset. {assetInfo.Error}");
|
||||
YooLogger.Error($"Failed to load asset ! {assetInfo.Error}");
|
||||
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
|
||||
completedProvider.SetCompleted(assetInfo.Error);
|
||||
return completedProvider.CreateHandle<AssetOperationHandle>();
|
||||
@@ -220,7 +225,7 @@ namespace YooAsset
|
||||
{
|
||||
if (assetInfo.IsInvalid)
|
||||
{
|
||||
YooLogger.Error($"Failed to load sub assets. {assetInfo.Error}");
|
||||
YooLogger.Error($"Failed to load sub assets ! {assetInfo.Error}");
|
||||
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
|
||||
completedProvider.SetCompleted(assetInfo.Error);
|
||||
return completedProvider.CreateHandle<SubAssetsOperationHandle>();
|
||||
@@ -240,6 +245,33 @@ namespace YooAsset
|
||||
return provider.CreateHandle<SubAssetsOperationHandle>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载原生文件
|
||||
/// </summary>
|
||||
public RawFileOperationHandle LoadRawFileAsync(AssetInfo assetInfo)
|
||||
{
|
||||
if (assetInfo.IsInvalid)
|
||||
{
|
||||
YooLogger.Error($"Failed to load raw file ! {assetInfo.Error}");
|
||||
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
|
||||
completedProvider.SetCompleted(assetInfo.Error);
|
||||
return completedProvider.CreateHandle<RawFileOperationHandle>();
|
||||
}
|
||||
|
||||
string providerGUID = assetInfo.GUID;
|
||||
ProviderBase provider = TryGetProvider(providerGUID);
|
||||
if (provider == null)
|
||||
{
|
||||
if (_simulationOnEditor)
|
||||
provider = new DatabaseRawFileProvider(this, providerGUID, assetInfo);
|
||||
else
|
||||
provider = new BundledRawFileProvider(this, providerGUID, assetInfo);
|
||||
provider.InitSpawnDebugInfo();
|
||||
_providers.Add(provider);
|
||||
}
|
||||
return provider.CreateHandle<RawFileOperationHandle>();
|
||||
}
|
||||
|
||||
internal void UnloadSubScene(ProviderBase provider)
|
||||
{
|
||||
string providerGUID = provider.ProviderGUID;
|
||||
@@ -265,19 +297,39 @@ namespace YooAsset
|
||||
// 卸载未被使用的资源(包括场景)
|
||||
UnloadUnusedAssets();
|
||||
}
|
||||
internal void ClearSceneHandle()
|
||||
{
|
||||
// 释放资源包下的所有场景
|
||||
if (BundleServices.IsServicesValid())
|
||||
{
|
||||
string packageName = _packageName;
|
||||
List<string> removeList = new List<string>();
|
||||
foreach (var valuePair in _sceneHandles)
|
||||
{
|
||||
if (valuePair.Value.PackageName == packageName)
|
||||
{
|
||||
removeList.Add(valuePair.Key);
|
||||
}
|
||||
}
|
||||
foreach (var key in removeList)
|
||||
{
|
||||
_sceneHandles.Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal AssetBundleLoaderBase CreateOwnerAssetBundleLoader(AssetInfo assetInfo)
|
||||
internal BundleLoaderBase CreateOwnerAssetBundleLoader(AssetInfo assetInfo)
|
||||
{
|
||||
BundleInfo bundleInfo = BundleServices.GetBundleInfo(assetInfo);
|
||||
return CreateAssetBundleLoaderInternal(bundleInfo);
|
||||
}
|
||||
internal List<AssetBundleLoaderBase> CreateDependAssetBundleLoaders(AssetInfo assetInfo)
|
||||
internal List<BundleLoaderBase> CreateDependAssetBundleLoaders(AssetInfo assetInfo)
|
||||
{
|
||||
BundleInfo[] depends = BundleServices.GetAllDependBundleInfos(assetInfo);
|
||||
List<AssetBundleLoaderBase> result = new List<AssetBundleLoaderBase>(depends.Length);
|
||||
List<BundleLoaderBase> result = new List<BundleLoaderBase>(depends.Length);
|
||||
foreach (var bundleInfo in depends)
|
||||
{
|
||||
AssetBundleLoaderBase dependLoader = CreateAssetBundleLoaderInternal(bundleInfo);
|
||||
BundleLoaderBase dependLoader = CreateAssetBundleLoaderInternal(bundleInfo);
|
||||
result.Add(dependLoader);
|
||||
}
|
||||
return result;
|
||||
@@ -290,29 +342,35 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
private AssetBundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo)
|
||||
private BundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo)
|
||||
{
|
||||
// 如果加载器已经存在
|
||||
AssetBundleLoaderBase loader = TryGetAssetBundleLoader(bundleInfo.Bundle.BundleName);
|
||||
BundleLoaderBase loader = TryGetAssetBundleLoader(bundleInfo.Bundle.BundleName);
|
||||
if (loader != null)
|
||||
return loader;
|
||||
|
||||
// 新增下载需求
|
||||
#if UNITY_WEBGL
|
||||
loader = new AssetBundleWebLoader(this, bundleInfo);
|
||||
if (bundleInfo.Bundle.IsRawFile)
|
||||
loader = new RawBundleFileLoader(this, bundleInfo);
|
||||
else
|
||||
loader = new AssetBundleWebLoader(this, bundleInfo);
|
||||
#else
|
||||
loader = new AssetBundleFileLoader(this, bundleInfo);
|
||||
if (bundleInfo.Bundle.IsRawFile)
|
||||
loader = new RawBundleFileLoader(this, bundleInfo);
|
||||
else
|
||||
loader = new AssetBundleFileLoader(this, bundleInfo);
|
||||
#endif
|
||||
|
||||
_loaders.Add(loader);
|
||||
return loader;
|
||||
}
|
||||
private AssetBundleLoaderBase TryGetAssetBundleLoader(string bundleName)
|
||||
private BundleLoaderBase TryGetAssetBundleLoader(string bundleName)
|
||||
{
|
||||
AssetBundleLoaderBase loader = null;
|
||||
BundleLoaderBase loader = null;
|
||||
for (int i = 0; i < _loaders.Count; i++)
|
||||
{
|
||||
AssetBundleLoaderBase temp = _loaders[i];
|
||||
BundleLoaderBase temp = _loaders[i];
|
||||
if (temp.MainBundleInfo.Bundle.BundleName.Equals(bundleName))
|
||||
{
|
||||
loader = temp;
|
||||
@@ -348,7 +406,7 @@ namespace YooAsset
|
||||
providerInfo.SpawnTime = provider.SpawnTime;
|
||||
providerInfo.LoadingTime = provider.LoadingTime;
|
||||
providerInfo.RefCount = provider.RefCount;
|
||||
providerInfo.Status = (int)provider.Status;
|
||||
providerInfo.Status = provider.Status.ToString();
|
||||
providerInfo.DependBundleInfos = new List<DebugBundleInfo>();
|
||||
result.Add(providerInfo);
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
public sealed class AssetOperationHandle : OperationHandleBase
|
||||
public sealed class AssetOperationHandle : OperationHandleBase, IDisposable
|
||||
{
|
||||
private System.Action<AssetOperationHandle> _callback;
|
||||
|
||||
@@ -22,7 +23,7 @@ namespace YooAsset
|
||||
{
|
||||
add
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
throw new System.Exception($"{nameof(AssetOperationHandle)} is invalid");
|
||||
if (Provider.IsDone)
|
||||
value.Invoke(this);
|
||||
@@ -31,42 +32,18 @@ namespace YooAsset
|
||||
}
|
||||
remove
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
throw new System.Exception($"{nameof(AssetOperationHandle)} is invalid");
|
||||
_callback -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资源对象
|
||||
/// </summary>
|
||||
public UnityEngine.Object AssetObject
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValid == false)
|
||||
return null;
|
||||
return Provider.AssetObject;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取资源对象
|
||||
/// </summary>
|
||||
/// <typeparam name="TAsset">资源类型</typeparam>
|
||||
public TAsset GetAssetObject<TAsset>() where TAsset : UnityEngine.Object
|
||||
{
|
||||
if (IsValid == false)
|
||||
return null;
|
||||
return Provider.AssetObject as TAsset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 等待异步执行完毕
|
||||
/// </summary>
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return;
|
||||
Provider.WaitForAsyncComplete();
|
||||
}
|
||||
@@ -79,6 +56,38 @@ namespace YooAsset
|
||||
this.ReleaseInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源句柄
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.ReleaseInternal();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 资源对象
|
||||
/// </summary>
|
||||
public UnityEngine.Object AssetObject
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValidWithWarning == false)
|
||||
return null;
|
||||
return Provider.AssetObject;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取资源对象
|
||||
/// </summary>
|
||||
/// <typeparam name="TAsset">资源类型</typeparam>
|
||||
public TAsset GetAssetObject<TAsset>() where TAsset : UnityEngine.Object
|
||||
{
|
||||
if (IsValidWithWarning == false)
|
||||
return null;
|
||||
return Provider.AssetObject as TAsset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步初始化游戏对象
|
||||
@@ -124,7 +133,7 @@ namespace YooAsset
|
||||
|
||||
private GameObject InstantiateSyncInternal(Vector3 position, Quaternion rotation, Transform parent)
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return null;
|
||||
if (Provider.AssetObject == null)
|
||||
return null;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
@@ -14,7 +15,6 @@ namespace YooAsset
|
||||
}
|
||||
internal abstract void InvokeCallback();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取资源信息
|
||||
/// </summary>
|
||||
@@ -23,6 +23,18 @@ namespace YooAsset
|
||||
return _assetInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取下载报告
|
||||
/// </summary>
|
||||
public DownloadReport GetDownloadReport()
|
||||
{
|
||||
if (IsValidWithWarning == false)
|
||||
{
|
||||
return DownloadReport.CreateDefaultReport();
|
||||
}
|
||||
return Provider.GetDownloadReport();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
@@ -30,11 +42,11 @@ namespace YooAsset
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return EOperationStatus.None;
|
||||
if (Provider.Status == ProviderBase.EStatus.Fail)
|
||||
if (Provider.Status == ProviderBase.EStatus.Failed)
|
||||
return EOperationStatus.Failed;
|
||||
else if (Provider.Status == ProviderBase.EStatus.Success)
|
||||
else if (Provider.Status == ProviderBase.EStatus.Succeed)
|
||||
return EOperationStatus.Succeed;
|
||||
else
|
||||
return EOperationStatus.None;
|
||||
@@ -48,7 +60,7 @@ namespace YooAsset
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return string.Empty;
|
||||
return Provider.LastError;
|
||||
}
|
||||
@@ -61,7 +73,7 @@ namespace YooAsset
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return 0;
|
||||
return Provider.Progress;
|
||||
}
|
||||
@@ -74,7 +86,7 @@ namespace YooAsset
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return false;
|
||||
return Provider.IsDone;
|
||||
}
|
||||
@@ -84,6 +96,20 @@ namespace YooAsset
|
||||
/// 句柄是否有效
|
||||
/// </summary>
|
||||
public bool IsValid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Provider != null && Provider.IsDestroyed == false)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 句柄是否有效
|
||||
/// </summary>
|
||||
internal bool IsValidWithWarning
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -102,26 +128,12 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 句柄是否有效
|
||||
/// </summary>
|
||||
public bool IsValidNoWarning
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Provider != null && Provider.IsDestroyed == false)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放句柄
|
||||
/// </summary>
|
||||
internal void ReleaseInternal()
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return;
|
||||
Provider.ReleaseHandle(this);
|
||||
Provider = null;
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
public class RawFileOperationHandle : OperationHandleBase, IDisposable
|
||||
{
|
||||
private System.Action<RawFileOperationHandle> _callback;
|
||||
|
||||
internal RawFileOperationHandle(ProviderBase provider) : base(provider)
|
||||
{
|
||||
}
|
||||
internal override void InvokeCallback()
|
||||
{
|
||||
_callback?.Invoke(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 完成委托
|
||||
/// </summary>
|
||||
public event System.Action<RawFileOperationHandle> Completed
|
||||
{
|
||||
add
|
||||
{
|
||||
if (IsValidWithWarning == false)
|
||||
throw new System.Exception($"{nameof(RawFileOperationHandle)} is invalid");
|
||||
if (Provider.IsDone)
|
||||
value.Invoke(this);
|
||||
else
|
||||
_callback += value;
|
||||
}
|
||||
remove
|
||||
{
|
||||
if (IsValidWithWarning == false)
|
||||
throw new System.Exception($"{nameof(RawFileOperationHandle)} is invalid");
|
||||
_callback -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 等待异步执行完毕
|
||||
/// </summary>
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
if (IsValidWithWarning == false)
|
||||
return;
|
||||
Provider.WaitForAsyncComplete();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源句柄
|
||||
/// </summary>
|
||||
public void Release()
|
||||
{
|
||||
this.ReleaseInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源句柄
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.ReleaseInternal();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取原生文件的二进制数据
|
||||
/// </summary>
|
||||
public byte[] GetRawFileData()
|
||||
{
|
||||
if (IsValidWithWarning == false)
|
||||
return null;
|
||||
string filePath = Provider.RawFilePath;
|
||||
if (File.Exists(filePath) == false)
|
||||
return null;
|
||||
return File.ReadAllBytes(filePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取原生文件的文本数据
|
||||
/// </summary>
|
||||
public string GetRawFileText()
|
||||
{
|
||||
if (IsValidWithWarning == false)
|
||||
return null;
|
||||
string filePath = Provider.RawFilePath;
|
||||
if (File.Exists(filePath) == false)
|
||||
return null;
|
||||
return File.ReadAllText(filePath, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取原生文件的路径
|
||||
/// </summary>
|
||||
public string GetRawFilePath()
|
||||
{
|
||||
if (IsValidWithWarning == false)
|
||||
return string.Empty;
|
||||
return Provider.RawFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d400b2548d79ca42bec7370f5d66b78
|
||||
guid: e8420ba734d425a4ba9f19173d74503c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -3,8 +3,9 @@
|
||||
namespace YooAsset
|
||||
{
|
||||
public class SceneOperationHandle : OperationHandleBase
|
||||
{
|
||||
{
|
||||
private System.Action<SceneOperationHandle> _callback;
|
||||
internal string PackageName { set; get; }
|
||||
|
||||
internal SceneOperationHandle(ProviderBase provider) : base(provider)
|
||||
{
|
||||
@@ -21,7 +22,7 @@ namespace YooAsset
|
||||
{
|
||||
add
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
throw new System.Exception($"{nameof(SceneOperationHandle)} is invalid");
|
||||
if (Provider.IsDone)
|
||||
value.Invoke(this);
|
||||
@@ -30,7 +31,7 @@ namespace YooAsset
|
||||
}
|
||||
remove
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
throw new System.Exception($"{nameof(SceneOperationHandle)} is invalid");
|
||||
_callback -= value;
|
||||
}
|
||||
@@ -43,7 +44,7 @@ namespace YooAsset
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return new Scene();
|
||||
return Provider.SceneObject;
|
||||
}
|
||||
@@ -54,7 +55,7 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public bool ActivateScene()
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return false;
|
||||
|
||||
if (SceneObject.IsValid() && SceneObject.isLoaded)
|
||||
@@ -73,7 +74,7 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public bool IsMainScene()
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return false;
|
||||
|
||||
if (Provider is DatabaseSceneProvider)
|
||||
@@ -98,7 +99,7 @@ namespace YooAsset
|
||||
public UnloadSceneOperation UnloadAsync()
|
||||
{
|
||||
// 如果句柄无效
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
{
|
||||
string error = $"{nameof(SceneOperationHandle)} is invalid.";
|
||||
var operation = new UnloadSceneOperation(error);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
public sealed class SubAssetsOperationHandle : OperationHandleBase
|
||||
public sealed class SubAssetsOperationHandle : OperationHandleBase, IDisposable
|
||||
{
|
||||
private System.Action<SubAssetsOperationHandle> _callback;
|
||||
|
||||
@@ -21,7 +22,7 @@ namespace YooAsset
|
||||
{
|
||||
add
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
throw new System.Exception($"{nameof(SubAssetsOperationHandle)} is invalid");
|
||||
if (Provider.IsDone)
|
||||
value.Invoke(this);
|
||||
@@ -30,31 +31,18 @@ namespace YooAsset
|
||||
}
|
||||
remove
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
throw new System.Exception($"{nameof(SubAssetsOperationHandle)} is invalid");
|
||||
_callback -= value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 子资源对象集合
|
||||
/// </summary>
|
||||
public UnityEngine.Object[] AllAssetObjects
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValid == false)
|
||||
return null;
|
||||
return Provider.AllAssetObjects;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 等待异步执行完毕
|
||||
/// </summary>
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return;
|
||||
Provider.WaitForAsyncComplete();
|
||||
}
|
||||
@@ -67,6 +55,27 @@ namespace YooAsset
|
||||
this.ReleaseInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源句柄
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.ReleaseInternal();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 子资源对象集合
|
||||
/// </summary>
|
||||
public UnityEngine.Object[] AllAssetObjects
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsValidWithWarning == false)
|
||||
return null;
|
||||
return Provider.AllAssetObjects;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取子资源对象
|
||||
@@ -75,7 +84,7 @@ namespace YooAsset
|
||||
/// <param name="assetName">子资源对象名称</param>
|
||||
public TObject GetSubAssetObject<TObject>(string assetName) where TObject : UnityEngine.Object
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return null;
|
||||
|
||||
foreach (var assetObject in Provider.AllAssetObjects)
|
||||
@@ -94,7 +103,7 @@ namespace YooAsset
|
||||
/// <typeparam name="TObject">子资源对象类型</typeparam>
|
||||
public TObject[] GetSubAssetObjects<TObject>() where TObject : UnityEngine.Object
|
||||
{
|
||||
if (IsValid == false)
|
||||
if (IsValidWithWarning == false)
|
||||
return null;
|
||||
|
||||
List<TObject> ret = new List<TObject>(Provider.AllAssetObjects.Length);
|
||||
|
||||
@@ -6,7 +6,7 @@ using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal sealed class AssetBundleFileLoader : AssetBundleLoaderBase
|
||||
internal sealed class AssetBundleFileLoader : BundleLoaderBase
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
@@ -21,7 +21,6 @@ namespace YooAsset
|
||||
}
|
||||
|
||||
private ESteps _steps = ESteps.None;
|
||||
private string _fileLoadPath;
|
||||
private bool _isWaitForAsyncComplete = false;
|
||||
private bool _isShowWaitForAsyncError = false;
|
||||
private DownloaderBase _unpacker;
|
||||
@@ -47,7 +46,7 @@ namespace YooAsset
|
||||
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
|
||||
{
|
||||
_steps = ESteps.Download;
|
||||
_fileLoadPath = MainBundleInfo.Bundle.CachedFilePath;
|
||||
FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath;
|
||||
}
|
||||
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
|
||||
{
|
||||
@@ -56,22 +55,22 @@ namespace YooAsset
|
||||
if (loadMethod == EBundleLoadMethod.LoadFromMemory || loadMethod == EBundleLoadMethod.LoadFromStream)
|
||||
{
|
||||
_steps = ESteps.Unpack;
|
||||
_fileLoadPath = MainBundleInfo.Bundle.CachedFilePath;
|
||||
FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.LoadFile;
|
||||
_fileLoadPath = MainBundleInfo.Bundle.StreamingFilePath;
|
||||
FileLoadPath = MainBundleInfo.Bundle.StreamingFilePath;
|
||||
}
|
||||
#else
|
||||
_steps = ESteps.LoadFile;
|
||||
_fileLoadPath = MainBundleInfo.Bundle.StreamingFilePath;
|
||||
FileLoadPath = MainBundleInfo.Bundle.StreamingFilePath;
|
||||
#endif
|
||||
}
|
||||
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
|
||||
{
|
||||
_steps = ESteps.LoadFile;
|
||||
_fileLoadPath = MainBundleInfo.Bundle.CachedFilePath;
|
||||
FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -90,6 +89,8 @@ namespace YooAsset
|
||||
// 2. 检测服务器下载结果
|
||||
if (_steps == ESteps.CheckDownload)
|
||||
{
|
||||
DownloadProgress = _downloader.DownloadProgress;
|
||||
DownloadedBytes = _downloader.DownloadedBytes;
|
||||
if (_downloader.IsDone() == false)
|
||||
return;
|
||||
|
||||
@@ -109,7 +110,7 @@ namespace YooAsset
|
||||
if (_steps == ESteps.Unpack)
|
||||
{
|
||||
int failedTryAgain = 1;
|
||||
var bundleInfo = HostPlayModeImpl.ConvertToUnpackInfo(MainBundleInfo.Bundle);
|
||||
var bundleInfo = PatchManifestTools.GetUnpackInfo(MainBundleInfo.Bundle);
|
||||
_unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
|
||||
_steps = ESteps.CheckUnpack;
|
||||
}
|
||||
@@ -117,6 +118,8 @@ namespace YooAsset
|
||||
// 4.检测内置文件解压结果
|
||||
if (_steps == ESteps.CheckUnpack)
|
||||
{
|
||||
DownloadProgress = _unpacker.DownloadProgress;
|
||||
DownloadedBytes = _unpacker.DownloadedBytes;
|
||||
if (_unpacker.IsDone() == false)
|
||||
return;
|
||||
|
||||
@@ -137,24 +140,28 @@ namespace YooAsset
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
// 注意:Unity2017.4编辑器模式下,如果AssetBundle文件不存在会导致编辑器崩溃,这里做了预判。
|
||||
if (System.IO.File.Exists(_fileLoadPath) == false)
|
||||
if (System.IO.File.Exists(FileLoadPath) == false)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EStatus.Failed;
|
||||
LastError = $"Not found assetBundle file : {_fileLoadPath}";
|
||||
LastError = $"Not found assetBundle file : {FileLoadPath}";
|
||||
YooLogger.Error(LastError);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// 设置下载进度
|
||||
DownloadProgress = 1f;
|
||||
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
|
||||
|
||||
// Load assetBundle file
|
||||
var loadMethod = (EBundleLoadMethod)MainBundleInfo.Bundle.LoadMethod;
|
||||
if (loadMethod == EBundleLoadMethod.Normal)
|
||||
{
|
||||
if (_isWaitForAsyncComplete)
|
||||
CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath);
|
||||
CacheBundle = AssetBundle.LoadFromFile(FileLoadPath);
|
||||
else
|
||||
_createRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath);
|
||||
_createRequest = AssetBundle.LoadFromFileAsync(FileLoadPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -169,15 +176,15 @@ namespace YooAsset
|
||||
|
||||
DecryptFileInfo fileInfo = new DecryptFileInfo();
|
||||
fileInfo.BundleName = MainBundleInfo.Bundle.BundleName;
|
||||
fileInfo.FilePath = _fileLoadPath;
|
||||
fileInfo.FilePath = FileLoadPath;
|
||||
|
||||
if (loadMethod == EBundleLoadMethod.LoadFromFileOffset)
|
||||
{
|
||||
ulong offset = Impl.DecryptionServices.LoadFromFileOffset(fileInfo);
|
||||
if (_isWaitForAsyncComplete)
|
||||
CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath, 0, offset);
|
||||
CacheBundle = AssetBundle.LoadFromFile(FileLoadPath, 0, offset);
|
||||
else
|
||||
_createRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath, 0, offset);
|
||||
_createRequest = AssetBundle.LoadFromFileAsync(FileLoadPath, 0, offset);
|
||||
}
|
||||
else if (loadMethod == EBundleLoadMethod.LoadFromMemory)
|
||||
{
|
||||
@@ -235,14 +242,11 @@ namespace YooAsset
|
||||
// 在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性!
|
||||
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
|
||||
{
|
||||
string cacheLoadPath = MainBundleInfo.Bundle.CachedFilePath;
|
||||
if (CacheSystem.VerifyBundle(MainBundleInfo.Bundle, EVerifyLevel.High) != EVerifyResult.Succeed)
|
||||
var result = CacheSystem.VerifyingRecordFile(MainBundleInfo.Bundle.PackageName, MainBundleInfo.Bundle.CacheGUID);
|
||||
if (result != EVerifyResult.Succeed)
|
||||
{
|
||||
if (File.Exists(cacheLoadPath))
|
||||
{
|
||||
YooLogger.Error($"Delete the invalid cache file : {cacheLoadPath}");
|
||||
File.Delete(cacheLoadPath);
|
||||
}
|
||||
YooLogger.Error($"Found possibly corrupt file ! {MainBundleInfo.Bundle.CacheGUID}");
|
||||
CacheSystem.DiscardFile(MainBundleInfo.Bundle.PackageName, MainBundleInfo.Bundle.CacheGUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,6 +283,14 @@ namespace YooAsset
|
||||
int frame = 1000;
|
||||
while (true)
|
||||
{
|
||||
// 文件解压
|
||||
if (_unpacker != null)
|
||||
{
|
||||
_unpacker.Update();
|
||||
if (_unpacker.IsDone() == false)
|
||||
continue;
|
||||
}
|
||||
|
||||
// 保险机制
|
||||
// 注意:如果需要从WEB端下载资源,可能会触发保险机制!
|
||||
frame--;
|
||||
|
||||
@@ -7,7 +7,7 @@ using UnityEngine.Networking;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal sealed class AssetBundleWebLoader : AssetBundleLoaderBase
|
||||
internal sealed class AssetBundleWebLoader : BundleLoaderBase
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
@@ -24,7 +24,6 @@ namespace YooAsset
|
||||
|
||||
private ESteps _steps = ESteps.None;
|
||||
private float _tryTimer = 0;
|
||||
private string _fileLoadPath;
|
||||
private bool _isShowWaitForAsyncError = false;
|
||||
private DownloaderBase _downloader;
|
||||
private UnityWebRequest _webRequest;
|
||||
@@ -48,17 +47,17 @@ namespace YooAsset
|
||||
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
|
||||
{
|
||||
_steps = ESteps.Download;
|
||||
_fileLoadPath = MainBundleInfo.Bundle.CachedFilePath;
|
||||
FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath;
|
||||
}
|
||||
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
|
||||
{
|
||||
_steps = ESteps.LoadWebFile;
|
||||
_fileLoadPath = MainBundleInfo.Bundle.StreamingFilePath;
|
||||
FileLoadPath = MainBundleInfo.Bundle.StreamingFilePath;
|
||||
}
|
||||
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
|
||||
{
|
||||
_steps = ESteps.LoadCacheFile;
|
||||
_fileLoadPath = MainBundleInfo.Bundle.CachedFilePath;
|
||||
FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -77,6 +76,8 @@ namespace YooAsset
|
||||
// 2. 检测服务器下载结果
|
||||
if (_steps == ESteps.CheckDownload)
|
||||
{
|
||||
DownloadProgress = _downloader.DownloadProgress;
|
||||
DownloadedBytes = _downloader.DownloadedBytes;
|
||||
if (_downloader.IsDone() == false)
|
||||
return;
|
||||
|
||||
@@ -97,21 +98,25 @@ namespace YooAsset
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
// 注意:Unity2017.4编辑器模式下,如果AssetBundle文件不存在会导致编辑器崩溃,这里做了预判。
|
||||
if (System.IO.File.Exists(_fileLoadPath) == false)
|
||||
if (System.IO.File.Exists(FileLoadPath) == false)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EStatus.Failed;
|
||||
LastError = $"Not found assetBundle file : {_fileLoadPath}";
|
||||
LastError = $"Not found assetBundle file : {FileLoadPath}";
|
||||
YooLogger.Error(LastError);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// 设置下载进度
|
||||
DownloadProgress = 1f;
|
||||
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
|
||||
|
||||
// Load assetBundle file
|
||||
var loadMethod = (EBundleLoadMethod)MainBundleInfo.Bundle.LoadMethod;
|
||||
if (loadMethod == EBundleLoadMethod.Normal)
|
||||
{
|
||||
_createRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath);
|
||||
_createRequest = AssetBundle.LoadFromFileAsync(FileLoadPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -142,14 +147,11 @@ namespace YooAsset
|
||||
// 在AssetBundle文件加载失败的情况下,我们需要重新验证文件的完整性!
|
||||
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
|
||||
{
|
||||
string cacheLoadPath = MainBundleInfo.Bundle.CachedFilePath;
|
||||
if (CacheSystem.VerifyBundle(MainBundleInfo.Bundle, EVerifyLevel.High) != EVerifyResult.Succeed)
|
||||
var result = CacheSystem.VerifyingRecordFile(MainBundleInfo.Bundle.PackageName, MainBundleInfo.Bundle.CacheGUID);
|
||||
if (result != EVerifyResult.Succeed)
|
||||
{
|
||||
if (File.Exists(cacheLoadPath))
|
||||
{
|
||||
YooLogger.Error($"Delete the invalid cache file : {cacheLoadPath}");
|
||||
File.Delete(cacheLoadPath);
|
||||
}
|
||||
YooLogger.Error($"Found possibly corrupt file ! {MainBundleInfo.Bundle.CacheGUID}");
|
||||
CacheSystem.DiscardFile(MainBundleInfo.Bundle.PackageName, MainBundleInfo.Bundle.CacheGUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,7 +165,8 @@ namespace YooAsset
|
||||
// 5. 从WEB网站获取AssetBundle文件
|
||||
if (_steps == ESteps.LoadWebFile)
|
||||
{
|
||||
_webRequest = UnityWebRequestAssetBundle.GetAssetBundle(_fileLoadPath, Hash128.Parse(MainBundleInfo.Bundle.FileHash));
|
||||
var hash = Hash128.Parse(MainBundleInfo.Bundle.FileHash);
|
||||
_webRequest = UnityWebRequestAssetBundle.GetAssetBundle(FileLoadPath, hash);
|
||||
_webRequest.SendWebRequest();
|
||||
_steps = ESteps.CheckLoadWebFile;
|
||||
}
|
||||
@@ -171,6 +174,8 @@ namespace YooAsset
|
||||
// 6. 检测AssetBundle加载结果
|
||||
if (_steps == ESteps.CheckLoadWebFile)
|
||||
{
|
||||
DownloadProgress = _webRequest.downloadProgress;
|
||||
DownloadedBytes = _webRequest.downloadedBytes;
|
||||
if (_webRequest.isDone == false)
|
||||
return;
|
||||
|
||||
@@ -180,7 +185,7 @@ namespace YooAsset
|
||||
if (_webRequest.isNetworkError || _webRequest.isHttpError)
|
||||
#endif
|
||||
{
|
||||
YooLogger.Warning($"Failed to get asset bundle from web : {_fileLoadPath} Error : {_webRequest.error}");
|
||||
YooLogger.Warning($"Failed to get asset bundle from web : {FileLoadPath} Error : {_webRequest.error}");
|
||||
_steps = ESteps.TryLoadWebFile;
|
||||
_tryTimer = 0;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal abstract class AssetBundleLoaderBase
|
||||
internal abstract class BundleLoaderBase
|
||||
{
|
||||
public enum EStatus
|
||||
{
|
||||
@@ -18,7 +18,7 @@ namespace YooAsset
|
||||
/// 所属资源系统
|
||||
/// </summary>
|
||||
public AssetSystemImpl Impl { private set; get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 资源包文件信息
|
||||
/// </summary>
|
||||
@@ -46,9 +46,12 @@ namespace YooAsset
|
||||
|
||||
private readonly List<ProviderBase> _providers = new List<ProviderBase>(100);
|
||||
internal AssetBundle CacheBundle { set; get; }
|
||||
internal string FileLoadPath { set; get; }
|
||||
internal float DownloadProgress { set; get; }
|
||||
internal ulong DownloadedBytes { set; get; }
|
||||
|
||||
|
||||
public AssetBundleLoaderBase(AssetSystemImpl impl, BundleInfo bundleInfo)
|
||||
public BundleLoaderBase(AssetSystemImpl impl, BundleInfo bundleInfo)
|
||||
{
|
||||
Impl = impl;
|
||||
MainBundleInfo = bundleInfo;
|
||||
@@ -81,34 +84,6 @@ namespace YooAsset
|
||||
RefCount--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 轮询更新
|
||||
/// </summary>
|
||||
public abstract void Update();
|
||||
|
||||
/// <summary>
|
||||
/// 销毁
|
||||
/// </summary>
|
||||
public virtual void Destroy(bool forceDestroy)
|
||||
{
|
||||
IsDestroyed = true;
|
||||
|
||||
// Check fatal
|
||||
if (forceDestroy == false)
|
||||
{
|
||||
if (RefCount > 0)
|
||||
throw new Exception($"Bundle file loader ref is not zero : {MainBundleInfo.Bundle.BundleName}");
|
||||
if (IsDone() == false)
|
||||
throw new Exception($"Bundle file loader is not done : {MainBundleInfo.Bundle.BundleName}");
|
||||
}
|
||||
|
||||
if (CacheBundle != null)
|
||||
{
|
||||
CacheBundle.Unload(true);
|
||||
CacheBundle = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否完毕(无论成功或失败)
|
||||
/// </summary>
|
||||
@@ -158,6 +133,35 @@ namespace YooAsset
|
||||
_providers.Clear();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 轮询更新
|
||||
/// </summary>
|
||||
public abstract void Update();
|
||||
|
||||
/// <summary>
|
||||
/// 销毁
|
||||
/// </summary>
|
||||
public virtual void Destroy(bool forceDestroy)
|
||||
{
|
||||
IsDestroyed = true;
|
||||
|
||||
// Check fatal
|
||||
if (forceDestroy == false)
|
||||
{
|
||||
if (RefCount > 0)
|
||||
throw new Exception($"Bundle file loader ref is not zero : {MainBundleInfo.Bundle.BundleName}");
|
||||
if (IsDone() == false)
|
||||
throw new Exception($"Bundle file loader is not done : {MainBundleInfo.Bundle.BundleName}");
|
||||
}
|
||||
|
||||
if (CacheBundle != null)
|
||||
{
|
||||
CacheBundle.Unload(true);
|
||||
CacheBundle = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 主线程等待异步操作完毕
|
||||
/// </summary>
|
||||
@@ -9,12 +9,12 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 依赖的资源包加载器列表
|
||||
/// </summary>
|
||||
private readonly List<AssetBundleLoaderBase> _dependBundles;
|
||||
internal readonly List<BundleLoaderBase> DependBundles;
|
||||
|
||||
|
||||
public DependAssetBundleGroup(List<AssetBundleLoaderBase> dpendBundles)
|
||||
public DependAssetBundleGroup(List<BundleLoaderBase> dpendBundles)
|
||||
{
|
||||
_dependBundles = dpendBundles;
|
||||
DependBundles = dpendBundles;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -22,7 +22,7 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public bool IsDone()
|
||||
{
|
||||
foreach (var loader in _dependBundles)
|
||||
foreach (var loader in DependBundles)
|
||||
{
|
||||
if (loader.IsDone() == false)
|
||||
return false;
|
||||
@@ -35,9 +35,9 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public bool IsSucceed()
|
||||
{
|
||||
foreach (var loader in _dependBundles)
|
||||
foreach (var loader in DependBundles)
|
||||
{
|
||||
if (loader.Status != AssetBundleLoaderBase.EStatus.Succeed)
|
||||
if (loader.Status != BundleLoaderBase.EStatus.Succeed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -50,9 +50,9 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public string GetLastError()
|
||||
{
|
||||
foreach (var loader in _dependBundles)
|
||||
foreach (var loader in DependBundles)
|
||||
{
|
||||
if (loader.Status != AssetBundleLoaderBase.EStatus.Succeed)
|
||||
if (loader.Status != BundleLoaderBase.EStatus.Succeed)
|
||||
{
|
||||
return loader.LastError;
|
||||
}
|
||||
@@ -65,7 +65,7 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public void WaitForAsyncComplete()
|
||||
{
|
||||
foreach (var loader in _dependBundles)
|
||||
foreach (var loader in DependBundles)
|
||||
{
|
||||
if (loader.IsDone() == false)
|
||||
loader.WaitForAsyncComplete();
|
||||
@@ -77,7 +77,7 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public void Reference()
|
||||
{
|
||||
foreach (var loader in _dependBundles)
|
||||
foreach (var loader in DependBundles)
|
||||
{
|
||||
loader.Reference();
|
||||
}
|
||||
@@ -88,7 +88,7 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public void Release()
|
||||
{
|
||||
foreach (var loader in _dependBundles)
|
||||
foreach (var loader in DependBundles)
|
||||
{
|
||||
loader.Release();
|
||||
}
|
||||
@@ -99,12 +99,12 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
internal void GetBundleDebugInfos(List<DebugBundleInfo> output)
|
||||
{
|
||||
foreach (var loader in _dependBundles)
|
||||
foreach (var loader in DependBundles)
|
||||
{
|
||||
var bundleInfo = new DebugBundleInfo();
|
||||
bundleInfo.BundleName = loader.MainBundleInfo.Bundle.BundleName;
|
||||
bundleInfo.RefCount = loader.RefCount;
|
||||
bundleInfo.Status = (int)loader.Status;
|
||||
bundleInfo.Status = loader.Status.ToString();
|
||||
output.Add(bundleInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
using System.IO;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class RawBundleFileLoader : BundleLoaderBase
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Download,
|
||||
CheckDownload,
|
||||
Unpack,
|
||||
CheckUnpack,
|
||||
CheckFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
private ESteps _steps = ESteps.None;
|
||||
private bool _isShowWaitForAsyncError = false;
|
||||
private DownloaderBase _unpacker;
|
||||
private DownloaderBase _downloader;
|
||||
|
||||
|
||||
public RawBundleFileLoader(AssetSystemImpl impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 轮询更新
|
||||
/// </summary>
|
||||
public override void Update()
|
||||
{
|
||||
if (_steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.None)
|
||||
{
|
||||
if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
|
||||
{
|
||||
_steps = ESteps.Download;
|
||||
FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath;
|
||||
}
|
||||
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
|
||||
{
|
||||
#if UNITY_ANDROID || UNITY_WEBGL
|
||||
_steps = ESteps.Unpack;
|
||||
FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath;
|
||||
#else
|
||||
_steps = ESteps.CheckFile;
|
||||
FileLoadPath = MainBundleInfo.Bundle.StreamingFilePath;
|
||||
#endif
|
||||
}
|
||||
else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
|
||||
{
|
||||
_steps = ESteps.CheckFile;
|
||||
FileLoadPath = MainBundleInfo.Bundle.CachedDataFilePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 下载远端文件
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
int failedTryAgain = int.MaxValue;
|
||||
_downloader = DownloadSystem.BeginDownload(MainBundleInfo, failedTryAgain);
|
||||
_steps = ESteps.CheckDownload;
|
||||
}
|
||||
|
||||
// 2. 检测下载结果
|
||||
if (_steps == ESteps.CheckDownload)
|
||||
{
|
||||
DownloadProgress = _downloader.DownloadProgress;
|
||||
DownloadedBytes = _downloader.DownloadedBytes;
|
||||
if (_downloader.IsDone() == false)
|
||||
return;
|
||||
|
||||
if (_downloader.HasError())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EStatus.Failed;
|
||||
LastError = _downloader.GetLastError();
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.CheckFile;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 解压内置文件
|
||||
if (_steps == ESteps.Unpack)
|
||||
{
|
||||
int failedTryAgain = 1;
|
||||
var bundleInfo = PatchManifestTools.GetUnpackInfo(MainBundleInfo.Bundle);
|
||||
_unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
|
||||
_steps = ESteps.CheckUnpack;
|
||||
}
|
||||
|
||||
// 4. 检测解压结果
|
||||
if (_steps == ESteps.CheckUnpack)
|
||||
{
|
||||
DownloadProgress = _unpacker.DownloadProgress;
|
||||
DownloadedBytes = _unpacker.DownloadedBytes;
|
||||
if (_unpacker.IsDone() == false)
|
||||
return;
|
||||
|
||||
if (_unpacker.HasError())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EStatus.Failed;
|
||||
LastError = _unpacker.GetLastError();
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.CheckFile;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 检测结果
|
||||
if (_steps == ESteps.CheckFile)
|
||||
{
|
||||
// 设置下载进度
|
||||
DownloadProgress = 1f;
|
||||
DownloadedBytes = (ulong)MainBundleInfo.Bundle.FileSize;
|
||||
|
||||
_steps = ESteps.Done;
|
||||
if (File.Exists(FileLoadPath))
|
||||
{
|
||||
Status = EStatus.Succeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = EStatus.Failed;
|
||||
LastError = $"Raw file not found : {FileLoadPath}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 主线程等待异步操作完毕
|
||||
/// </summary>
|
||||
public override void WaitForAsyncComplete()
|
||||
{
|
||||
int frame = 1000;
|
||||
while (true)
|
||||
{
|
||||
// 文件解压
|
||||
if (_unpacker != null)
|
||||
{
|
||||
_unpacker.Update();
|
||||
if (_unpacker.IsDone() == false)
|
||||
continue;
|
||||
}
|
||||
|
||||
// 保险机制
|
||||
// 注意:如果需要从WEB端下载资源,可能会触发保险机制!
|
||||
frame--;
|
||||
if (frame == 0)
|
||||
{
|
||||
if (_isShowWaitForAsyncError == false)
|
||||
{
|
||||
_isShowWaitForAsyncError = true;
|
||||
YooLogger.Error($"WaitForAsyncComplete failed ! Try load bundle : {MainBundleInfo.Bundle.BundleName} from remote with sync load method !");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 驱动流程
|
||||
Update();
|
||||
|
||||
// 完成后退出
|
||||
if (IsDone())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa39f24727abe514093f18787c0c7e27
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -41,7 +41,7 @@ namespace YooAsset
|
||||
|
||||
if (_steps == ESteps.Clone)
|
||||
{
|
||||
if (_handle.IsValid == false)
|
||||
if (_handle.IsValidWithWarning == false)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
|
||||
@@ -1,468 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 原生文件操作
|
||||
/// </summary>
|
||||
public abstract class RawFileOperation : AsyncOperationBase
|
||||
{
|
||||
internal readonly BundleInfo _bundleInfo;
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件的拷贝路径
|
||||
/// </summary>
|
||||
public string CopyPath { private set; get; }
|
||||
|
||||
|
||||
internal RawFileOperation(BundleInfo bundleInfo, string copyPath)
|
||||
{
|
||||
_bundleInfo = bundleInfo;
|
||||
CopyPath = copyPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件的缓存路径
|
||||
/// </summary>
|
||||
public abstract string GetCachePath();
|
||||
|
||||
/// <summary>
|
||||
/// 获取原生文件的二进制数据
|
||||
/// </summary>
|
||||
public byte[] LoadFileData()
|
||||
{
|
||||
string filePath = GetCachePath();
|
||||
if (File.Exists(filePath) == false)
|
||||
return null;
|
||||
return File.ReadAllBytes(filePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取原生文件的文本数据
|
||||
/// </summary>
|
||||
public string LoadFileText()
|
||||
{
|
||||
string filePath = GetCachePath();
|
||||
if (File.Exists(filePath) == false)
|
||||
return string.Empty;
|
||||
return File.ReadAllText(filePath, System.Text.Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发生错误的原生文件操作
|
||||
/// </summary>
|
||||
internal sealed class CompletedRawFileOperation : RawFileOperation
|
||||
{
|
||||
private readonly string _error;
|
||||
internal CompletedRawFileOperation(string error, string copyPath) : base(null, copyPath)
|
||||
{
|
||||
_error = error;
|
||||
}
|
||||
internal override void Start()
|
||||
{
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _error;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件的缓存路径
|
||||
/// </summary>
|
||||
public override string GetCachePath()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑器下模拟运行的原生文件操作
|
||||
/// </summary>
|
||||
internal sealed class EditorPlayModeRawFileOperation : RawFileOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Prepare,
|
||||
CheckAndCopyFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal EditorPlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
|
||||
{
|
||||
}
|
||||
internal override void Start()
|
||||
{
|
||||
_steps = ESteps.Prepare;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
// 1. 准备工作
|
||||
if (_steps == ESteps.Prepare)
|
||||
{
|
||||
if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromEditor)
|
||||
{
|
||||
_steps = ESteps.CheckAndCopyFile;
|
||||
return; // 模拟实现异步操作
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException(_bundleInfo.LoadMode.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 检测并拷贝原生文件
|
||||
if (_steps == ESteps.CheckAndCopyFile)
|
||||
{
|
||||
// 如果不需要保存文件
|
||||
if (string.IsNullOrEmpty(CopyPath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果原生文件已经存在,则将其删除
|
||||
if (File.Exists(CopyPath))
|
||||
{
|
||||
File.Delete(CopyPath);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FileUtility.CreateFileDirectory(CopyPath);
|
||||
File.Copy(GetCachePath(), CopyPath, true);
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = e.Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件的缓存路径
|
||||
/// </summary>
|
||||
public override string GetCachePath()
|
||||
{
|
||||
if (_bundleInfo == null)
|
||||
return string.Empty;
|
||||
return _bundleInfo.EditorAssetPath;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 离线模式的原生文件操作
|
||||
/// </summary>
|
||||
internal sealed class OfflinePlayModeRawFileOperation : RawFileOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Prepare,
|
||||
Unpack,
|
||||
CheckUnpack,
|
||||
CheckAndCopyFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
private ESteps _steps = ESteps.None;
|
||||
private DownloaderBase _unpacker;
|
||||
|
||||
public OfflinePlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
|
||||
{
|
||||
}
|
||||
internal override void Start()
|
||||
{
|
||||
_steps = ESteps.Prepare;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
// 1. 准备工作
|
||||
if (_steps == ESteps.Prepare)
|
||||
{
|
||||
if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.None)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"Bundle info is invalid : {_bundleInfo.Bundle.BundleName}";
|
||||
}
|
||||
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
|
||||
{
|
||||
_steps = ESteps.Unpack;
|
||||
}
|
||||
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
|
||||
{
|
||||
_steps = ESteps.CheckAndCopyFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException(_bundleInfo.LoadMode.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 内置文件解压
|
||||
if (_steps == ESteps.Unpack)
|
||||
{
|
||||
int failedTryAgain = 1;
|
||||
var bundleInfo = HostPlayModeImpl.ConvertToUnpackInfo(_bundleInfo.Bundle);
|
||||
_unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
|
||||
_steps = ESteps.CheckUnpack;
|
||||
}
|
||||
|
||||
// 3. 检测内置文件解压结果
|
||||
if (_steps == ESteps.CheckUnpack)
|
||||
{
|
||||
Progress = _unpacker.DownloadProgress;
|
||||
if (_unpacker.IsDone() == false)
|
||||
return;
|
||||
|
||||
if (_unpacker.HasError())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _unpacker.GetLastError();
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.CheckAndCopyFile;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 检测并拷贝原生文件
|
||||
if (_steps == ESteps.CheckAndCopyFile)
|
||||
{
|
||||
// 如果不需要保存文件
|
||||
if (string.IsNullOrEmpty(CopyPath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果原生文件已经存在,则验证其完整性
|
||||
if (File.Exists(CopyPath))
|
||||
{
|
||||
var verifyResult = CacheSystem.VerifyContentInternal(CopyPath, _bundleInfo.Bundle.FileSize, _bundleInfo.Bundle.FileCRC, EVerifyLevel.High);
|
||||
if (verifyResult == EVerifyResult.Succeed)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Delete(CopyPath);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FileUtility.CreateFileDirectory(CopyPath);
|
||||
File.Copy(GetCachePath(), CopyPath, true);
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = e.Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件的缓存路径
|
||||
/// </summary>
|
||||
public override string GetCachePath()
|
||||
{
|
||||
if (_bundleInfo == null)
|
||||
return string.Empty;
|
||||
return _bundleInfo.Bundle.CachedFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 联机模式的原生文件操作
|
||||
/// </summary>
|
||||
internal sealed class HostPlayModeRawFileOperation : RawFileOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
Prepare,
|
||||
Download,
|
||||
CheckDownload,
|
||||
Unpack,
|
||||
CheckUnpack,
|
||||
CheckAndCopyFile,
|
||||
Done,
|
||||
}
|
||||
|
||||
private ESteps _steps = ESteps.None;
|
||||
private DownloaderBase _unpacker;
|
||||
private DownloaderBase _downloader;
|
||||
|
||||
internal HostPlayModeRawFileOperation(BundleInfo bundleInfo, string copyPath) : base(bundleInfo, copyPath)
|
||||
{
|
||||
}
|
||||
internal override void Start()
|
||||
{
|
||||
_steps = ESteps.Prepare;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
// 1. 准备工作
|
||||
if (_steps == ESteps.Prepare)
|
||||
{
|
||||
if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.None)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = $"Bundle info is invalid : {_bundleInfo.Bundle.BundleName}";
|
||||
}
|
||||
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
|
||||
{
|
||||
_steps = ESteps.Download;
|
||||
}
|
||||
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
|
||||
{
|
||||
_steps = ESteps.Unpack;
|
||||
}
|
||||
else if (_bundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
|
||||
{
|
||||
_steps = ESteps.CheckAndCopyFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.NotImplementedException(_bundleInfo.LoadMode.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 下载远端文件
|
||||
if (_steps == ESteps.Download)
|
||||
{
|
||||
int failedTryAgain = int.MaxValue;
|
||||
_downloader = DownloadSystem.BeginDownload(_bundleInfo, failedTryAgain);
|
||||
_steps = ESteps.CheckDownload;
|
||||
}
|
||||
|
||||
// 3. 检测下载结果
|
||||
if (_steps == ESteps.CheckDownload)
|
||||
{
|
||||
Progress = _downloader.DownloadProgress;
|
||||
if (_downloader.IsDone() == false)
|
||||
return;
|
||||
|
||||
if (_downloader.HasError())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _downloader.GetLastError();
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.CheckAndCopyFile;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 解压内置文件
|
||||
if (_steps == ESteps.Unpack)
|
||||
{
|
||||
int failedTryAgain = 1;
|
||||
var bundleInfo = HostPlayModeImpl.ConvertToUnpackInfo(_bundleInfo.Bundle);
|
||||
_unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
|
||||
_steps = ESteps.CheckUnpack;
|
||||
}
|
||||
|
||||
// 4. 检测解压结果
|
||||
if (_steps == ESteps.CheckUnpack)
|
||||
{
|
||||
Progress = _unpacker.DownloadProgress;
|
||||
if (_unpacker.IsDone() == false)
|
||||
return;
|
||||
|
||||
if (_unpacker.HasError())
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = _unpacker.GetLastError();
|
||||
}
|
||||
else
|
||||
{
|
||||
_steps = ESteps.CheckAndCopyFile;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 检测并拷贝原生文件
|
||||
if (_steps == ESteps.CheckAndCopyFile)
|
||||
{
|
||||
// 如果不需要保存文件
|
||||
if (string.IsNullOrEmpty(CopyPath))
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果原生文件已经存在,则验证其完整性
|
||||
if (File.Exists(CopyPath))
|
||||
{
|
||||
var verifyResult = CacheSystem.VerifyContentInternal(CopyPath, _bundleInfo.Bundle.FileSize, _bundleInfo.Bundle.FileCRC, EVerifyLevel.High);
|
||||
if (verifyResult == EVerifyResult.Succeed)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Delete(CopyPath);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FileUtility.CreateFileDirectory(CopyPath);
|
||||
File.Copy(GetCachePath(), CopyPath, true);
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Failed;
|
||||
Error = e.Message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件的缓存路径
|
||||
/// </summary>
|
||||
public override string GetCachePath()
|
||||
{
|
||||
if (_bundleInfo == null)
|
||||
return string.Empty;
|
||||
return _bundleInfo.Bundle.CachedFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,15 +7,6 @@ namespace YooAsset
|
||||
internal sealed class BundledAssetProvider : BundledProvider
|
||||
{
|
||||
private AssetBundleRequest _cacheRequest;
|
||||
public override float Progress
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_cacheRequest == null)
|
||||
return 0;
|
||||
return _cacheRequest.progress;
|
||||
}
|
||||
}
|
||||
|
||||
public BundledAssetProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
|
||||
{
|
||||
@@ -48,15 +39,15 @@ namespace YooAsset
|
||||
|
||||
if (DependBundleGroup.IsSucceed() == false)
|
||||
{
|
||||
Status = EStatus.Fail;
|
||||
Status = EStatus.Failed;
|
||||
LastError = DependBundleGroup.GetLastError();
|
||||
InvokeCompletion();
|
||||
return;
|
||||
}
|
||||
|
||||
if (OwnerBundle.Status != AssetBundleLoaderBase.EStatus.Succeed)
|
||||
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
|
||||
{
|
||||
Status = EStatus.Fail;
|
||||
Status = EStatus.Failed;
|
||||
LastError = OwnerBundle.LastError;
|
||||
InvokeCompletion();
|
||||
return;
|
||||
@@ -66,7 +57,7 @@ namespace YooAsset
|
||||
{
|
||||
if (OwnerBundle.IsDestroyed)
|
||||
throw new System.Exception("Should never get here !");
|
||||
Status = EStatus.Fail;
|
||||
Status = EStatus.Failed;
|
||||
LastError = $"The bundle {OwnerBundle.MainBundleInfo.Bundle.BundleName} has been destroyed by unity bugs !";
|
||||
YooLogger.Error(LastError);
|
||||
InvokeCompletion();
|
||||
@@ -109,14 +100,15 @@ namespace YooAsset
|
||||
}
|
||||
else
|
||||
{
|
||||
Progress = _cacheRequest.progress;
|
||||
if (_cacheRequest.isDone == false)
|
||||
return;
|
||||
AssetObject = _cacheRequest.asset;
|
||||
}
|
||||
}
|
||||
|
||||
Status = AssetObject == null ? EStatus.Fail : EStatus.Success;
|
||||
if (Status == EStatus.Fail)
|
||||
Status = AssetObject == null ? EStatus.Failed : EStatus.Succeed;
|
||||
if (Status == EStatus.Failed)
|
||||
{
|
||||
if (MainAssetInfo.AssetType == null)
|
||||
LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace YooAsset
|
||||
{
|
||||
internal abstract class BundledProvider : ProviderBase
|
||||
{
|
||||
protected AssetBundleLoaderBase OwnerBundle { private set; get; }
|
||||
protected BundleLoaderBase OwnerBundle { private set; get; }
|
||||
protected DependAssetBundleGroup DependBundleGroup { private set; get; }
|
||||
|
||||
public BundledProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
|
||||
@@ -35,6 +35,23 @@ namespace YooAsset
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取下载报告
|
||||
/// </summary>
|
||||
public override DownloadReport GetDownloadReport()
|
||||
{
|
||||
DownloadReport result = new DownloadReport();
|
||||
result.TotalSize = (ulong)OwnerBundle.MainBundleInfo.Bundle.FileSize;
|
||||
result.DownloadedBytes = OwnerBundle.DownloadedBytes;
|
||||
foreach (var dependBundle in DependBundleGroup.DependBundles)
|
||||
{
|
||||
result.TotalSize += (ulong)dependBundle.MainBundleInfo.Bundle.FileSize;
|
||||
result.DownloadedBytes += dependBundle.DownloadedBytes;
|
||||
}
|
||||
result.Progress = (float)result.DownloadedBytes / result.TotalSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取资源包的调试信息列表
|
||||
/// </summary>
|
||||
@@ -43,7 +60,7 @@ namespace YooAsset
|
||||
var bundleInfo = new DebugBundleInfo();
|
||||
bundleInfo.BundleName = OwnerBundle.MainBundleInfo.Bundle.BundleName;
|
||||
bundleInfo.RefCount = OwnerBundle.RefCount;
|
||||
bundleInfo.Status = (int)OwnerBundle.Status;
|
||||
bundleInfo.Status = OwnerBundle.Status.ToString();
|
||||
output.Add(bundleInfo);
|
||||
|
||||
DependBundleGroup.GetBundleDebugInfos(output);
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class BundledRawFileProvider : BundledProvider
|
||||
{
|
||||
public BundledRawFileProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
|
||||
{
|
||||
}
|
||||
public override void Update()
|
||||
{
|
||||
DebugRecording();
|
||||
|
||||
if (IsDone)
|
||||
return;
|
||||
|
||||
if (Status == EStatus.None)
|
||||
{
|
||||
Status = EStatus.CheckBundle;
|
||||
}
|
||||
|
||||
if (Status == EStatus.CheckBundle)
|
||||
{
|
||||
if (IsWaitForAsyncComplete)
|
||||
{
|
||||
OwnerBundle.WaitForAsyncComplete();
|
||||
}
|
||||
|
||||
if (OwnerBundle.IsDone() == false)
|
||||
return;
|
||||
|
||||
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
|
||||
{
|
||||
Status = EStatus.Failed;
|
||||
LastError = OwnerBundle.LastError;
|
||||
InvokeCompletion();
|
||||
return;
|
||||
}
|
||||
|
||||
Status = EStatus.Checking;
|
||||
}
|
||||
|
||||
if (Status == EStatus.Checking)
|
||||
{
|
||||
RawFilePath = OwnerBundle.FileLoadPath;
|
||||
Status = EStatus.Succeed;
|
||||
InvokeCompletion();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a00889582fd95446b103af1074fa6ba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -13,15 +13,6 @@ namespace YooAsset
|
||||
private readonly bool _activateOnLoad;
|
||||
private readonly int _priority;
|
||||
private AsyncOperation _asyncOp;
|
||||
public override float Progress
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_asyncOp == null)
|
||||
return 0;
|
||||
return _asyncOp.progress;
|
||||
}
|
||||
}
|
||||
|
||||
public BundledSceneProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) : base(impl, providerGUID, assetInfo)
|
||||
{
|
||||
@@ -52,15 +43,15 @@ namespace YooAsset
|
||||
|
||||
if (DependBundleGroup.IsSucceed() == false)
|
||||
{
|
||||
Status = EStatus.Fail;
|
||||
Status = EStatus.Failed;
|
||||
LastError = DependBundleGroup.GetLastError();
|
||||
InvokeCompletion();
|
||||
return;
|
||||
}
|
||||
|
||||
if (OwnerBundle.Status != AssetBundleLoaderBase.EStatus.Succeed)
|
||||
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
|
||||
{
|
||||
Status = EStatus.Fail;
|
||||
Status = EStatus.Failed;
|
||||
LastError = OwnerBundle.LastError;
|
||||
InvokeCompletion();
|
||||
return;
|
||||
@@ -83,7 +74,7 @@ namespace YooAsset
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = EStatus.Fail;
|
||||
Status = EStatus.Failed;
|
||||
LastError = $"Failed to load scene : {_sceneName}";
|
||||
YooLogger.Error(LastError);
|
||||
InvokeCompletion();
|
||||
@@ -93,13 +84,14 @@ namespace YooAsset
|
||||
// 3. 检测加载结果
|
||||
if (Status == EStatus.Checking)
|
||||
{
|
||||
Progress = _asyncOp.progress;
|
||||
if (_asyncOp.isDone)
|
||||
{
|
||||
if (SceneObject.IsValid() && _activateOnLoad)
|
||||
SceneManager.SetActiveScene(SceneObject);
|
||||
|
||||
Status = SceneObject.IsValid() ? EStatus.Success : EStatus.Fail;
|
||||
if (Status == EStatus.Fail)
|
||||
Status = SceneObject.IsValid() ? EStatus.Succeed : EStatus.Failed;
|
||||
if (Status == EStatus.Failed)
|
||||
{
|
||||
LastError = $"The load scene is invalid : {MainAssetInfo.AssetPath}";
|
||||
YooLogger.Error(LastError);
|
||||
|
||||
@@ -7,15 +7,6 @@ namespace YooAsset
|
||||
internal sealed class BundledSubAssetsProvider : BundledProvider
|
||||
{
|
||||
private AssetBundleRequest _cacheRequest;
|
||||
public override float Progress
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_cacheRequest == null)
|
||||
return 0;
|
||||
return _cacheRequest.progress;
|
||||
}
|
||||
}
|
||||
|
||||
public BundledSubAssetsProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
|
||||
{
|
||||
@@ -48,15 +39,15 @@ namespace YooAsset
|
||||
|
||||
if (DependBundleGroup.IsSucceed() == false)
|
||||
{
|
||||
Status = EStatus.Fail;
|
||||
Status = EStatus.Failed;
|
||||
LastError = DependBundleGroup.GetLastError();
|
||||
InvokeCompletion();
|
||||
return;
|
||||
}
|
||||
|
||||
if (OwnerBundle.Status != AssetBundleLoaderBase.EStatus.Succeed)
|
||||
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
|
||||
{
|
||||
Status = EStatus.Fail;
|
||||
Status = EStatus.Failed;
|
||||
LastError = OwnerBundle.LastError;
|
||||
InvokeCompletion();
|
||||
return;
|
||||
@@ -98,14 +89,15 @@ namespace YooAsset
|
||||
}
|
||||
else
|
||||
{
|
||||
Progress = _cacheRequest.progress;
|
||||
if (_cacheRequest.isDone == false)
|
||||
return;
|
||||
AllAssetObjects = _cacheRequest.allAssets;
|
||||
}
|
||||
}
|
||||
|
||||
Status = AllAssetObjects == null ? EStatus.Fail : EStatus.Success;
|
||||
if (Status == EStatus.Fail)
|
||||
Status = AllAssetObjects == null ? EStatus.Failed : EStatus.Succeed;
|
||||
if (Status == EStatus.Failed)
|
||||
{
|
||||
if (MainAssetInfo.AssetType == null)
|
||||
LastError = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
|
||||
|
||||
@@ -3,17 +3,6 @@ namespace YooAsset
|
||||
{
|
||||
internal sealed class CompletedProvider : ProviderBase
|
||||
{
|
||||
public override float Progress
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsDone)
|
||||
return 1f;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public CompletedProvider(AssetInfo assetInfo) : base(null, string.Empty, assetInfo)
|
||||
{
|
||||
}
|
||||
@@ -24,7 +13,7 @@ namespace YooAsset
|
||||
{
|
||||
if (Status == EStatus.None)
|
||||
{
|
||||
Status = EStatus.Fail;
|
||||
Status = EStatus.Failed;
|
||||
LastError = error;
|
||||
InvokeCompletion();
|
||||
}
|
||||
|
||||
@@ -6,17 +6,6 @@ namespace YooAsset
|
||||
{
|
||||
internal sealed class DatabaseAssetProvider : ProviderBase
|
||||
{
|
||||
public override float Progress
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsDone)
|
||||
return 1f;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public DatabaseAssetProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
|
||||
{
|
||||
}
|
||||
@@ -32,7 +21,7 @@ namespace YooAsset
|
||||
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
Status = EStatus.Fail;
|
||||
Status = EStatus.Failed;
|
||||
LastError = $"Not found asset : {MainAssetInfo.AssetPath}";
|
||||
YooLogger.Error(LastError);
|
||||
InvokeCompletion();
|
||||
@@ -59,8 +48,8 @@ namespace YooAsset
|
||||
// 2. 检测加载结果
|
||||
if (Status == EStatus.Checking)
|
||||
{
|
||||
Status = AssetObject == null ? EStatus.Fail : EStatus.Success;
|
||||
if (Status == EStatus.Fail)
|
||||
Status = AssetObject == null ? EStatus.Failed : EStatus.Succeed;
|
||||
if (Status == EStatus.Failed)
|
||||
{
|
||||
if (MainAssetInfo.AssetType == null)
|
||||
LastError = $"Failed to load asset object : {MainAssetInfo.AssetPath} AssetType : null";
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class DatabaseRawFileProvider : ProviderBase
|
||||
{
|
||||
public DatabaseRawFileProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
|
||||
{
|
||||
}
|
||||
public override void Update()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (IsDone)
|
||||
return;
|
||||
|
||||
if (Status == EStatus.None)
|
||||
{
|
||||
// 检测资源文件是否存在
|
||||
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
Status = EStatus.Failed;
|
||||
LastError = $"Not found asset : {MainAssetInfo.AssetPath}";
|
||||
YooLogger.Error(LastError);
|
||||
InvokeCompletion();
|
||||
return;
|
||||
}
|
||||
|
||||
Status = EStatus.Checking;
|
||||
|
||||
// 注意:模拟异步加载效果提前返回
|
||||
if (IsWaitForAsyncComplete == false)
|
||||
return;
|
||||
}
|
||||
|
||||
if(Status == EStatus.Checking)
|
||||
{
|
||||
RawFilePath = MainAssetInfo.AssetPath;
|
||||
Status = EStatus.Succeed;
|
||||
InvokeCompletion();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41d0e9bbc5a3a5b4e8b05d60d40d495a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -9,15 +9,6 @@ namespace YooAsset
|
||||
private readonly bool _activateOnLoad;
|
||||
private readonly int _priority;
|
||||
private AsyncOperation _asyncOp;
|
||||
public override float Progress
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_asyncOp == null)
|
||||
return 0;
|
||||
return _asyncOp.progress;
|
||||
}
|
||||
}
|
||||
|
||||
public DatabaseSceneProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) : base(impl, providerGUID, assetInfo)
|
||||
{
|
||||
@@ -51,7 +42,7 @@ namespace YooAsset
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = EStatus.Fail;
|
||||
Status = EStatus.Failed;
|
||||
LastError = $"Failed to load scene : {MainAssetInfo.AssetPath}";
|
||||
YooLogger.Error(LastError);
|
||||
InvokeCompletion();
|
||||
@@ -61,13 +52,14 @@ namespace YooAsset
|
||||
// 2. 检测加载结果
|
||||
if (Status == EStatus.Checking)
|
||||
{
|
||||
Progress = _asyncOp.progress;
|
||||
if (_asyncOp.isDone)
|
||||
{
|
||||
if (SceneObject.IsValid() && _activateOnLoad)
|
||||
SceneManager.SetActiveScene(SceneObject);
|
||||
|
||||
Status = SceneObject.IsValid() ? EStatus.Success : EStatus.Fail;
|
||||
if (Status == EStatus.Fail)
|
||||
Status = SceneObject.IsValid() ? EStatus.Succeed : EStatus.Failed;
|
||||
if (Status == EStatus.Failed)
|
||||
{
|
||||
LastError = $"The loaded scene is invalid : {MainAssetInfo.AssetPath}";
|
||||
YooLogger.Error(LastError);
|
||||
|
||||
@@ -6,17 +6,6 @@ namespace YooAsset
|
||||
{
|
||||
internal sealed class DatabaseSubAssetsProvider : ProviderBase
|
||||
{
|
||||
public override float Progress
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsDone)
|
||||
return 1f;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public DatabaseSubAssetsProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
|
||||
{
|
||||
}
|
||||
@@ -32,7 +21,7 @@ namespace YooAsset
|
||||
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
Status = EStatus.Fail;
|
||||
Status = EStatus.Failed;
|
||||
LastError = $"Not found asset : {MainAssetInfo.AssetPath}";
|
||||
YooLogger.Error(LastError);
|
||||
InvokeCompletion();
|
||||
@@ -70,8 +59,8 @@ namespace YooAsset
|
||||
// 2. 检测加载结果
|
||||
if (Status == EStatus.Checking)
|
||||
{
|
||||
Status = AllAssetObjects == null ? EStatus.Fail : EStatus.Success;
|
||||
if (Status == EStatus.Fail)
|
||||
Status = AllAssetObjects == null ? EStatus.Failed : EStatus.Succeed;
|
||||
if (Status == EStatus.Failed)
|
||||
{
|
||||
if (MainAssetInfo.AssetType == null)
|
||||
LastError = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null";
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace YooAsset
|
||||
CheckBundle,
|
||||
Loading,
|
||||
Checking,
|
||||
Success,
|
||||
Fail,
|
||||
Succeed,
|
||||
Failed,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -47,6 +47,11 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public UnityEngine.SceneManagement.Scene SceneObject { protected set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 原生文件路径
|
||||
/// </summary>
|
||||
public string RawFilePath { protected set; get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当前的加载状态
|
||||
@@ -58,6 +63,11 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public string LastError { protected set; get; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 加载进度
|
||||
/// </summary>
|
||||
public float Progress { protected set; get; } = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// 引用计数
|
||||
/// </summary>
|
||||
@@ -75,18 +85,7 @@ namespace YooAsset
|
||||
{
|
||||
get
|
||||
{
|
||||
return Status == EStatus.Success || Status == EStatus.Fail;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载进度
|
||||
/// </summary>
|
||||
public virtual float Progress
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
return Status == EStatus.Succeed || Status == EStatus.Failed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +114,14 @@ namespace YooAsset
|
||||
IsDestroyed = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取下载进度
|
||||
/// </summary>
|
||||
public virtual DownloadReport GetDownloadReport()
|
||||
{
|
||||
return DownloadReport.CreateDefaultReport();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否可以销毁
|
||||
/// </summary>
|
||||
@@ -152,6 +159,8 @@ namespace YooAsset
|
||||
handle = new SceneOperationHandle(this);
|
||||
else if (typeof(T) == typeof(SubAssetsOperationHandle))
|
||||
handle = new SubAssetsOperationHandle(this);
|
||||
else if (typeof(T) == typeof(RawFileOperationHandle))
|
||||
handle = new RawFileOperationHandle(this);
|
||||
else
|
||||
throw new System.NotImplementedException();
|
||||
|
||||
@@ -212,6 +221,9 @@ namespace YooAsset
|
||||
private TaskCompletionSource<object> _taskCompletionSource;
|
||||
protected void InvokeCompletion()
|
||||
{
|
||||
// 进度百分百完成
|
||||
Progress = 1f;
|
||||
|
||||
// 注意:创建临时列表是为了防止外部逻辑在回调函数内创建或者释放资源句柄。
|
||||
List<OperationHandleBase> tempers = new List<OperationHandleBase>(_handles);
|
||||
foreach (var hande in tempers)
|
||||
|
||||
@@ -13,10 +13,8 @@ namespace YooAsset
|
||||
private EOperationStatus _initializeStatus = EOperationStatus.None;
|
||||
private EPlayMode _playMode;
|
||||
private IBundleServices _bundleServices;
|
||||
private IPlayModeServices _playModeServices;
|
||||
private AssetSystemImpl _assetSystemImpl;
|
||||
private EditorSimulateModeImpl _editorSimulateModeImpl;
|
||||
private OfflinePlayModeImpl _offlinePlayModeImpl;
|
||||
private HostPlayModeImpl _hostPlayModeImpl;
|
||||
|
||||
/// <summary>
|
||||
/// 包裹名
|
||||
@@ -59,11 +57,8 @@ namespace YooAsset
|
||||
_isInitialize = false;
|
||||
_initializeError = string.Empty;
|
||||
_initializeStatus = EOperationStatus.None;
|
||||
|
||||
_bundleServices = null;
|
||||
_editorSimulateModeImpl = null;
|
||||
_offlinePlayModeImpl = null;
|
||||
_hostPlayModeImpl = null;
|
||||
_playModeServices = null;
|
||||
|
||||
if (_assetSystemImpl != null)
|
||||
{
|
||||
@@ -78,6 +73,9 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public InitializationOperation InitializeAsync(InitializeParameters parameters)
|
||||
{
|
||||
// 注意:WebGL平台因为网络原因可能会初始化失败!
|
||||
ResetInitializeAfterFailed();
|
||||
|
||||
// 检测初始化参数合法性
|
||||
CheckInitializeParameters(parameters);
|
||||
|
||||
@@ -86,36 +84,39 @@ namespace YooAsset
|
||||
_assetSystemImpl = new AssetSystemImpl();
|
||||
if (_playMode == EPlayMode.EditorSimulateMode)
|
||||
{
|
||||
_editorSimulateModeImpl = new EditorSimulateModeImpl();
|
||||
_bundleServices = _editorSimulateModeImpl;
|
||||
_assetSystemImpl.Initialize(true, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices);
|
||||
var editorSimulateModeImpl = new EditorSimulateModeImpl();
|
||||
_bundleServices = editorSimulateModeImpl;
|
||||
_playModeServices = editorSimulateModeImpl;
|
||||
_assetSystemImpl.Initialize(PackageName, true, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices);
|
||||
|
||||
var initializeParameters = parameters as EditorSimulateModeParameters;
|
||||
initializeOperation = _editorSimulateModeImpl.InitializeAsync(
|
||||
initializeParameters.LocationToLower,
|
||||
initializeParameters.SimulatePatchManifestPath);
|
||||
initializeOperation = editorSimulateModeImpl.InitializeAsync(initializeParameters.LocationToLower, initializeParameters.SimulatePatchManifestPath);
|
||||
}
|
||||
else if (_playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
_offlinePlayModeImpl = new OfflinePlayModeImpl();
|
||||
_bundleServices = _offlinePlayModeImpl;
|
||||
_assetSystemImpl.Initialize(false, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices);
|
||||
var offlinePlayModeImpl = new OfflinePlayModeImpl();
|
||||
_bundleServices = offlinePlayModeImpl;
|
||||
_playModeServices = offlinePlayModeImpl;
|
||||
_assetSystemImpl.Initialize(PackageName, false, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices);
|
||||
|
||||
var initializeParameters = parameters as OfflinePlayModeParameters;
|
||||
initializeOperation = _offlinePlayModeImpl.InitializeAsync(
|
||||
initializeParameters.LocationToLower,
|
||||
PackageName);
|
||||
initializeOperation = offlinePlayModeImpl.InitializeAsync(PackageName, initializeParameters.LocationToLower);
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
_hostPlayModeImpl = new HostPlayModeImpl();
|
||||
_bundleServices = _hostPlayModeImpl;
|
||||
_assetSystemImpl.Initialize(false, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices);
|
||||
var hostPlayModeImpl = new HostPlayModeImpl();
|
||||
_bundleServices = hostPlayModeImpl;
|
||||
_playModeServices = hostPlayModeImpl;
|
||||
_assetSystemImpl.Initialize(PackageName, false, parameters.AssetLoadingMaxNumber, parameters.DecryptionServices, _bundleServices);
|
||||
|
||||
var initializeParameters = parameters as HostPlayModeParameters;
|
||||
initializeOperation = _hostPlayModeImpl.InitializeAsync(
|
||||
initializeOperation = hostPlayModeImpl.InitializeAsync(
|
||||
PackageName,
|
||||
initializeParameters.LocationToLower,
|
||||
initializeParameters.DefaultHostServer,
|
||||
initializeParameters.FallbackHostServer,
|
||||
initializeParameters.QueryServices,
|
||||
PackageName);
|
||||
initializeParameters.QueryServices
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -127,6 +128,18 @@ namespace YooAsset
|
||||
initializeOperation.Completed += InitializeOperation_Completed;
|
||||
return initializeOperation;
|
||||
}
|
||||
private void ResetInitializeAfterFailed()
|
||||
{
|
||||
if (_isInitialize && _initializeStatus == EOperationStatus.Failed)
|
||||
{
|
||||
_isInitialize = false;
|
||||
_initializeStatus = EOperationStatus.None;
|
||||
_initializeError = string.Empty;
|
||||
_bundleServices = null;
|
||||
_playModeServices = null;
|
||||
_assetSystemImpl = null;
|
||||
}
|
||||
}
|
||||
private void CheckInitializeParameters(InitializeParameters parameters)
|
||||
{
|
||||
if (_isInitialize)
|
||||
@@ -184,113 +197,58 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 向网络端请求最新的资源版本
|
||||
/// </summary>
|
||||
/// <param name="appendTimeTicks">在URL末尾添加时间戳</param>
|
||||
/// <param name="timeout">超时时间(默认值:60秒)</param>
|
||||
public UpdateStaticVersionOperation UpdateStaticVersionAsync(int timeout = 60)
|
||||
public UpdatePackageVersionOperation UpdatePackageVersionAsync(bool appendTimeTicks = true, int timeout = 60)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
if (_playMode == EPlayMode.EditorSimulateMode)
|
||||
{
|
||||
var operation = new EditorPlayModeUpdateStaticVersionOperation();
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
var operation = new OfflinePlayModeUpdateStaticVersionOperation();
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
return _hostPlayModeImpl.UpdateStaticVersionAsync(PackageName, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return _playModeServices.UpdatePackageVersionAsync(appendTimeTicks, timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向网络端请求并更新补丁清单
|
||||
/// </summary>
|
||||
/// <param name="packageVersion">更新的包裹版本</param>
|
||||
/// <param name="autoActiveManifest">自动激活清单</param>
|
||||
/// <param name="timeout">超时时间(默认值:60秒)</param>
|
||||
public UpdateManifestOperation UpdateManifestAsync(string packageVersion, int timeout = 60)
|
||||
public UpdatePackageManifestOperation UpdatePackageManifestAsync(string packageVersion, int timeout = 60)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
DebugCheckUpdateManifest();
|
||||
if (_playMode == EPlayMode.EditorSimulateMode)
|
||||
{
|
||||
var operation = new EditorPlayModeUpdateManifestOperation();
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
var operation = new OfflinePlayModeUpdateManifestOperation();
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
return _hostPlayModeImpl.UpdatePatchManifestAsync(PackageName, packageVersion, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return _playModeServices.UpdatePackageManifestAsync(packageVersion, timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查本地包裹内容的完整性
|
||||
/// 预下载指定版本的包裹资源
|
||||
/// </summary>
|
||||
public CheckPackageContentsOperation CheckPackageContentsAsync()
|
||||
/// <param name="packageVersion">下载的包裹版本</param>
|
||||
/// <param name="timeout">超时时间(默认值:60秒)</param>
|
||||
public PreDownloadPackageOperation PreDownloadPackageAsync(string packageVersion, int timeout = 60)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
if (_playMode == EPlayMode.EditorSimulateMode)
|
||||
{
|
||||
var operation = new EditorSimulateModeCheckPackageContentsOperation();
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
var operation = new OfflinePlayModeCheckPackageContentsOperation();
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
return _hostPlayModeImpl.CheckPackageContentsAsync(PackageName);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return _playModeServices.PreDownloadPackageAsync(packageVersion, timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取包裹的版本信息
|
||||
/// 清理包裹未使用的缓存文件
|
||||
/// </summary>
|
||||
public ClearUnusedCacheFilesOperation ClearUnusedCacheFilesAsync()
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
var operation = new ClearUnusedCacheFilesOperation(this);
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地包裹的版本信息
|
||||
/// </summary>
|
||||
public string GetPackageVersion()
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
if (_playMode == EPlayMode.EditorSimulateMode)
|
||||
{
|
||||
return _editorSimulateModeImpl.GetPackageVersion();
|
||||
}
|
||||
else if (_playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
return _offlinePlayModeImpl.GetPackageVersion();
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
return _hostPlayModeImpl.GetPackageVersion();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
if (_playModeServices.ActiveManifest == null)
|
||||
return string.Empty;
|
||||
return _playModeServices.ActiveManifest.PackageVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -363,7 +321,7 @@ namespace YooAsset
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
string[] tags = new string[] { tag };
|
||||
return _bundleServices.GetAssetInfos(tags);
|
||||
return _playModeServices.ActiveManifest.GetAssetsInfoByTags(tags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -373,7 +331,7 @@ namespace YooAsset
|
||||
public AssetInfo[] GetAssetInfos(string[] tags)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
return _bundleServices.GetAssetInfos(tags);
|
||||
return _playModeServices.ActiveManifest.GetAssetsInfoByTags(tags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -394,81 +352,70 @@ namespace YooAsset
|
||||
public bool CheckLocationValid(string location)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
string assetPath = _bundleServices.TryMappingToAssetPath(location);
|
||||
string assetPath = _playModeServices.ActiveManifest.TryMappingToAssetPath(location);
|
||||
return string.IsNullOrEmpty(assetPath) == false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 原生文件
|
||||
/// <summary>
|
||||
/// 异步获取原生文件
|
||||
/// 同步加载原生文件
|
||||
/// </summary>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
/// <param name="copyPath">拷贝路径</param>
|
||||
public RawFileOperation GetRawFileAsync(string location, string copyPath = null)
|
||||
/// <param name="assetInfo">资源信息</param>
|
||||
public RawFileOperationHandle LoadRawFileSync(AssetInfo assetInfo)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
|
||||
return GetRawFileInternal(assetInfo, copyPath);
|
||||
return LoadRawFileInternal(assetInfo, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步获取原生文件
|
||||
/// 同步加载原生文件
|
||||
/// </summary>
|
||||
/// <param name="assetInfo">资源信息</param>
|
||||
/// <param name="copyPath">拷贝路径</param>
|
||||
public RawFileOperation GetRawFileAsync(AssetInfo assetInfo, string copyPath = null)
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
public RawFileOperationHandle LoadRawFileSync(string location)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
return GetRawFileInternal(assetInfo, copyPath);
|
||||
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
|
||||
return LoadRawFileInternal(assetInfo, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载原生文件
|
||||
/// </summary>
|
||||
/// <param name="assetInfo">资源信息</param>
|
||||
public RawFileOperationHandle LoadRawFileAsync(AssetInfo assetInfo)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
return LoadRawFileInternal(assetInfo, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载原生文件
|
||||
/// </summary>
|
||||
/// <param name="location">资源的定位地址</param>
|
||||
public RawFileOperationHandle LoadRawFileAsync(string location)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
|
||||
return LoadRawFileInternal(assetInfo, false);
|
||||
}
|
||||
|
||||
|
||||
private RawFileOperation GetRawFileInternal(AssetInfo assetInfo, string copyPath)
|
||||
private RawFileOperationHandle LoadRawFileInternal(AssetInfo assetInfo, bool waitForAsyncComplete)
|
||||
{
|
||||
if (assetInfo.IsInvalid)
|
||||
{
|
||||
YooLogger.Error($"Failed to get raw file. {assetInfo.Error}");
|
||||
RawFileOperation operation = new CompletedRawFileOperation(assetInfo.Error, copyPath);
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
|
||||
BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (bundleInfo.Bundle.IsRawFile == false)
|
||||
if (assetInfo.IsInvalid == false)
|
||||
{
|
||||
string error = $"Cannot load asset bundle file using {nameof(GetRawFileAsync)} method !";
|
||||
YooLogger.Error(error);
|
||||
RawFileOperation operation = new CompletedRawFileOperation(error, copyPath);
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
|
||||
if (bundleInfo.Bundle.IsRawFile == false)
|
||||
throw new Exception($"Cannot load asset bundle file using {nameof(LoadRawFileAsync)} method !");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_playMode == EPlayMode.EditorSimulateMode)
|
||||
{
|
||||
RawFileOperation operation = new EditorPlayModeRawFileOperation(bundleInfo, copyPath);
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
RawFileOperation operation = new OfflinePlayModeRawFileOperation(bundleInfo, copyPath);
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
RawFileOperation operation = new HostPlayModeRawFileOperation(bundleInfo, copyPath);
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
var handle = _assetSystemImpl.LoadRawFileAsync(assetInfo);
|
||||
if (waitForAsyncComplete)
|
||||
handle.WaitForAsyncComplete();
|
||||
return handle;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -581,13 +528,7 @@ namespace YooAsset
|
||||
{
|
||||
BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
|
||||
if (bundleInfo.Bundle.IsRawFile)
|
||||
{
|
||||
string error = $"Cannot load raw file using LoadAsset method !";
|
||||
YooLogger.Error(error);
|
||||
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
|
||||
completedProvider.SetCompleted(error);
|
||||
return completedProvider.CreateHandle<AssetOperationHandle>();
|
||||
}
|
||||
throw new Exception($"Cannot load raw file using {nameof(LoadAssetAsync)} method !");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -676,13 +617,7 @@ namespace YooAsset
|
||||
{
|
||||
BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
|
||||
if (bundleInfo.Bundle.IsRawFile)
|
||||
{
|
||||
string error = $"Cannot load raw file using LoadSubAssets method !";
|
||||
YooLogger.Error(error);
|
||||
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
|
||||
completedProvider.SetCompleted(error);
|
||||
return completedProvider.CreateHandle<SubAssetsOperationHandle>();
|
||||
}
|
||||
throw new Exception($"Cannot load raw file using {nameof(LoadSubAssetsAsync)} method !");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -704,7 +639,7 @@ namespace YooAsset
|
||||
public PatchDownloaderOperation CreatePatchDownloader(string tag, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
return CreatePatchDownloader(new string[] { tag }, downloadingMaxNumber, failedTryAgain, timeout);
|
||||
return _playModeServices.CreatePatchDownloaderByTags(new string[] { tag }, downloadingMaxNumber, failedTryAgain, timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -717,20 +652,7 @@ namespace YooAsset
|
||||
public PatchDownloaderOperation CreatePatchDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
if (_playMode == EPlayMode.EditorSimulateMode || _playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
List<BundleInfo> downloadList = new List<BundleInfo>();
|
||||
var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
return _hostPlayModeImpl.CreatePatchDownloaderByTags(tags, downloadingMaxNumber, failedTryAgain, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return _playModeServices.CreatePatchDownloaderByTags(tags, downloadingMaxNumber, failedTryAgain, timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -742,53 +664,7 @@ namespace YooAsset
|
||||
public PatchDownloaderOperation CreatePatchDownloader(int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
if (_playMode == EPlayMode.EditorSimulateMode || _playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
List<BundleInfo> downloadList = new List<BundleInfo>();
|
||||
var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
return _hostPlayModeImpl.CreatePatchDownloaderByAll(downloadingMaxNumber, failedTryAgain, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 创建补丁下载器,用于下载更新指定的资源列表依赖的资源包文件
|
||||
/// </summary>
|
||||
/// <param name="locations">资源定位列表</param>
|
||||
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
|
||||
/// <param name="failedTryAgain">下载失败的重试次数</param>
|
||||
/// <param name="timeout">超时时间</param>
|
||||
public PatchDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
if (_playMode == EPlayMode.EditorSimulateMode || _playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
List<BundleInfo> downloadList = new List<BundleInfo>();
|
||||
var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
List<AssetInfo> assetInfos = new List<AssetInfo>(locations.Length);
|
||||
foreach (var location in locations)
|
||||
{
|
||||
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
|
||||
assetInfos.Add(assetInfo);
|
||||
}
|
||||
return _hostPlayModeImpl.CreatePatchDownloaderByPaths(assetInfos.ToArray(), downloadingMaxNumber, failedTryAgain, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return _playModeServices.CreatePatchDownloaderByAll(downloadingMaxNumber, failedTryAgain, timeout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -801,20 +677,7 @@ namespace YooAsset
|
||||
public PatchDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain, int timeout = 60)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
if (_playMode == EPlayMode.EditorSimulateMode || _playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
List<BundleInfo> downloadList = new List<BundleInfo>();
|
||||
var operation = new PatchDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain, timeout);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
return _hostPlayModeImpl.CreatePatchDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return _playModeServices.CreatePatchDownloaderByPaths(assetInfos, downloadingMaxNumber, failedTryAgain, timeout);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -828,7 +691,7 @@ namespace YooAsset
|
||||
public PatchUnpackerOperation CreatePatchUnpacker(string tag, int unpackingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
return CreatePatchUnpacker(new string[] { tag }, unpackingMaxNumber, failedTryAgain);
|
||||
return _playModeServices.CreatePatchUnpackerByTags(new string[] { tag }, unpackingMaxNumber, failedTryAgain, int.MaxValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -840,26 +703,7 @@ namespace YooAsset
|
||||
public PatchUnpackerOperation CreatePatchUnpacker(string[] tags, int unpackingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
if (_playMode == EPlayMode.EditorSimulateMode)
|
||||
{
|
||||
List<BundleInfo> downloadList = new List<BundleInfo>();
|
||||
var operation = new PatchUnpackerOperation(downloadList, unpackingMaxNumber, failedTryAgain, int.MaxValue);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
List<BundleInfo> downloadList = new List<BundleInfo>();
|
||||
var operation = new PatchUnpackerOperation(downloadList, unpackingMaxNumber, failedTryAgain, int.MaxValue);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
return _hostPlayModeImpl.CreatePatchUnpackerByTags(tags, unpackingMaxNumber, failedTryAgain, int.MaxValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return _playModeServices.CreatePatchUnpackerByTags(tags, unpackingMaxNumber, failedTryAgain, int.MaxValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -870,58 +714,7 @@ namespace YooAsset
|
||||
public PatchUnpackerOperation CreatePatchUnpacker(int unpackingMaxNumber, int failedTryAgain)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
if (_playMode == EPlayMode.EditorSimulateMode)
|
||||
{
|
||||
List<BundleInfo> downloadList = new List<BundleInfo>();
|
||||
var operation = new PatchUnpackerOperation(downloadList, unpackingMaxNumber, failedTryAgain, int.MaxValue);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
List<BundleInfo> downloadList = new List<BundleInfo>();
|
||||
var operation = new PatchUnpackerOperation(downloadList, unpackingMaxNumber, failedTryAgain, int.MaxValue);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
return _hostPlayModeImpl.CreatePatchUnpackerByAll(unpackingMaxNumber, failedTryAgain, int.MaxValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 包裹更新
|
||||
/// <summary>
|
||||
/// 创建资源包裹下载器,用于下载更新指定资源版本所有的资源包文件
|
||||
/// </summary>
|
||||
/// <param name="packageVersion">指定更新的包裹版本</param>
|
||||
/// <param name="timeout">超时时间</param>
|
||||
public UpdatePackageOperation UpdatePackageAsync(string packageVersion, int timeout = 60)
|
||||
{
|
||||
DebugCheckInitialize();
|
||||
if (_playMode == EPlayMode.EditorSimulateMode)
|
||||
{
|
||||
var operation = new EditorPlayModeUpdatePackageOperation();
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
var operation = new OfflinePlayModeUpdatePackageOperation();
|
||||
OperationSystem.StartOperation(operation);
|
||||
return operation;
|
||||
}
|
||||
else if (_playMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
return _hostPlayModeImpl.UpdatePackageAsync(PackageName, packageVersion, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return _playModeServices.CreatePatchUnpackerByAll(unpackingMaxNumber, failedTryAgain, int.MaxValue);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -929,12 +722,20 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 是否包含资源文件
|
||||
/// </summary>
|
||||
internal bool IsIncludeBundleFile(string fileName)
|
||||
internal bool IsIncludeBundleFile(string cacheGUID)
|
||||
{
|
||||
// NOTE : 编辑器模拟模式下始终返回TRUE
|
||||
if (_playMode == EPlayMode.EditorSimulateMode)
|
||||
return true;
|
||||
return _bundleServices.IsIncludeBundleFile(fileName);
|
||||
return _playModeServices.ActiveManifest.IsIncludeBundleFile(cacheGUID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 资源定位地址转换为资源信息类
|
||||
/// </summary>
|
||||
private AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType)
|
||||
{
|
||||
return _playModeServices.ActiveManifest.ConvertLocationToAssetInfo(location, assetType);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -948,24 +749,6 @@ namespace YooAsset
|
||||
throw new Exception($"Package initialize failed ! {_initializeError}");
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void DebugCheckLocation(string location)
|
||||
{
|
||||
if (string.IsNullOrEmpty(location) == false)
|
||||
{
|
||||
// 检查路径末尾是否有空格
|
||||
int index = location.LastIndexOf(" ");
|
||||
if (index != -1)
|
||||
{
|
||||
if (location.Length == index + 1)
|
||||
YooLogger.Warning($"Found blank character in location : \"{location}\"");
|
||||
}
|
||||
|
||||
if (location.IndexOfAny(System.IO.Path.GetInvalidPathChars()) >= 0)
|
||||
YooLogger.Warning($"Found illegal character in location : \"{location}\"");
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
private void DebugCheckUpdateManifest()
|
||||
{
|
||||
@@ -986,33 +769,5 @@ namespace YooAsset
|
||||
return data;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 私有方法
|
||||
/// <summary>
|
||||
/// 资源定位地址转换为资源信息类,失败时内部会发出错误日志。
|
||||
/// </summary>
|
||||
/// <returns>如果转换失败会返回一个无效的资源信息类</returns>
|
||||
private AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType)
|
||||
{
|
||||
DebugCheckLocation(location);
|
||||
string assetPath = _bundleServices.MappingToAssetPath(location);
|
||||
PatchAsset patchAsset = _bundleServices.TryGetPatchAsset(assetPath);
|
||||
if (patchAsset != null)
|
||||
{
|
||||
AssetInfo assetInfo = new AssetInfo(patchAsset, assetType);
|
||||
return assetInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
string error;
|
||||
if (string.IsNullOrEmpty(location))
|
||||
error = $"The location is null or empty !";
|
||||
else
|
||||
error = $"The location is invalid : {location}";
|
||||
AssetInfo assetInfo = new AssetInfo(error);
|
||||
return assetInfo;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
36
Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs
Normal file
36
Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class CacheFileInfo
|
||||
{
|
||||
private static readonly BufferWriter SharedBuffer = new BufferWriter(1024);
|
||||
|
||||
/// <summary>
|
||||
/// 写入资源包信息
|
||||
/// </summary>
|
||||
public static void WriteInfoToFile(string filePath, string dataFileCRC, long dataFileSize)
|
||||
{
|
||||
using (FileStream fs = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
SharedBuffer.Clear();
|
||||
SharedBuffer.WriteUTF8(dataFileCRC);
|
||||
SharedBuffer.WriteInt64(dataFileSize);
|
||||
SharedBuffer.WriteToStream(fs);
|
||||
fs.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取资源包信息
|
||||
/// </summary>
|
||||
public static void ReadInfoFromFile(string filePath, out string dataFileCRC, out long dataFileSize)
|
||||
{
|
||||
byte[] binaryData = FileUtility.ReadAllBytes(filePath);
|
||||
BufferReader buffer = new BufferReader(binaryData);
|
||||
dataFileCRC = buffer.ReadUTF8();
|
||||
dataFileSize = buffer.ReadInt64();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta
Normal file
11
Assets/YooAsset/Runtime/CacheSystem/CacheFileInfo.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4a97c06e069c1146a881fcb359f9b4b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -2,20 +2,19 @@
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal static class CacheSystem
|
||||
{
|
||||
private readonly static Dictionary<string, PatchBundle> _cachedDic = new Dictionary<string, PatchBundle>(1000);
|
||||
private readonly static Dictionary<string, PackageCache> _cachedDic = new Dictionary<string, PackageCache>(1000);
|
||||
|
||||
/// <summary>
|
||||
/// 初始化时的验证级别
|
||||
/// </summary>
|
||||
public static EVerifyLevel InitVerifyLevel { set; get; } = EVerifyLevel.Low;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 清空所有数据
|
||||
/// </summary>
|
||||
@@ -26,73 +25,116 @@ namespace YooAsset
|
||||
|
||||
/// <summary>
|
||||
/// 查询是否为验证文件
|
||||
/// 注意:被收录的文件完整性是绝对有效的
|
||||
/// </summary>
|
||||
public static bool IsCached(PatchBundle patchBundle)
|
||||
public static bool IsCached(string packageName, string cacheGUID)
|
||||
{
|
||||
string fileHash = patchBundle.FileHash;
|
||||
if (_cachedDic.ContainsKey(fileHash))
|
||||
var cache = GetOrCreateCache(packageName);
|
||||
return cache.IsCached(cacheGUID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 录入验证的文件
|
||||
/// </summary>
|
||||
public static void RecordFile(string packageName, string cacheGUID, PackageCache.RecordWrapper wrapper)
|
||||
{
|
||||
var cache = GetOrCreateCache(packageName);
|
||||
cache.Record(cacheGUID, wrapper);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 丢弃验证的文件(同时删除文件)
|
||||
/// </summary>
|
||||
public static void DiscardFile(string packageName, string cacheGUID)
|
||||
{
|
||||
var cache = GetOrCreateCache(packageName);
|
||||
var wrapper = cache.TryGetWrapper(cacheGUID);
|
||||
if (wrapper == null)
|
||||
return;
|
||||
|
||||
cache.Discard(cacheGUID);
|
||||
|
||||
try
|
||||
{
|
||||
string filePath = patchBundle.CachedFilePath;
|
||||
if (File.Exists(filePath))
|
||||
string dataFilePath = wrapper.DataFilePath;
|
||||
FileInfo fileInfo = new FileInfo(dataFilePath);
|
||||
if (fileInfo.Exists)
|
||||
fileInfo.Directory.Delete(true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
YooLogger.Error($"Failed to delete cache file ! {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证缓存文件(子线程内操作)
|
||||
/// </summary>
|
||||
public static EVerifyResult VerifyingCacheFile(VerifyElement element, EVerifyLevel verifyLevel)
|
||||
{
|
||||
try
|
||||
{
|
||||
string infoFilePath = element.InfoFilePath;
|
||||
if (File.Exists(infoFilePath) == false)
|
||||
return EVerifyResult.InfoFileNotExisted;
|
||||
|
||||
// 解析信息文件获取验证数据
|
||||
CacheFileInfo.ReadInfoFromFile(infoFilePath, out element.DataFileCRC, out element.DataFileSize);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return EVerifyResult.Exception;
|
||||
}
|
||||
|
||||
return VerifyingInternal(element.DataFilePath, element.DataFileSize, element.DataFileCRC, verifyLevel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证下载文件
|
||||
/// </summary>
|
||||
public static EVerifyResult VerifyingTempFile(PatchBundle patchBundle, EVerifyLevel verifyLevel)
|
||||
{
|
||||
return VerifyingInternal(patchBundle.TempDataFilePath, patchBundle.FileSize, patchBundle.FileCRC, verifyLevel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证记录文件
|
||||
/// </summary>
|
||||
public static EVerifyResult VerifyingRecordFile(string packageName, string cacheGUID)
|
||||
{
|
||||
var cache = GetOrCreateCache(packageName);
|
||||
var wrapper = cache.TryGetWrapper(cacheGUID);
|
||||
if (wrapper == null)
|
||||
return EVerifyResult.CacheNotFound;
|
||||
|
||||
EVerifyResult result = VerifyingInternal(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EVerifyLevel.High);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取未被使用的缓存文件
|
||||
/// </summary>
|
||||
public static List<string> GetUnusedCacheGUIDs(AssetsPackage package)
|
||||
{
|
||||
var cache = GetOrCreateCache(package.PackageName);
|
||||
var keys = cache.GetAllKeys();
|
||||
List<string> result = new List<string>(keys.Count);
|
||||
foreach (var cacheGUID in keys)
|
||||
{
|
||||
if (package.IsIncludeBundleFile(cacheGUID) == false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cachedDic.Remove(fileHash);
|
||||
YooLogger.Error($"Cache file is missing : {filePath}");
|
||||
return false;
|
||||
result.Add(cacheGUID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缓存补丁包文件
|
||||
/// </summary>
|
||||
public static void CacheBundle(PatchBundle patchBundle)
|
||||
{
|
||||
string fileHash = patchBundle.FileHash;
|
||||
if (_cachedDic.ContainsKey(fileHash) == false)
|
||||
{
|
||||
string filePath = patchBundle.CachedFilePath;
|
||||
YooLogger.Log($"Cache verify file : {filePath}");
|
||||
_cachedDic.Add(fileHash, patchBundle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证补丁包文件
|
||||
/// </summary>
|
||||
public static EVerifyResult VerifyBundle(PatchBundle patchBundle, EVerifyLevel verifyLevel)
|
||||
{
|
||||
return VerifyContentInternal(patchBundle.CachedFilePath, patchBundle.FileSize, patchBundle.FileCRC, verifyLevel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证并缓存补丁包文件
|
||||
/// </summary>
|
||||
public static EVerifyResult VerifyAndCacheBundle(PatchBundle patchBundle, EVerifyLevel verifyLevel)
|
||||
{
|
||||
var verifyResult = VerifyContentInternal(patchBundle.CachedFilePath, patchBundle.FileSize, patchBundle.FileCRC, verifyLevel);
|
||||
if (verifyResult == EVerifyResult.Succeed)
|
||||
CacheBundle(patchBundle);
|
||||
return verifyResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证文件完整性
|
||||
/// </summary>
|
||||
public static EVerifyResult VerifyContentInternal(string filePath, long fileSize, string fileCRC, EVerifyLevel verifyLevel)
|
||||
private static EVerifyResult VerifyingInternal(string filePath, long fileSize, string fileCRC, EVerifyLevel verifyLevel)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(filePath) == false)
|
||||
return EVerifyResult.FileNotExisted;
|
||||
return EVerifyResult.DataFileNotExisted;
|
||||
|
||||
// 先验证文件大小
|
||||
long size = FileUtility.GetFileSize(filePath);
|
||||
@@ -120,5 +162,14 @@ namespace YooAsset
|
||||
return EVerifyResult.Exception;
|
||||
}
|
||||
}
|
||||
private static PackageCache GetOrCreateCache(string packageName)
|
||||
{
|
||||
if (_cachedDic.TryGetValue(packageName, out PackageCache cache) == false)
|
||||
{
|
||||
cache = new PackageCache(packageName);
|
||||
_cachedDic.Add(packageName, cache);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 本地缓存文件验证器
|
||||
/// </summary>
|
||||
internal abstract class CacheVerifier
|
||||
{
|
||||
public abstract void InitVerifier(List<VerifyInfo> verifyInfos);
|
||||
public abstract bool UpdateVerifier();
|
||||
public abstract float GetVerifierProgress();
|
||||
|
||||
public List<VerifyInfo> VerifySuccessList { protected set; get; }
|
||||
public List<VerifyInfo> VerifyFailList { protected set; get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 本地缓存文件验证器(线程版)
|
||||
/// </summary>
|
||||
internal class CacheVerifierWithThread : CacheVerifier
|
||||
{
|
||||
private readonly ThreadSyncContext _syncContext = new ThreadSyncContext();
|
||||
private readonly List<VerifyInfo> _waitingList = new List<VerifyInfo>(1000);
|
||||
private readonly List<VerifyInfo> _verifyingList = new List<VerifyInfo>(100);
|
||||
private int _verifyMaxNum;
|
||||
private int _verifyTotalCount;
|
||||
|
||||
public override void InitVerifier(List<VerifyInfo> verifyInfos)
|
||||
{
|
||||
_waitingList.AddRange(verifyInfos);
|
||||
VerifySuccessList = new List<VerifyInfo>(verifyInfos.Count);
|
||||
VerifyFailList = new List<VerifyInfo>(verifyInfos.Count);
|
||||
|
||||
// 设置同时验证的最大数
|
||||
ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads);
|
||||
YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}");
|
||||
_verifyMaxNum = Math.Min(workerThreads, ioThreads);
|
||||
_verifyTotalCount = _waitingList.Count;
|
||||
if (_verifyMaxNum < 1)
|
||||
_verifyMaxNum = 1;
|
||||
}
|
||||
public override bool UpdateVerifier()
|
||||
{
|
||||
_syncContext.Update();
|
||||
|
||||
if (_waitingList.Count == 0 && _verifyingList.Count == 0)
|
||||
return true;
|
||||
|
||||
if (_verifyingList.Count >= _verifyMaxNum)
|
||||
return false;
|
||||
|
||||
for (int i = _waitingList.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (_verifyingList.Count >= _verifyMaxNum)
|
||||
break;
|
||||
|
||||
var verifyIno = _waitingList[i];
|
||||
if (VerifyFileWithThread(verifyIno))
|
||||
{
|
||||
_waitingList.RemoveAt(i);
|
||||
_verifyingList.Add(verifyIno);
|
||||
}
|
||||
else
|
||||
{
|
||||
YooLogger.Warning("The thread pool is failed queued.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public override float GetVerifierProgress()
|
||||
{
|
||||
if (_verifyTotalCount == 0)
|
||||
return 1f;
|
||||
return (float)(VerifySuccessList.Count + VerifyFailList.Count) / _verifyTotalCount;
|
||||
}
|
||||
|
||||
private bool VerifyFileWithThread(VerifyInfo verifyInfo)
|
||||
{
|
||||
return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), verifyInfo);
|
||||
}
|
||||
private void VerifyInThread(object infoObj)
|
||||
{
|
||||
VerifyInfo verifyInfo = (VerifyInfo)infoObj;
|
||||
verifyInfo.Result = CacheSystem.VerifyBundle(verifyInfo.VerifyBundle, CacheSystem.InitVerifyLevel);
|
||||
_syncContext.Post(VerifyCallback, verifyInfo);
|
||||
}
|
||||
private void VerifyCallback(object obj)
|
||||
{
|
||||
VerifyInfo verifyIno = (VerifyInfo)obj;
|
||||
if (verifyIno.Result == EVerifyResult.Succeed)
|
||||
{
|
||||
VerifySuccessList.Add(verifyIno);
|
||||
CacheSystem.CacheBundle(verifyIno.VerifyBundle);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyFailList.Add(verifyIno);
|
||||
|
||||
// NOTE:不期望删除断点续传的资源文件
|
||||
/*
|
||||
if (File.Exists(patchBundle.CachedBundleFilePath))
|
||||
File.Delete(patchBundle.CachedBundleFilePath);
|
||||
*/
|
||||
}
|
||||
_verifyingList.Remove(verifyIno);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 本地缓存文件验证器(非线程版)
|
||||
/// </summary>
|
||||
internal class CacheVerifierWithoutThread : CacheVerifier
|
||||
{
|
||||
private readonly List<VerifyInfo> _waitingList = new List<VerifyInfo>(1000);
|
||||
private readonly List<VerifyInfo> _verifyingList = new List<VerifyInfo>(100);
|
||||
private int _verifyMaxNum;
|
||||
private int _verifyTotalCount;
|
||||
|
||||
public override void InitVerifier(List<VerifyInfo> verifyInfos)
|
||||
{
|
||||
_waitingList.AddRange(verifyInfos);
|
||||
VerifySuccessList = new List<VerifyInfo>(verifyInfos.Count);
|
||||
VerifyFailList = new List<VerifyInfo>(verifyInfos.Count);
|
||||
|
||||
// 设置同时验证的最大数
|
||||
_verifyMaxNum = 32;
|
||||
_verifyTotalCount = _waitingList.Count;
|
||||
}
|
||||
public override bool UpdateVerifier()
|
||||
{
|
||||
if (_waitingList.Count == 0 && _verifyingList.Count == 0)
|
||||
return true;
|
||||
|
||||
for (int i = _waitingList.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (_verifyingList.Count >= _verifyMaxNum)
|
||||
break;
|
||||
|
||||
var verifyIno = _waitingList[i];
|
||||
VerifyFileWithoutThread(verifyIno);
|
||||
_waitingList.RemoveAt(i);
|
||||
_verifyingList.Add(verifyIno);
|
||||
}
|
||||
|
||||
_verifyingList.Clear();
|
||||
return false;
|
||||
}
|
||||
public override float GetVerifierProgress()
|
||||
{
|
||||
if (_verifyTotalCount == 0)
|
||||
return 1f;
|
||||
return (float)(VerifySuccessList.Count + VerifyFailList.Count) / _verifyTotalCount;
|
||||
}
|
||||
|
||||
private void VerifyFileWithoutThread(VerifyInfo verifyIno)
|
||||
{
|
||||
var verifyResult = CacheSystem.VerifyAndCacheBundle(verifyIno.VerifyBundle, CacheSystem.InitVerifyLevel);
|
||||
if (verifyResult == EVerifyResult.Succeed)
|
||||
{
|
||||
VerifySuccessList.Add(verifyIno);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyFailList.Add(verifyIno);
|
||||
|
||||
// NOTE:不期望删除断点续传的资源文件
|
||||
/*
|
||||
if (File.Exists(patchBundle.CachedBundleFilePath))
|
||||
File.Delete(patchBundle.CachedBundleFilePath);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,19 @@ namespace YooAsset
|
||||
internal enum EVerifyResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件不存在
|
||||
/// 未找到缓存信息
|
||||
/// </summary>
|
||||
FileNotExisted = -4,
|
||||
CacheNotFound = -6,
|
||||
|
||||
/// <summary>
|
||||
/// 信息文件不存在
|
||||
/// </summary>
|
||||
InfoFileNotExisted = -5,
|
||||
|
||||
/// <summary>
|
||||
/// 数据文件不存在
|
||||
/// </summary>
|
||||
DataFileNotExisted = -4,
|
||||
|
||||
/// <summary>
|
||||
/// 文件内容不足(小于正常大小)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec6bf912e76d0e84d8c58b9da0b020ce
|
||||
guid: d29a9623b2b346e439b7a7e37fafa781
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 清理本地包裹未使用的缓存文件
|
||||
/// </summary>
|
||||
public sealed class ClearUnusedCacheFilesOperation : AsyncOperationBase
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
GetUnusedCacheFiles,
|
||||
ClearUnusedCacheFiles,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly AssetsPackage _package;
|
||||
private List<string> _unusedCacheGUIDs;
|
||||
private int _unusedFileTotalCount = 0;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
internal ClearUnusedCacheFilesOperation(AssetsPackage package)
|
||||
{
|
||||
_package = package;
|
||||
}
|
||||
internal override void Start()
|
||||
{
|
||||
_steps = ESteps.GetUnusedCacheFiles;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.GetUnusedCacheFiles)
|
||||
{
|
||||
_unusedCacheGUIDs = CacheSystem.GetUnusedCacheGUIDs(_package);
|
||||
_unusedFileTotalCount = _unusedCacheGUIDs.Count;
|
||||
YooLogger.Log($"Found unused cache file count : {_unusedFileTotalCount}");
|
||||
_steps = ESteps.ClearUnusedCacheFiles;
|
||||
}
|
||||
|
||||
if (_steps == ESteps.ClearUnusedCacheFiles)
|
||||
{
|
||||
for (int i = _unusedCacheGUIDs.Count - 1; i >= 0; i--)
|
||||
{
|
||||
string cacheGUID = _unusedCacheGUIDs[i];
|
||||
CacheSystem.DiscardFile(_package.PackageName, cacheGUID);
|
||||
_unusedCacheGUIDs.RemoveAt(i);
|
||||
|
||||
if (OperationSystem.IsBusy)
|
||||
break;
|
||||
}
|
||||
|
||||
if (_unusedFileTotalCount == 0)
|
||||
Progress = 1.0f;
|
||||
else
|
||||
Progress = 1.0f - (_unusedCacheGUIDs.Count / _unusedFileTotalCount);
|
||||
|
||||
if (_unusedCacheGUIDs.Count == 0)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class PackageCachingOperation : AsyncOperationBase
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
GetCacheFiles,
|
||||
VerifyCacheFiles,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly string _packageName;
|
||||
private PackageVerifyOperation _packageVerifyOp;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
public PackageCachingOperation(string packageName)
|
||||
{
|
||||
_packageName = packageName;
|
||||
}
|
||||
internal override void Start()
|
||||
{
|
||||
_steps = ESteps.GetCacheFiles;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.GetCacheFiles)
|
||||
{
|
||||
var elements = GetVerifyElements();
|
||||
_packageVerifyOp = PackageVerifyOperation.CreateOperation(elements);
|
||||
OperationSystem.StartOperation(_packageVerifyOp);
|
||||
_steps = ESteps.VerifyCacheFiles;
|
||||
}
|
||||
|
||||
if (_steps == ESteps.VerifyCacheFiles)
|
||||
{
|
||||
Progress = _packageVerifyOp.Progress;
|
||||
if (_packageVerifyOp.IsDone == false)
|
||||
return;
|
||||
|
||||
// 注意:总是返回成功
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
}
|
||||
}
|
||||
|
||||
private List<VerifyElement> GetVerifyElements()
|
||||
{
|
||||
string cacheFolderPath = PersistentHelper.GetCacheFolderPath(_packageName);
|
||||
if (Directory.Exists(cacheFolderPath) == false)
|
||||
return new List<VerifyElement>();
|
||||
|
||||
DirectoryInfo rootDirectory = new DirectoryInfo(cacheFolderPath);
|
||||
DirectoryInfo[] fileFolders = rootDirectory.GetDirectories();
|
||||
List<VerifyElement> result = new List<VerifyElement>(fileFolders.Length);
|
||||
foreach (var fileFoder in fileFolders)
|
||||
{
|
||||
string cacheGUID = fileFoder.Name;
|
||||
if (CacheSystem.IsCached(_packageName, cacheGUID))
|
||||
continue;
|
||||
|
||||
string fileRootPath = fileFoder.FullName;
|
||||
string dataFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleDataFileName}";
|
||||
string infoFilePath = $"{fileRootPath}/{ YooAssetSettings.CacheBundleInfoFileName}";
|
||||
VerifyElement element = new VerifyElement(_packageName, cacheGUID, fileRootPath, dataFilePath, infoFilePath);
|
||||
result.Add(element);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ff95e7516dbfa148b4fe16eaab783fb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,258 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal abstract class PackageVerifyOperation : AsyncOperationBase
|
||||
{
|
||||
public static PackageVerifyOperation CreateOperation(List<VerifyElement> elements)
|
||||
{
|
||||
#if UNITY_WEBGL
|
||||
var operation = new PackageVerifyWithoutThreadOperation(elements);
|
||||
#else
|
||||
var operation = new PackageVerifyWithThreadOperation(elements);
|
||||
#endif
|
||||
return operation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 本地缓存文件验证(线程版)
|
||||
/// </summary>
|
||||
internal class PackageVerifyWithThreadOperation : PackageVerifyOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
InitVerify,
|
||||
UpdateVerify,
|
||||
Done,
|
||||
}
|
||||
|
||||
private readonly ThreadSyncContext _syncContext = new ThreadSyncContext();
|
||||
private List<VerifyElement> _waitingList;
|
||||
private List<VerifyElement> _verifyingList;
|
||||
private int _verifyMaxNum;
|
||||
private int _verifyTotalCount;
|
||||
private float _verifyStartTime;
|
||||
private int _succeedCount;
|
||||
private int _failedCount;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
public PackageVerifyWithThreadOperation(List<VerifyElement> elements)
|
||||
{
|
||||
_waitingList = elements;
|
||||
}
|
||||
internal override void Start()
|
||||
{
|
||||
_steps = ESteps.InitVerify;
|
||||
_verifyStartTime = UnityEngine.Time.realtimeSinceStartup;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.InitVerify)
|
||||
{
|
||||
int fileCount = _waitingList.Count;
|
||||
|
||||
// 设置同时验证的最大数
|
||||
ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads);
|
||||
YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}");
|
||||
_verifyMaxNum = Math.Min(workerThreads, ioThreads);
|
||||
_verifyTotalCount = fileCount;
|
||||
if (_verifyMaxNum < 1)
|
||||
_verifyMaxNum = 1;
|
||||
|
||||
_verifyingList = new List<VerifyElement>(_verifyMaxNum);
|
||||
_steps = ESteps.UpdateVerify;
|
||||
}
|
||||
|
||||
if (_steps == ESteps.UpdateVerify)
|
||||
{
|
||||
_syncContext.Update();
|
||||
|
||||
Progress = GetProgress();
|
||||
if (_waitingList.Count == 0 && _verifyingList.Count == 0)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime;
|
||||
YooLogger.Log($"Package verify elapsed time {costTime:f1} seconds");
|
||||
}
|
||||
|
||||
for (int i = _waitingList.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (OperationSystem.IsBusy)
|
||||
break;
|
||||
|
||||
if (_verifyingList.Count >= _verifyMaxNum)
|
||||
break;
|
||||
|
||||
var element = _waitingList[i];
|
||||
if (BeginVerifyFileWithThread(element))
|
||||
{
|
||||
_waitingList.RemoveAt(i);
|
||||
_verifyingList.Add(element);
|
||||
}
|
||||
else
|
||||
{
|
||||
YooLogger.Warning("The thread pool is failed queued.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float GetProgress()
|
||||
{
|
||||
if (_verifyTotalCount == 0)
|
||||
return 1f;
|
||||
return (float)(_succeedCount + _failedCount) / _verifyTotalCount;
|
||||
}
|
||||
private bool BeginVerifyFileWithThread(VerifyElement element)
|
||||
{
|
||||
return ThreadPool.QueueUserWorkItem(new WaitCallback(VerifyInThread), element);
|
||||
}
|
||||
private void VerifyInThread(object obj)
|
||||
{
|
||||
VerifyElement element = (VerifyElement)obj;
|
||||
element.Result = CacheSystem.VerifyingCacheFile(element, CacheSystem.InitVerifyLevel);
|
||||
_syncContext.Post(VerifyCallback, element);
|
||||
}
|
||||
private void VerifyCallback(object obj)
|
||||
{
|
||||
VerifyElement element = (VerifyElement)obj;
|
||||
_verifyingList.Remove(element);
|
||||
|
||||
if (element.Result == EVerifyResult.Succeed)
|
||||
{
|
||||
_succeedCount++;
|
||||
var wrapper = new PackageCache.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
|
||||
CacheSystem.RecordFile(element.PackageName, element.CacheGUID, wrapper);
|
||||
}
|
||||
else
|
||||
{
|
||||
_failedCount++;
|
||||
|
||||
// 删除验证失败的缓存文件
|
||||
if (Directory.Exists(element.FileRootPath))
|
||||
{
|
||||
YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}");
|
||||
Directory.Delete(element.FileRootPath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 本地缓存文件验证(非线程版)
|
||||
/// </summary>
|
||||
internal class PackageVerifyWithoutThreadOperation : PackageVerifyOperation
|
||||
{
|
||||
private enum ESteps
|
||||
{
|
||||
None,
|
||||
InitVerify,
|
||||
UpdateVerify,
|
||||
Done,
|
||||
}
|
||||
|
||||
private List<VerifyElement> _waitingList;
|
||||
private List<VerifyElement> _verifyingList;
|
||||
private int _verifyMaxNum;
|
||||
private int _verifyTotalCount;
|
||||
private float _verifyStartTime;
|
||||
private int _succeedCount;
|
||||
private int _failedCount;
|
||||
private ESteps _steps = ESteps.None;
|
||||
|
||||
public PackageVerifyWithoutThreadOperation(List<VerifyElement> elements)
|
||||
{
|
||||
_waitingList = elements;
|
||||
}
|
||||
internal override void Start()
|
||||
{
|
||||
_steps = ESteps.InitVerify;
|
||||
_verifyStartTime = UnityEngine.Time.realtimeSinceStartup;
|
||||
}
|
||||
internal override void Update()
|
||||
{
|
||||
if (_steps == ESteps.None || _steps == ESteps.Done)
|
||||
return;
|
||||
|
||||
if (_steps == ESteps.InitVerify)
|
||||
{
|
||||
int fileCount = _waitingList.Count;
|
||||
|
||||
// 设置同时验证的最大数
|
||||
_verifyMaxNum = fileCount;
|
||||
_verifyTotalCount = fileCount;
|
||||
|
||||
_verifyingList = new List<VerifyElement>(_verifyMaxNum);
|
||||
_steps = ESteps.UpdateVerify;
|
||||
}
|
||||
|
||||
if (_steps == ESteps.UpdateVerify)
|
||||
{
|
||||
Progress = GetProgress();
|
||||
if (_waitingList.Count == 0 && _verifyingList.Count == 0)
|
||||
{
|
||||
_steps = ESteps.Done;
|
||||
Status = EOperationStatus.Succeed;
|
||||
float costTime = UnityEngine.Time.realtimeSinceStartup - _verifyStartTime;
|
||||
YooLogger.Log($"Package verify elapsed time {costTime:f1} seconds");
|
||||
}
|
||||
|
||||
for (int i = _waitingList.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (OperationSystem.IsBusy)
|
||||
break;
|
||||
|
||||
if (_verifyingList.Count >= _verifyMaxNum)
|
||||
break;
|
||||
|
||||
var element = _waitingList[i];
|
||||
BeginVerifyFileWithoutThread(element);
|
||||
_waitingList.RemoveAt(i);
|
||||
_verifyingList.Add(element);
|
||||
}
|
||||
|
||||
// 主线程内验证,可以清空列表
|
||||
_verifyingList.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private float GetProgress()
|
||||
{
|
||||
if (_verifyTotalCount == 0)
|
||||
return 1f;
|
||||
return (float)(_succeedCount + _failedCount) / _verifyTotalCount;
|
||||
}
|
||||
private void BeginVerifyFileWithoutThread(VerifyElement element)
|
||||
{
|
||||
element.Result = CacheSystem.VerifyingCacheFile(element, CacheSystem.InitVerifyLevel);
|
||||
if (element.Result == EVerifyResult.Succeed)
|
||||
{
|
||||
_succeedCount++;
|
||||
var wrapper = new PackageCache.RecordWrapper(element.InfoFilePath, element.DataFilePath, element.DataFileCRC, element.DataFileSize);
|
||||
CacheSystem.RecordFile(element.PackageName, element.CacheGUID, wrapper);
|
||||
}
|
||||
else
|
||||
{
|
||||
_failedCount++;
|
||||
|
||||
// 删除验证失败的缓存文件
|
||||
if (Directory.Exists(element.FileRootPath))
|
||||
{
|
||||
YooLogger.Warning($"Failed verify file and delete files : {element.FileRootPath}");
|
||||
Directory.Delete(element.FileRootPath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 868188d19436b674b8c403d2d90afeaf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
103
Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs
Normal file
103
Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class PackageCache
|
||||
{
|
||||
internal class RecordWrapper
|
||||
{
|
||||
public string InfoFilePath { private set; get; }
|
||||
public string DataFilePath { private set; get; }
|
||||
public string DataFileCRC { private set; get; }
|
||||
public long DataFileSize { private set; get; }
|
||||
|
||||
public RecordWrapper(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize)
|
||||
{
|
||||
InfoFilePath = infoFilePath;
|
||||
DataFilePath = dataFilePath;
|
||||
DataFileCRC = dataFileCRC;
|
||||
DataFileSize = dataFileSize;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, RecordWrapper> _wrappers = new Dictionary<string, RecordWrapper>();
|
||||
|
||||
/// <summary>
|
||||
/// 包裹名称
|
||||
/// </summary>
|
||||
public string PackageName { private set; get; }
|
||||
|
||||
|
||||
public PackageCache(string packageName)
|
||||
{
|
||||
PackageName = packageName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空所有数据
|
||||
/// </summary>
|
||||
public void ClearAll()
|
||||
{
|
||||
_wrappers.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询缓存记录
|
||||
/// </summary>
|
||||
public bool IsCached(string cacheGUID)
|
||||
{
|
||||
return _wrappers.ContainsKey(cacheGUID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录验证结果
|
||||
/// </summary>
|
||||
public void Record(string cacheGUID, RecordWrapper wrapper)
|
||||
{
|
||||
if (_wrappers.ContainsKey(cacheGUID) == false)
|
||||
{
|
||||
_wrappers.Add(cacheGUID, wrapper);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Should never get here !");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 丢弃验证结果
|
||||
/// </summary>
|
||||
public void Discard(string cacheGUID)
|
||||
{
|
||||
if (_wrappers.ContainsKey(cacheGUID))
|
||||
{
|
||||
_wrappers.Remove(cacheGUID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取记录对象
|
||||
/// </summary>
|
||||
public RecordWrapper TryGetWrapper(string cacheGUID)
|
||||
{
|
||||
if (_wrappers.TryGetValue(cacheGUID, out RecordWrapper value))
|
||||
return value;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
internal List<string> GetAllKeys()
|
||||
{
|
||||
List<string> keys = new List<string>(_wrappers.Keys.Count);
|
||||
var keyCollection = _wrappers.Keys;
|
||||
foreach (var key in keyCollection)
|
||||
{
|
||||
keys.Add(key);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs.meta
Normal file
11
Assets/YooAsset/Runtime/CacheSystem/PackageCache.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08f3e92fdbd5d56459d8882be1f54f60
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
25
Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs
Normal file
25
Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class VerifyElement
|
||||
{
|
||||
public string PackageName { private set; get; }
|
||||
public string CacheGUID { private set; get; }
|
||||
public string FileRootPath { private set; get; }
|
||||
public string DataFilePath { private set; get; }
|
||||
public string InfoFilePath { private set; get; }
|
||||
|
||||
public EVerifyResult Result;
|
||||
public string DataFileCRC;
|
||||
public long DataFileSize;
|
||||
|
||||
public VerifyElement(string packageName, string cacheGUID, string fileRootPath, string dataFilePath, string infoFilePath)
|
||||
{
|
||||
PackageName = packageName;
|
||||
CacheGUID = cacheGUID;
|
||||
FileRootPath = fileRootPath;
|
||||
DataFilePath = dataFilePath;
|
||||
InfoFilePath = infoFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta
Normal file
11
Assets/YooAsset/Runtime/CacheSystem/VerifyElement.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a4b96484bd701f4289b2f74c38abaa8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,33 +0,0 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
internal class VerifyInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证的资源文件是否为内置资源
|
||||
/// </summary>
|
||||
public bool IsBuildinFile { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证的资源包实例
|
||||
/// </summary>
|
||||
public PatchBundle VerifyBundle { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证的文件路径
|
||||
/// </summary>
|
||||
public string VerifyFilePath { private set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证结果
|
||||
/// </summary>
|
||||
public EVerifyResult Result;
|
||||
|
||||
public VerifyInfo(bool isBuildinFile, PatchBundle verifyBundle)
|
||||
{
|
||||
IsBuildinFile = isBuildinFile;
|
||||
VerifyBundle = verifyBundle;
|
||||
VerifyFilePath = verifyBundle.CachedFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 加载状态
|
||||
/// </summary>
|
||||
public int Status;
|
||||
public string Status;
|
||||
|
||||
public int CompareTo(DebugBundleInfo other)
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 加载状态
|
||||
/// </summary>
|
||||
public int Status;
|
||||
public string Status;
|
||||
|
||||
/// <summary>
|
||||
/// 依赖的资源包列表
|
||||
|
||||
30
Assets/YooAsset/Runtime/DownloadSystem/DownloadReport.cs
Normal file
30
Assets/YooAsset/Runtime/DownloadSystem/DownloadReport.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
public struct DownloadReport
|
||||
{
|
||||
/// <summary>
|
||||
/// 下载进度(0f~1f)
|
||||
/// </summary>
|
||||
public float Progress;
|
||||
|
||||
/// <summary>
|
||||
/// 需要下载的总字节数
|
||||
/// </summary>
|
||||
public ulong TotalSize;
|
||||
|
||||
/// <summary>
|
||||
/// 已经下载的字节数
|
||||
/// </summary>
|
||||
public ulong DownloadedBytes;
|
||||
|
||||
public static DownloadReport CreateDefaultReport()
|
||||
{
|
||||
DownloadReport report = new DownloadReport();
|
||||
report.Progress = 0f;
|
||||
report.TotalSize = 0;
|
||||
report.DownloadedBytes = 0;
|
||||
return report;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d40b8341fcd4ad2478eb1a890ebf0476
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -77,13 +77,13 @@ namespace YooAsset
|
||||
public static DownloaderBase BeginDownload(BundleInfo bundleInfo, int failedTryAgain, int timeout = 60)
|
||||
{
|
||||
// 查询存在的下载器
|
||||
if (_downloaderDic.TryGetValue(bundleInfo.Bundle.CachedFilePath, out var downloader))
|
||||
if (_downloaderDic.TryGetValue(bundleInfo.Bundle.CachedDataFilePath, out var downloader))
|
||||
{
|
||||
return downloader;
|
||||
}
|
||||
|
||||
// 如果资源已经缓存
|
||||
if (CacheSystem.IsCached(bundleInfo.Bundle))
|
||||
if (CacheSystem.IsCached(bundleInfo.Bundle.PackageName, bundleInfo.Bundle.CacheGUID))
|
||||
{
|
||||
var tempDownloader = new TempDownloader(bundleInfo);
|
||||
return tempDownloader;
|
||||
@@ -92,11 +92,11 @@ namespace YooAsset
|
||||
// 创建新的下载器
|
||||
{
|
||||
YooLogger.Log($"Beginning to download file : {bundleInfo.Bundle.FileName} URL : {bundleInfo.RemoteMainURL}");
|
||||
FileUtility.CreateFileDirectory(bundleInfo.Bundle.CachedFilePath);
|
||||
FileUtility.CreateFileDirectory(bundleInfo.Bundle.CachedDataFilePath);
|
||||
bool breakDownload = bundleInfo.Bundle.FileSize >= BreakpointResumeFileSize;
|
||||
DownloaderBase newDownloader = new FileDownloader(bundleInfo, breakDownload);
|
||||
newDownloader.SendRequest(failedTryAgain, timeout);
|
||||
_downloaderDic.Add(bundleInfo.Bundle.CachedFilePath, newDownloader);
|
||||
_downloaderDic.Add(bundleInfo.Bundle.CachedDataFilePath, newDownloader);
|
||||
return newDownloader;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,13 @@ namespace YooAsset
|
||||
protected enum ESteps
|
||||
{
|
||||
None,
|
||||
CheckLocalFile,
|
||||
CreateDownload,
|
||||
CheckTempFile,
|
||||
PrepareDownload,
|
||||
CreateResumeDownloader,
|
||||
CreateGeneralDownloader,
|
||||
CheckDownload,
|
||||
VerifyingFile,
|
||||
CachingFile,
|
||||
TryAgain,
|
||||
Succeed,
|
||||
Failed,
|
||||
@@ -30,7 +34,7 @@ namespace YooAsset
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 下载进度
|
||||
/// 下载进度(0f~1f)
|
||||
/// </summary>
|
||||
public float DownloadProgress
|
||||
{
|
||||
@@ -56,7 +60,7 @@ namespace YooAsset
|
||||
{
|
||||
_failedTryAgain = failedTryAgain;
|
||||
_timeout = timeout;
|
||||
_steps = ESteps.CheckLocalFile;
|
||||
_steps = ESteps.CheckTempFile;
|
||||
}
|
||||
}
|
||||
public abstract void Update();
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace YooAsset
|
||||
internal sealed class FileDownloader : DownloaderBase
|
||||
{
|
||||
private readonly bool _breakResume;
|
||||
private readonly string _tempFilePath;
|
||||
private UnityWebRequest _webRequest = null;
|
||||
private DownloadHandlerFileRange _downloadHandle = null;
|
||||
|
||||
@@ -24,6 +25,7 @@ namespace YooAsset
|
||||
public FileDownloader(BundleInfo bundleInfo, bool breakResume) : base(bundleInfo)
|
||||
{
|
||||
_breakResume = breakResume;
|
||||
_tempFilePath = bundleInfo.Bundle.TempDataFilePath;
|
||||
}
|
||||
public override void Update()
|
||||
{
|
||||
@@ -32,31 +34,28 @@ namespace YooAsset
|
||||
if (IsDone())
|
||||
return;
|
||||
|
||||
// 检测本地文件
|
||||
if (_steps == ESteps.CheckLocalFile)
|
||||
// 检测本地临时文件
|
||||
if (_steps == ESteps.CheckTempFile)
|
||||
{
|
||||
var verifyResult = CacheSystem.VerifyAndCacheBundle(_bundleInfo.Bundle, EVerifyLevel.High);
|
||||
var verifyResult = CacheSystem.VerifyingTempFile(_bundleInfo.Bundle, EVerifyLevel.High);
|
||||
if (verifyResult == EVerifyResult.Succeed)
|
||||
{
|
||||
_steps = ESteps.Succeed;
|
||||
_steps = ESteps.CachingFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verifyResult == EVerifyResult.FileOverflow)
|
||||
{
|
||||
string cacheFilePath = _bundleInfo.Bundle.CachedFilePath;
|
||||
if (File.Exists(cacheFilePath))
|
||||
File.Delete(cacheFilePath);
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
_steps = ESteps.CreateDownload;
|
||||
_steps = ESteps.PrepareDownload;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建下载器
|
||||
if (_steps == ESteps.CreateDownload)
|
||||
if (_steps == ESteps.PrepareDownload)
|
||||
{
|
||||
string fileSavePath = _bundleInfo.Bundle.CachedFilePath;
|
||||
|
||||
// 重置变量
|
||||
_downloadProgress = 0f;
|
||||
_downloadedBytes = 0;
|
||||
@@ -66,53 +65,71 @@ namespace YooAsset
|
||||
_latestDownloadRealtime = Time.realtimeSinceStartup;
|
||||
_tryAgainTimer = 0f;
|
||||
|
||||
// 是否开启断点续传下载
|
||||
if (_breakResume)
|
||||
{
|
||||
long fileLength = -1;
|
||||
if (File.Exists(fileSavePath))
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(fileSavePath);
|
||||
fileLength = fileInfo.Length;
|
||||
_fileOriginLength = (ulong)fileLength;
|
||||
_downloadedBytes = _fileOriginLength;
|
||||
}
|
||||
// 获取请求地址
|
||||
_requestURL = GetRequestURL();
|
||||
|
||||
_requestURL = GetRequestURL();
|
||||
_webRequest = UnityWebRequest.Get(_requestURL);
|
||||
if (_breakResume)
|
||||
_steps = ESteps.CreateResumeDownloader;
|
||||
else
|
||||
_steps = ESteps.CreateGeneralDownloader;
|
||||
}
|
||||
|
||||
// 创建普通的下载器
|
||||
if (_steps == ESteps.CreateGeneralDownloader)
|
||||
{
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
|
||||
_webRequest = new UnityWebRequest(_requestURL, UnityWebRequest.kHttpVerbGET);
|
||||
DownloadHandlerFile handler = new DownloadHandlerFile(_tempFilePath);
|
||||
handler.removeFileOnAbort = true;
|
||||
_webRequest.downloadHandler = handler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
|
||||
if (DownloadSystem.CertificateHandlerInstance != null)
|
||||
{
|
||||
_webRequest.certificateHandler = DownloadSystem.CertificateHandlerInstance;
|
||||
_webRequest.disposeCertificateHandlerOnDispose = false;
|
||||
}
|
||||
|
||||
_webRequest.SendWebRequest();
|
||||
_steps = ESteps.CheckDownload;
|
||||
}
|
||||
|
||||
// 创建断点续传下载器
|
||||
if (_steps == ESteps.CreateResumeDownloader)
|
||||
{
|
||||
long fileLength = -1;
|
||||
if (File.Exists(_tempFilePath))
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(_tempFilePath);
|
||||
fileLength = fileInfo.Length;
|
||||
_fileOriginLength = (ulong)fileLength;
|
||||
_downloadedBytes = _fileOriginLength;
|
||||
}
|
||||
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
var handler = new DownloadHandlerFile(fileSavePath, true);
|
||||
handler.removeFileOnAbort = false;
|
||||
_webRequest = new UnityWebRequest(_requestURL, UnityWebRequest.kHttpVerbGET);
|
||||
var handler = new DownloadHandlerFile(_tempFilePath, true);
|
||||
handler.removeFileOnAbort = false;
|
||||
#else
|
||||
var handler = new DownloadHandlerFileRange(fileSavePath, _bundleInfo.Bundle.FileSize, _webRequest);
|
||||
_downloadHandle = handler;
|
||||
_webRequest = new UnityWebRequest(_requestURL, UnityWebRequest.kHttpVerbGET);
|
||||
var handler = new DownloadHandlerFileRange(_tempFilePath, _bundleInfo.Bundle.FileSize, _webRequest);
|
||||
_downloadHandle = handler;
|
||||
#endif
|
||||
_webRequest.downloadHandler = handler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
if (fileLength > 0)
|
||||
_webRequest.SetRequestHeader("Range", $"bytes={fileLength}-");
|
||||
|
||||
if (DownloadSystem.CertificateHandlerInstance != null)
|
||||
{
|
||||
_webRequest.certificateHandler = DownloadSystem.CertificateHandlerInstance;
|
||||
_webRequest.disposeCertificateHandlerOnDispose = false;
|
||||
}
|
||||
|
||||
_webRequest.downloadHandler = handler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
if (fileLength > 0)
|
||||
_webRequest.SetRequestHeader("Range", $"bytes={fileLength}-");
|
||||
_webRequest.SendWebRequest();
|
||||
_steps = ESteps.CheckDownload;
|
||||
}
|
||||
else
|
||||
if (DownloadSystem.CertificateHandlerInstance != null)
|
||||
{
|
||||
_requestURL = GetRequestURL();
|
||||
_webRequest = new UnityWebRequest(_requestURL, UnityWebRequest.kHttpVerbGET);
|
||||
DownloadHandlerFile handler = new DownloadHandlerFile(fileSavePath);
|
||||
handler.removeFileOnAbort = true;
|
||||
_webRequest.downloadHandler = handler;
|
||||
_webRequest.disposeDownloadHandlerOnDispose = true;
|
||||
_webRequest.SendWebRequest();
|
||||
_steps = ESteps.CheckDownload;
|
||||
_webRequest.certificateHandler = DownloadSystem.CertificateHandlerInstance;
|
||||
_webRequest.disposeCertificateHandlerOnDispose = false;
|
||||
}
|
||||
|
||||
_webRequest.SendWebRequest();
|
||||
_steps = ESteps.CheckDownload;
|
||||
}
|
||||
|
||||
// 检测下载结果
|
||||
@@ -145,78 +162,111 @@ namespace YooAsset
|
||||
}
|
||||
#endif
|
||||
|
||||
// 检查文件完整性
|
||||
if (hasError == false)
|
||||
{
|
||||
var verifyResult = CacheSystem.VerifyAndCacheBundle(_bundleInfo.Bundle, EVerifyLevel.High);
|
||||
if (verifyResult != EVerifyResult.Succeed)
|
||||
{
|
||||
hasError = true;
|
||||
_lastError = $"Verify bundle content failed : {_bundleInfo.Bundle.FileName}";
|
||||
_lastCode = _webRequest.responseCode;
|
||||
|
||||
// 验证失败后删除文件
|
||||
string cacheFilePath = _bundleInfo.Bundle.CachedFilePath;
|
||||
if (File.Exists(cacheFilePath))
|
||||
File.Delete(cacheFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果下载失败
|
||||
// 如果网络异常
|
||||
if (hasError)
|
||||
{
|
||||
// 注意:非断点续传下载失败之后删除文件
|
||||
if (_breakResume == false)
|
||||
{
|
||||
string cacheFilePath = _bundleInfo.Bundle.CachedFilePath;
|
||||
if (File.Exists(cacheFilePath))
|
||||
File.Delete(cacheFilePath);
|
||||
}
|
||||
else
|
||||
if (_breakResume)
|
||||
{
|
||||
// 注意:下载断点续传文件发生特殊错误码之后删除文件
|
||||
if (DownloadSystem.ClearFileResponseCodes != null)
|
||||
{
|
||||
if (DownloadSystem.ClearFileResponseCodes.Contains(_webRequest.responseCode))
|
||||
{
|
||||
string cacheFilePath = _bundleInfo.Bundle.CachedFilePath;
|
||||
if (File.Exists(cacheFilePath))
|
||||
File.Delete(cacheFilePath);
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 失败后重新尝试
|
||||
if (_failedTryAgain > 0)
|
||||
{
|
||||
ReportWarning();
|
||||
_steps = ESteps.TryAgain;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReportError();
|
||||
_steps = ESteps.Failed;
|
||||
// 注意:非断点续传下载失败之后删除文件
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
}
|
||||
|
||||
_steps = ESteps.TryAgain;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lastError = string.Empty;
|
||||
_lastCode = 0;
|
||||
_steps = ESteps.Succeed;
|
||||
_steps = ESteps.VerifyingFile;
|
||||
}
|
||||
|
||||
// 释放下载器
|
||||
DisposeWebRequest();
|
||||
}
|
||||
|
||||
// 验证下载文件
|
||||
if (_steps == ESteps.VerifyingFile)
|
||||
{
|
||||
var verifyResult = CacheSystem.VerifyingTempFile(_bundleInfo.Bundle, EVerifyLevel.High);
|
||||
if (verifyResult == EVerifyResult.Succeed)
|
||||
{
|
||||
_steps = ESteps.CachingFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lastError = $"Failed to verifying file : {_bundleInfo.Bundle.FileName}, ErrorCode : {verifyResult}";
|
||||
|
||||
// 注意:验证失败后删除文件
|
||||
if (File.Exists(_tempFilePath))
|
||||
File.Delete(_tempFilePath);
|
||||
|
||||
_steps = ESteps.TryAgain;
|
||||
}
|
||||
}
|
||||
|
||||
// 缓存下载文件
|
||||
if (_steps == ESteps.CachingFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
string infoFilePath = _bundleInfo.Bundle.CachedInfoFilePath;
|
||||
string dataFilePath = _bundleInfo.Bundle.CachedDataFilePath;
|
||||
string dataFileCRC = _bundleInfo.Bundle.FileCRC;
|
||||
long dataFileSize = _bundleInfo.Bundle.FileSize;
|
||||
|
||||
if (File.Exists(infoFilePath))
|
||||
File.Delete(infoFilePath);
|
||||
if (File.Exists(dataFilePath))
|
||||
File.Delete(dataFilePath);
|
||||
|
||||
FileInfo fileInfo = new FileInfo(_tempFilePath);
|
||||
fileInfo.MoveTo(dataFilePath);
|
||||
|
||||
// 写入信息文件记录验证数据
|
||||
CacheFileInfo.WriteInfoToFile(infoFilePath, dataFileCRC, dataFileSize);
|
||||
|
||||
// 记录缓存文件
|
||||
var wrapper = new PackageCache.RecordWrapper(infoFilePath, dataFilePath, dataFileCRC, dataFileSize);
|
||||
CacheSystem.RecordFile(_bundleInfo.Bundle.PackageName, _bundleInfo.Bundle.CacheGUID, wrapper);
|
||||
|
||||
_lastError = string.Empty;
|
||||
_lastCode = 0;
|
||||
_steps = ESteps.Succeed;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_lastError = e.Message;
|
||||
_steps = ESteps.TryAgain;
|
||||
}
|
||||
}
|
||||
|
||||
// 重新尝试下载
|
||||
if (_steps == ESteps.TryAgain)
|
||||
{
|
||||
if (_failedTryAgain <= 0)
|
||||
{
|
||||
ReportError();
|
||||
_steps = ESteps.Failed;
|
||||
return;
|
||||
}
|
||||
|
||||
_tryAgainTimer += Time.unscaledDeltaTime;
|
||||
if (_tryAgainTimer > 1f)
|
||||
{
|
||||
_failedTryAgain--;
|
||||
_steps = ESteps.CreateDownload;
|
||||
_steps = ESteps.PrepareDownload;
|
||||
ReportWarning();
|
||||
YooLogger.Warning($"Try again download : {_requestURL}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
internal class UnityWebDataRequester
|
||||
{
|
||||
protected UnityWebRequest _webRequest;
|
||||
protected UnityWebRequestAsyncOperation _operationHandle;
|
||||
private UnityWebRequest _webRequest;
|
||||
private UnityWebRequestAsyncOperation _operationHandle;
|
||||
|
||||
/// <summary>
|
||||
/// 请求URL地址
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine;
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
@@ -11,8 +12,14 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
internal class UnityWebFileRequester
|
||||
{
|
||||
protected UnityWebRequest _webRequest;
|
||||
protected UnityWebRequestAsyncOperation _operationHandle;
|
||||
private UnityWebRequest _webRequest;
|
||||
private UnityWebRequestAsyncOperation _operationHandle;
|
||||
|
||||
// 超时相关
|
||||
private float _timeout;
|
||||
private bool _isAbort = false;
|
||||
private ulong _latestDownloadBytes;
|
||||
private float _latestDownloadRealtime;
|
||||
|
||||
/// <summary>
|
||||
/// 请求URL地址
|
||||
@@ -23,11 +30,15 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 发送GET请求
|
||||
/// </summary>
|
||||
public void SendRequest(string url, string savePath)
|
||||
public void SendRequest(string url, string savePath, float timeout = 60)
|
||||
{
|
||||
if (_webRequest == null)
|
||||
{
|
||||
URL = url;
|
||||
_timeout = timeout;
|
||||
_latestDownloadBytes = 0;
|
||||
_latestDownloadRealtime = Time.realtimeSinceStartup;
|
||||
|
||||
_webRequest = new UnityWebRequest(URL, UnityWebRequest.kHttpVerbGET);
|
||||
DownloadHandlerFile handler = new DownloadHandlerFile(savePath);
|
||||
handler.removeFileOnAbort = true;
|
||||
@@ -96,5 +107,28 @@ namespace YooAsset
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测超时
|
||||
/// </summary>
|
||||
public void CheckTimeout()
|
||||
{
|
||||
// 注意:在连续时间段内无新增下载数据及判定为超时
|
||||
if (_isAbort == false)
|
||||
{
|
||||
if (_latestDownloadBytes != _webRequest.downloadedBytes)
|
||||
{
|
||||
_latestDownloadBytes = _webRequest.downloadedBytes;
|
||||
_latestDownloadRealtime = Time.realtimeSinceStartup;
|
||||
}
|
||||
|
||||
float offset = Time.realtimeSinceStartup - _latestDownloadRealtime;
|
||||
if (offset > _timeout)
|
||||
{
|
||||
_webRequest.Abort();
|
||||
_isAbort = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user