Compare commits

...

65 Commits

Author SHA1 Message Date
何冠峰
a5b68b28b2 update asset bundle builder 2025-02-20 11:27:44 +08:00
何冠峰
bd285faf37 update space shooter 2025-02-20 11:27:30 +08:00
何冠峰
8a4960b560 code style 2025-02-20 11:02:59 +08:00
何冠峰
83c6ae2057 update asset bundle builder
修复怀旧依赖模式下,TAG传染不正确的问题。
2025-02-20 11:01:25 +08:00
何冠峰
b71563e889 Update EBuildBundleType.cs 2025-02-20 10:02:12 +08:00
何冠峰
79e0cf85f9 Update CHANGELOG.md 2025-02-19 19:10:36 +08:00
何冠峰
e996eaa008 Update package.json 2025-02-19 19:10:28 +08:00
何冠峰
5088c9e985 update asset bundle builder 2025-02-19 18:46:39 +08:00
何冠峰
610b3c6d32 Update FileSystemParameters.cs 2025-02-19 18:36:43 +08:00
何冠峰
cc7290f10e update operation system
快速启动模式
2025-02-19 18:36:33 +08:00
何冠峰
576b842368 support legacy dependency mode
YOOASSET_LEGACY_DEPENDENCY
2025-02-19 18:27:23 +08:00
何冠峰
d23c0ba715 update space shooter 2025-02-18 19:35:46 +08:00
何冠峰
98e19baebd Update TextureSchema.cs 2025-02-18 19:34:41 +08:00
何冠峰
f5947db44a Update ReorderableListView.cs 2025-02-18 19:34:34 +08:00
何冠峰
e978164329 Update ReorderableListView.cs 2025-02-18 19:28:55 +08:00
何冠峰
966c8f2efa update space shooter 2025-02-18 18:41:05 +08:00
何冠峰
a57fec3d71 update UIElements 2025-02-18 18:38:00 +08:00
何冠峰
84844eda20 update UIElements 2025-02-18 17:31:49 +08:00
何冠峰
698cdcba61 update AssetArtScanner 2025-02-17 18:18:07 +08:00
何冠峰
1d6c9393d4 Update AssetBundleCollector
支持列表元素上下拖拽排序
2025-02-17 17:54:46 +08:00
何冠峰
b654ac156d update AssetArtScanner
支持列表元素上下拖拽排序
2025-02-17 17:54:34 +08:00
何冠峰
d133a9a692 update extension sample 2025-02-17 15:44:41 +08:00
何冠峰
d55db19f0e update extension sample
微信小游戏和抖音小游戏AssetBundle使用插件卸载机制。
2025-02-14 16:37:23 +08:00
何冠峰
e3fc3df32c update space shooter 2025-02-14 12:05:30 +08:00
何冠峰
f2334da72d update extension sample 2025-02-14 12:05:24 +08:00
何冠峰
2902b6c2cf fix #472 2025-02-14 11:29:13 +08:00
何冠峰
dfa95b57b9 Update CHANGELOG.md 2025-02-14 10:03:39 +08:00
何冠峰
33a2cf66d0 Update CHANGELOG.md 2025-02-14 10:03:15 +08:00
何冠峰
5f52cf5b51 Update package.json 2025-02-14 10:03:09 +08:00
何冠峰
9d07905f2d fix #471 2025-02-13 20:14:33 +08:00
何冠峰
26dbe9dfdd update extension sample 2025-02-13 19:08:23 +08:00
何冠峰
98c5851071 update extension file system
解决微信小游戏预下载和正常下载冲突的问题
2025-02-13 18:57:39 +08:00
何冠峰
a6ee571d65 update file system 2025-02-13 18:56:24 +08:00
何冠峰
a138701afe update extension sample
抖音小游戏支持资源加密
2025-02-13 12:12:52 +08:00
何冠峰
e52bdea255 fix #467
微信小游戏资源加密
2025-02-13 12:02:09 +08:00
何冠峰
068a712a30 Merge pull request #470 from suxf/dev
fix: 微信加密资源解密错误
2025-02-13 10:13:28 +08:00
枫似锦
80a5300648 fix: 微信加密资源解密错误 2025-02-13 00:12:26 +08:00
何冠峰
0c36e458f7 update space shooter 2025-02-12 17:43:15 +08:00
何冠峰
b2fa52e4c4 update AssetArtScanner 2025-02-12 17:43:07 +08:00
何冠峰
151e978e5b update space shoot 2025-02-12 16:29:26 +08:00
何冠峰
9e806861ec update extension sample 2025-02-12 16:28:31 +08:00
何冠峰
a9a9368b9b update test sample 2025-02-12 16:27:51 +08:00
何冠峰
7936ba31ea update file system
WebGL网页平台支持资源加密。
2025-02-12 16:27:30 +08:00
何冠峰
afc456de9a Update UnloadAllAssetsOperation.cs 2025-02-12 14:44:02 +08:00
何冠峰
a98db0ba83 update extension sample 2025-02-12 14:43:51 +08:00
何冠峰
fb8720edd3 update extension sample
抖音小游戏支持文件加密。
2025-02-12 11:59:09 +08:00
何冠峰
2aa2a0ac3a update space shooter 2025-02-12 11:46:38 +08:00
何冠峰
0531b6ef3a update extension sample 2025-02-12 11:45:12 +08:00
何冠峰
24142de11f update extension sample
支持微信小游戏文件加密
2025-02-12 11:23:27 +08:00
何冠峰
7fad6eb70b update services
增加WebGL端解密接口
2025-02-12 11:22:09 +08:00
何冠峰
f60227abdf Merge pull request #469 from suxf/dev
优化微信小游戏文件系统逻辑
2025-02-12 10:10:32 +08:00
枫似锦
18d6a74c53 Merge branch 'dev' of https://github.com/suxf/YooAsset into dev 2025-02-12 00:30:22 +08:00
枫似锦
03d06ba657 优化微信小游戏文件系统逻辑 2025-02-12 00:29:10 +08:00
何冠峰
07086b68c8 update extension sample
优化了抖音小游戏文件系统缓存机制
2025-02-11 18:44:51 +08:00
何冠峰
0a85f3126f update extension sample
优化了微信小游戏文件系统缓存机制。
2025-02-11 18:18:29 +08:00
何冠峰
efa4180340 update resource manager
UnloadUnusedAssetsOperation逻辑里移除了Resources.UnloadUnusedAssets调用
2025-02-11 18:15:45 +08:00
何冠峰
fb06f2aa11 update resource manager
UnloadAllAssetsAsync新增UnloadAllAssetsOptions参数
2025-02-11 17:32:31 +08:00
何冠峰
ce023cedb8 update extension sample 2025-02-11 15:13:45 +08:00
何冠峰
3d1a28a50e update file system 2025-02-11 15:09:23 +08:00
何冠峰
5d2d0b4168 fix #341 2025-02-11 10:20:33 +08:00
何冠峰
fa985a5a93 Merge branch 'dev' of https://github.com/tuyoogame/YooAsset into dev 2025-02-11 09:55:38 +08:00
何冠峰
40f9937b60 update space shooter 2025-02-11 09:55:37 +08:00
何冠峰
c543c629c3 Merge pull request #466 from suxf/dev
fix:微信小游戏缓存文件系统查询机制不生效
2025-02-11 09:43:16 +08:00
枫似锦
0a96e583d3 Merge branch 'dev' of https://github.com/suxf/YooAsset into dev 2025-02-10 16:39:31 +08:00
枫似锦
c9d263c60d fix:微信小游戏缓存文件系统查询机制不生效 2025-02-10 16:38:23 +08:00
83 changed files with 2307 additions and 732 deletions

View File

@@ -2,6 +2,82 @@
All notable changes to this package will be documented in this file.
## [2.3.0-preview] - 2025-02-19
### Improvements
资源收集窗口列表元素支持手动上下拖拽排序!
资源扫描窗口列表元素支持手动上下拖拽排序!
### Added
- 新增了UIElements扩展类ReorderableListView
- 新增初始化方法
```csharp
public class YooAssets
{
/// <summary>
/// 设置异步系统参数,快速启动模式的开关
/// 注意:该模式默认开启
/// </summary>
public static void SetOperationSystemQuickStartMode(bool state)
}
```
- 新增打包构建参数
```csharp
public class BuildParameters
{
/// <summary>
/// 旧版依赖模式
/// 说明兼容YooAssets1.5.x版本
/// </summary>
public bool LegacyDependency = false;
}
```
### Fixed
- (#472) 修复了Unity6平台TableView视图无法显示问题。
- 修复了微信小游戏和抖音小游戏未正确使用插件的卸载方法。
## [2.2.12] - 2025-02-14
### Improvements
- WebGL网页平台支持文件加密。
- 微信小游戏平台支持文件加密。
- 抖音小游戏平台支持文件加密。
### Fixed
- (#466) 修复了微信小游戏文件系统查询机制不生效!
- (#341) 修复了微信小游戏的下载进度异常问题。
- (#471) 修复了Unity2019,Unity2020平台上TableView视图无法显示的问题。
### Added
- 新增了ResourcePackage.UnloadAllAssetsAsync(UnloadAllAssetsOptions options)方法
```csharp
public sealed class UnloadAllAssetsOptions
{
/// <summary>
/// 释放所有资源句柄,防止卸载过程中触发完成回调!
/// </summary>
public bool ReleaseAllHandles = true;
/// <summary>
/// 卸载过程中锁定加载操作,防止新的任务请求!
/// </summary>
public bool LockLoadOperation = true;
}
```
## [2.2.11] - 2025-02-10
### Improvements

View File

@@ -69,7 +69,6 @@ namespace YooAsset.Editor
_scannerListView = root.Q<ListView>("ScannerListView");
_scannerListView.makeItem = MakeScannerListViewItem;
_scannerListView.bindItem = BindScannerListViewItem;
#if UNITY_2022_3_OR_NEWER
_scannerListView.selectionChanged += ScannerListView_onSelectionChange;
#elif UNITY_2020_1_OR_NEWER
@@ -277,12 +276,23 @@ namespace YooAsset.Editor
{
_scannerListView.Clear();
_scannerListView.ClearSelection();
_scannerListView.itemsSource = FilterScanners();
_scannerListView.Rebuild();
if (_lastModifyScannerIndex >= 0 && _lastModifyScannerIndex < _scannerListView.itemsSource.Count)
var filterItems = FilterScanners();
if (AssetArtScannerSettingData.Setting.Scanners.Count == filterItems.Count)
{
_scannerListView.selectedIndex = _lastModifyScannerIndex;
#if UNITY_2020_3_OR_NEWER
_scannerListView.reorderable = true;
#endif
_scannerListView.itemsSource = AssetArtScannerSettingData.Setting.Scanners;
_scannerListView.Rebuild();
}
else
{
#if UNITY_2020_3_OR_NEWER
_scannerListView.reorderable = false;
#endif
_scannerListView.itemsSource = filterItems;
_scannerListView.Rebuild();
}
}
private List<AssetArtScanner> FilterScanners()
@@ -344,31 +354,7 @@ namespace YooAsset.Editor
// 显示检视面板
var scanSchema = selectScanner.LoadSchema();
if (scanSchema != null)
{
var inspector = scanSchema.CreateInspector();
if (inspector == null)
{
UIElementsTools.SetElementVisible(_inspectorContainer, false);
}
else
{
if (inspector.Containner is VisualElement container)
{
UIElementsTools.SetElementVisible(_inspectorContainer, true);
_inspectorContainer.Clear();
_inspectorContainer.Add(container);
_inspectorContainer.style.width = inspector.Width;
_inspectorContainer.style.minWidth = inspector.MinWidth;
_inspectorContainer.style.maxWidth = inspector.MaxWidth;
}
else
{
Debug.LogWarning($"{nameof(ScannerSchema)} inspector container is invalid !");
UIElementsTools.SetElementVisible(_inspectorContainer, false);
}
}
}
RefreshInspector(scanSchema);
// 设置Schema对象
if (scanSchema == null)
@@ -521,6 +507,38 @@ namespace YooAsset.Editor
AssetArtScannerSettingData.RemoveCollector(selectSacnner, selectCollector);
FillCollectorViewData();
}
// 属性面板相关
private void RefreshInspector(ScannerSchema scanSchema)
{
if (scanSchema == null)
{
UIElementsTools.SetElementVisible(_inspectorContainer, false);
return;
}
var inspector = scanSchema.CreateInspector();
if (inspector == null)
{
UIElementsTools.SetElementVisible(_inspectorContainer, false);
return;
}
if (inspector.Containner is VisualElement container)
{
UIElementsTools.SetElementVisible(_inspectorContainer, true);
_inspectorContainer.Clear();
_inspectorContainer.Add(container);
_inspectorContainer.style.width = inspector.Width;
_inspectorContainer.style.minWidth = inspector.MinWidth;
_inspectorContainer.style.maxWidth = inspector.MaxWidth;
}
else
{
Debug.LogWarning($"{nameof(ScannerSchema)} inspector container is invalid !");
UIElementsTools.SetElementVisible(_inspectorContainer, false);
}
}
}
}
#endif

View File

@@ -9,7 +9,7 @@
<ui:VisualElement name="ScannerListContainer" style="width: 250px; flex-grow: 0; background-color: rgb(67, 67, 67); border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
<ui:Label text="Scanner List" display-tooltip-when-elided="true" name="ScannerListTitle" style="background-color: rgb(89, 89, 89); -unity-text-align: upper-center; -unity-font-style: bold; border-left-width: 3px; border-right-width: 3px; border-top-width: 3px; border-bottom-width: 3px; font-size: 12px;" />
<uie:ToolbarSearchField focusable="true" name="ScannerSearchField" style="width: 230px;" />
<ui:ListView focusable="true" name="ScannerListView" item-height="20" virtualization-method="DynamicHeight" style="flex-grow: 1;" />
<ui:ListView focusable="true" name="ScannerListView" item-height="20" virtualization-method="DynamicHeight" reorder-mode="Animated" reorderable="true" style="flex-grow: 1;" />
<ui:VisualElement name="ScannerAddContainer" style="justify-content: center; flex-direction: row; flex-shrink: 0;">
<ui:Button text=" - " display-tooltip-when-elided="true" name="RemoveBtn" />
<ui:Button text=" + " display-tooltip-when-elided="true" name="AddBtn" />

View File

@@ -6,7 +6,7 @@ namespace YooAsset.Editor
/// <summary>
/// 检视界面的UI元素容器UIElements元素
/// </summary>
public object Containner;
public object Containner { private set; get; }
/// <summary>
/// 检视界面宽度
@@ -22,5 +22,24 @@ namespace YooAsset.Editor
/// 检视界面最大宽度
/// </summary>
public int MaxWidth = 250;
public SchemaInspector(object containner)
{
Containner = containner;
}
public SchemaInspector(object containner, int width)
{
Containner = containner;
Width = width;
MinWidth = width;
MaxWidth = width;
}
public SchemaInspector(object containner, int width, int minWidth, int maxWidth)
{
Containner = containner;
Width = width;
MinWidth = minWidth;
MaxWidth = maxWidth;
}
}
}

View File

@@ -51,6 +51,12 @@ namespace YooAsset.Editor
/// </summary>
public string PackageNote;
/// <summary>
/// 怀旧版依赖模式
/// 说明兼容YooAssets1.5.x版本
/// </summary>
public bool LegacyDependency = false;
/// <summary>
/// 清空构建缓存文件
/// </summary>

View File

@@ -31,6 +31,7 @@ namespace YooAsset.Editor
// 创建新补丁清单
PackageManifest manifest = new PackageManifest();
manifest.FileVersion = YooAssetSettings.ManifestFileVersion;
manifest.LegacyDependency = buildParameters.LegacyDependency;
manifest.EnableAddressable = buildMapContext.Command.EnableAddressable;
manifest.LocationToLower = buildMapContext.Command.LocationToLower;
manifest.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID;
@@ -43,17 +44,25 @@ namespace YooAsset.Editor
manifest.AssetList = CreatePackageAssetList(buildMapContext);
manifest.BundleList = CreatePackageBundleList(buildMapContext);
// 处理资源清单的ID数据
ProcessPacakgeIDs(manifest);
// 1. 处理资源清单的资源对象
ProcessPacakgeAsset(manifest);
// 处理资源包的依赖列表
// 2. 处理资源包的依赖列表
if (processBundleDepends)
ProcessBundleDepends(context, manifest);
// 处理资源包的标签集合
// 3. 处理资源包的标签集合
if (processBundleTags)
ProcessBundleTags(manifest);
#region YOOASSET_LEGACY_DEPENDENCY
if (buildParameters.LegacyDependency)
{
if (processBundleDepends)
ProcessLegacyDependency(context, manifest);
}
#endregion
// 创建补丁清单文本文件
{
string fileName = YooAssetSettingsData.GetManifestJsonFileName(buildParameters.PackageName, buildParameters.PackageVersion);
@@ -137,7 +146,7 @@ namespace YooAsset.Editor
packageAsset.AssetPath = assetInfo.AssetInfo.AssetPath;
packageAsset.AssetGUID = buildMapContext.Command.IncludeAssetGUID ? assetInfo.AssetInfo.AssetGUID : string.Empty;
packageAsset.AssetTags = assetInfo.AssetTags.ToArray();
packageAsset.BundleNameInEditor = assetInfo.BundleName;
packageAsset.TempDataInEditor = assetInfo;
result.Add(packageAsset);
}
}
@@ -165,9 +174,9 @@ namespace YooAsset.Editor
}
/// <summary>
/// 处理资源清单的ID数据
/// 处理资源清单的资源对象列表
/// </summary>
private void ProcessPacakgeIDs(PackageManifest manifest)
private void ProcessPacakgeAsset(PackageManifest manifest)
{
// 注意:优先缓存资源包索引
for (int index = 0; index < manifest.BundleList.Count; index++)
@@ -176,11 +185,25 @@ namespace YooAsset.Editor
_cachedBundleIndexIDs.Add(bundleName, index);
}
// 记录资源对象所属的资源包ID
foreach (var packageAsset in manifest.AssetList)
{
string bundleName = packageAsset.BundleNameInEditor;
packageAsset.BundleID = GetCachedBundleIndexID(bundleName);
var assetInfo = packageAsset.TempDataInEditor as BuildAssetInfo;
packageAsset.BundleID = GetCachedBundleIndexID(assetInfo.BundleName);
}
#region YOOASSET_LEGACY_DEPENDENCY
if (manifest.LegacyDependency)
{
// 记录资源对象依赖的资源包ID集合
// 注意:依赖关系非引擎构建结果里查询!
foreach (var packageAsset in manifest.AssetList)
{
var mainAssetInfo = packageAsset.TempDataInEditor as BuildAssetInfo;
packageAsset.DependBundleIDs = GetAssetDependBundleIDs(mainAssetInfo);
}
}
#endregion
}
/// <summary>
@@ -192,7 +215,7 @@ namespace YooAsset.Editor
foreach (var packageBundle in manifest.BundleList)
{
int mainBundleID = GetCachedBundleIndexID(packageBundle.BundleName);
var depends = GetBundleDepends(context, packageBundle.BundleName);
string[] depends = GetBundleDepends(context, packageBundle.BundleName);
List<int> dependIDs = new List<int>(depends.Length);
foreach (var dependBundleName in depends)
{
@@ -202,6 +225,23 @@ namespace YooAsset.Editor
}
packageBundle.DependIDs = dependIDs.ToArray();
}
#region YOOASSET_LEGACY_DEPENDENCY
if (manifest.LegacyDependency)
{
foreach (var packageBundle in manifest.BundleList)
{
var dependIDs = packageBundle.DependIDs;
packageBundle.TempDataInEditor = new DependencyQuery(dependIDs);
}
// 记录引用该资源包的资源包ID集合
foreach (var packageBundle in manifest.BundleList)
{
packageBundle.ReferenceBundleIDs = GetBundleReferenceBundleIDs(manifest, packageBundle);
}
}
#endregion
}
/// <summary>
@@ -209,23 +249,51 @@ namespace YooAsset.Editor
/// </summary>
private void ProcessBundleTags(PackageManifest manifest)
{
// 将主资源的标签信息传染给其依赖的资源包集合
foreach (var packageAsset in manifest.AssetList)
foreach (var packageBundle in manifest.BundleList)
{
var assetTags = packageAsset.AssetTags;
int bundleID = packageAsset.BundleID;
CacheBundleTags(bundleID, assetTags);
packageBundle.Tags = Array.Empty<string>();
}
var packageBundle = manifest.BundleList[bundleID];
if (packageBundle.DependIDs != null)
// YOOASSET_LEGACY_DEPENDENCY
if (manifest.LegacyDependency)
{
// 将主资源的标签信息传染给其依赖的资源包集合
foreach (var packageAsset in manifest.AssetList)
{
foreach (var dependBundleID in packageBundle.DependIDs)
var assetTags = packageAsset.AssetTags;
int bundleID = packageAsset.BundleID;
CacheBundleTags(bundleID, assetTags);
if (packageAsset.DependBundleIDs != null)
{
CacheBundleTags(dependBundleID, assetTags);
foreach (var dependBundleID in packageAsset.DependBundleIDs)
{
CacheBundleTags(dependBundleID, assetTags);
}
}
}
}
else
{
// 将主资源的标签信息传染给其依赖的资源包集合
foreach (var packageAsset in manifest.AssetList)
{
var assetTags = packageAsset.AssetTags;
int bundleID = packageAsset.BundleID;
CacheBundleTags(bundleID, assetTags);
var packageBundle = manifest.BundleList[bundleID];
if (packageBundle.DependIDs != null)
{
foreach (var dependBundleID in packageBundle.DependIDs)
{
CacheBundleTags(dependBundleID, assetTags);
}
}
}
}
// 将缓存的资源标签赋值给资源包
for (int index = 0; index < manifest.BundleList.Count; index++)
{
var packageBundle = manifest.BundleList[index];
@@ -264,5 +332,120 @@ namespace YooAsset.Editor
}
return value;
}
/// <summary>
/// 是否包含该资源包的索引ID
/// </summary>
private bool ContainsCachedBundleIndexID(string bundleName)
{
return _cachedBundleIndexIDs.ContainsKey(bundleName);
}
#region YOOASSET_LEGACY_DEPENDENCY
private class DependencyQuery
{
private readonly HashSet<int> _dependIDs;
public DependencyQuery(int[] dependIDs)
{
_dependIDs = new HashSet<int>(dependIDs);
}
public bool Contains(int bundleID)
{
return _dependIDs.Contains(bundleID);
}
}
private void ProcessLegacyDependency(BuildContext context, PackageManifest manifest)
{
// 注意:如果是可编程构建管线,需要补充内置资源包
// 注意:该步骤依赖前面的操作!
var buildResultContext = context.TryGetContextObject<TaskBuilding_SBP.BuildResultContext>();
if (buildResultContext != null)
{
ProcessBuiltinBundleReference(context, manifest, buildResultContext.BuiltinShadersBundleName);
ProcessBuiltinBundleReference(context, manifest, buildResultContext.MonoScriptsBundleName);
}
}
private void ProcessBuiltinBundleReference(BuildContext context, PackageManifest manifest, string builtinBundleName)
{
if (string.IsNullOrEmpty(builtinBundleName))
return;
// 查询内置资源包是否存在
if (ContainsCachedBundleIndexID(builtinBundleName) == false)
return;
// 获取内置资源包
int builtinBundleID = GetCachedBundleIndexID(builtinBundleName);
var builtinPackageBundle = manifest.BundleList[builtinBundleID];
// 更新依赖资源包ID集合
HashSet<int> cacheBundleIDs = new HashSet<int>(builtinPackageBundle.ReferenceBundleIDs);
HashSet<string> tempTags = new HashSet<string>();
foreach (var packageAsset in manifest.AssetList)
{
if (cacheBundleIDs.Contains(packageAsset.BundleID))
{
if (packageAsset.DependBundleIDs.Contains(builtinBundleID) == false)
{
var tempBundleIDs = new List<int>(packageAsset.DependBundleIDs);
tempBundleIDs.Add(builtinBundleID);
packageAsset.DependBundleIDs = tempBundleIDs.ToArray();
}
foreach (var tag in packageAsset.AssetTags)
{
if (tempTags.Contains(tag) == false)
tempTags.Add(tag);
}
}
}
// 更新内置资源包的标签集合
foreach (var tag in builtinPackageBundle.Tags)
{
if (tempTags.Contains(tag) == false)
tempTags.Add(tag);
}
builtinPackageBundle.Tags = tempTags.ToArray();
}
private int[] GetAssetDependBundleIDs(BuildAssetInfo mainAssetInfo)
{
HashSet<int> result = new HashSet<int>();
int mainBundleID = GetCachedBundleIndexID(mainAssetInfo.BundleName);
foreach (var dependAssetInfo in mainAssetInfo.AllDependAssetInfos)
{
if (dependAssetInfo.HasBundleName())
{
int bundleID = GetCachedBundleIndexID(dependAssetInfo.BundleName);
if (mainBundleID != bundleID)
{
if (result.Contains(bundleID) == false)
result.Add(bundleID);
}
}
}
return result.ToArray();
}
private int[] GetBundleReferenceBundleIDs(PackageManifest manifest, PackageBundle queryBundle)
{
int queryBundleID = GetCachedBundleIndexID(queryBundle.BundleName);
List<int> result = new List<int>();
foreach (var packageBundle in manifest.BundleList)
{
if (packageBundle == queryBundle)
continue;
var dependencyQuery = packageBundle.TempDataInEditor as DependencyQuery;
if (dependencyQuery.Contains(queryBundleID))
{
int referenceBundleID = GetCachedBundleIndexID(packageBundle.BundleName);
if (result.Contains(referenceBundleID) == false)
result.Add(referenceBundleID);
}
}
return result.ToArray();
}
#endregion
}
}

View File

@@ -42,6 +42,7 @@ namespace YooAsset.Editor
buildReport.Summary.AutoCollectShaders = buildMapContext.Command.AutoCollectShaders;
// 构建参数
buildReport.Summary.LegacyDependency = buildParameters.LegacyDependency;
buildReport.Summary.ClearBuildCacheFiles = buildParameters.ClearBuildCacheFiles;
buildReport.Summary.UseAssetDependencyDB = buildParameters.UseAssetDependencyDB;
buildReport.Summary.EnableSharePackRule = buildParameters.EnableSharePackRule;

View File

@@ -13,6 +13,8 @@ namespace YooAsset.Editor
public class BuildResultContext : IContextObject
{
public IBundleBuildResults Results;
public string BuiltinShadersBundleName;
public string MonoScriptsBundleName;
}
void IBuildTask.Run(BuildContext context)
@@ -53,6 +55,8 @@ namespace YooAsset.Editor
BuildLogger.Log("UnityEngine build success!");
BuildResultContext buildResultContext = new BuildResultContext();
buildResultContext.Results = buildResults;
buildResultContext.BuiltinShadersBundleName = builtinShadersBundleName;
buildResultContext.MonoScriptsBundleName = monoScriptsBundleName;
context.SetContextObject(buildResultContext);
}
}

View File

@@ -9,7 +9,7 @@ namespace YooAsset.Editor
private readonly Dictionary<System.Type, IContextObject> _contextObjects = new Dictionary<System.Type, IContextObject>();
/// <summary>
/// 清空所有情景对象
/// 清空所有上下文对象
/// </summary>
public void ClearAllContext()
{
@@ -17,7 +17,7 @@ namespace YooAsset.Editor
}
/// <summary>
/// 设置情景对象
/// 设置上下文对象
/// </summary>
public void SetContextObject(IContextObject contextObject)
{
@@ -32,7 +32,7 @@ namespace YooAsset.Editor
}
/// <summary>
/// 获取情景对象
/// 获取上下文对象
/// </summary>
public T GetContextObject<T>() where T : IContextObject
{
@@ -46,5 +46,21 @@ namespace YooAsset.Editor
throw new Exception($"Not found context object : {type}");
}
}
/// <summary>
/// 获取上下文对象
/// </summary>
public T TryGetContextObject<T>() where T : IContextObject
{
var type = typeof(T);
if (_contextObjects.TryGetValue(type, out IContextObject contextObject))
{
return (T)contextObject;
}
else
{
return default;
}
}
}
}

View File

@@ -37,6 +37,7 @@ namespace YooAsset.Editor
buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = GetPackageVersion();
buildParameters.LegacyDependency = false;
buildParameters.EnableSharePackRule = true;
buildParameters.VerifyBuildingResult = true;
buildParameters.FileNameStyle = fileNameStyle;

View File

@@ -38,6 +38,7 @@ namespace YooAsset.Editor
buildParameters.BuildTarget = BuildTarget;
buildParameters.PackageName = PackageName;
buildParameters.PackageVersion = GetPackageVersion();
buildParameters.LegacyDependency = false;
buildParameters.EnableSharePackRule = true;
buildParameters.VerifyBuildingResult = true;
buildParameters.FileNameStyle = fileNameStyle;

View File

@@ -28,7 +28,7 @@
<ui:VisualElement name="ContentContainer" style="flex-grow: 1; flex-direction: row;">
<ui:VisualElement name="PackageContainer" style="width: 200px; flex-grow: 0; background-color: rgb(67, 67, 67); border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
<ui:Label text="Packages" display-tooltip-when-elided="true" name="PackageTitle" style="background-color: rgb(89, 89, 89); -unity-text-align: upper-center; -unity-font-style: bold; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px; font-size: 12px;" />
<ui:ListView focusable="true" name="PackageListView" item-height="20" virtualization-method="DynamicHeight" style="flex-grow: 1;" />
<ui:ListView focusable="true" name="PackageListView" item-height="20" virtualization-method="DynamicHeight" reorderable="true" reorder-mode="Animated" style="flex-grow: 1;" />
<ui:VisualElement name="PackageAddContainer" style="height: 20px; flex-direction: row; justify-content: center;">
<ui:Button text=" - " display-tooltip-when-elided="true" name="RemoveBtn" />
<ui:Button text=" + " display-tooltip-when-elided="true" name="AddBtn" />
@@ -38,7 +38,7 @@
<ui:Label text="Groups" display-tooltip-when-elided="true" name="GroupTitle" style="background-color: rgb(89, 89, 89); -unity-text-align: upper-center; -unity-font-style: bold; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px; font-size: 12px;" />
<ui:TextField picking-mode="Ignore" label="Package Name" name="PackageName" style="flex-direction: column;" />
<ui:TextField picking-mode="Ignore" label="Package Desc" name="PackageDesc" style="flex-direction: column;" />
<ui:ListView focusable="true" name="GroupListView" item-height="20" virtualization-method="DynamicHeight" style="flex-grow: 1;" />
<ui:ListView focusable="true" name="GroupListView" item-height="20" virtualization-method="DynamicHeight" reorderable="true" reorder-mode="Animated" style="flex-grow: 1;" />
<ui:VisualElement name="GroupAddContainer" style="height: 20px; flex-direction: row; justify-content: center;">
<ui:Button text=" - " display-tooltip-when-elided="true" name="RemoveBtn" />
<ui:Button text=" + " display-tooltip-when-elided="true" name="AddBtn" />

View File

@@ -2,7 +2,7 @@
<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;">
<YooAsset.Editor.TableView name="TopTableView" />
</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;">
<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; flex-grow: 1;">
<YooAsset.Editor.TableView name="BottomTableView" />
</ui:VisualElement>
</ui:UXML>

View File

@@ -67,6 +67,7 @@ namespace YooAsset.Editor
public string IgnoreRuleName;
// 构建参数
public bool LegacyDependency;
public bool ClearBuildCacheFiles;
public bool UseAssetDependencyDB;
public bool EnableSharePackRule;

View File

@@ -1,8 +1,8 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<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;">
<YooAsset.Editor.TableView name="TopTableView" />
<YooAsset.Editor.TableView name="TopTableView" style="flex-grow: 1;" />
</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;">
<YooAsset.Editor.TableView name="BottomTableView" />
<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; flex-grow: 1;">
<YooAsset.Editor.TableView name="BottomTableView" style="flex-grow: 1;" />
</ui:VisualElement>
</ui:UXML>

View File

@@ -1,8 +1,8 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<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;">
<YooAsset.Editor.TableView name="TopTableView" />
<YooAsset.Editor.TableView name="TopTableView" style="flex-grow: 1;" />
</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;">
<YooAsset.Editor.TableView name="BottomTableView" />
<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; flex-grow: 1;">
<YooAsset.Editor.TableView name="BottomTableView" style="flex-grow: 1;" />
</ui:VisualElement>
</ui:UXML>

View File

@@ -75,9 +75,10 @@ namespace YooAsset.Editor
_items.Add(new ItemWrapper("Include Asset GUID", $"{buildReport.Summary.IncludeAssetGUID}"));
_items.Add(new ItemWrapper("Auto Collect Shaders", $"{buildReport.Summary.AutoCollectShaders}"));
_items.Add(new ItemWrapper("Ignore Rule Name", $"{buildReport.Summary.IgnoreRuleName}"));
_items.Add(new ItemWrapper(string.Empty, string.Empty));
_items.Add(new ItemWrapper("Build Params", string.Empty));
_items.Add(new ItemWrapper("Legacy Dependency Mode", $"{buildReport.Summary.LegacyDependency}"));
_items.Add(new ItemWrapper("Clear Build Cache Files", $"{buildReport.Summary.ClearBuildCacheFiles}"));
_items.Add(new ItemWrapper("Use Asset Dependency DB", $"{buildReport.Summary.UseAssetDependencyDB}"));
_items.Add(new ItemWrapper("Enable Share Pack Rule", $"{buildReport.Summary.EnableSharePackRule}"));

View File

@@ -12,15 +12,9 @@ namespace YooAsset.Editor
/// </summary>
public class PanelSplitView : TwoPaneSplitView
{
#if UNITY_6000_0_OR_NEWER
public new class UxmlFactory : UxmlElementAttribute
{
}
#else
public new class UxmlFactory : UxmlFactory<PanelSplitView, UxmlTraits>
{
}
#endif
/// <summary>
/// 竖版分屏

View File

@@ -0,0 +1,627 @@
#if UNITY_2021_3_OR_NEWER
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace YooAsset.Editor
{
public class ReorderableListView : VisualElement
{
public new class UxmlFactory : UxmlFactory<ReorderableListView, UxmlTraits>
{
}
/// <summary>
/// 制作元素委托
/// </summary>
/// <returns></returns>
public delegate VisualElement MakeElementDelegate();
/// <summary>
/// 绑定元素委托
/// </summary>
public delegate void BindElementDelegqate(VisualElement element, int index);
private Foldout _foldout;
private ListView _listView;
private Label _headerLabel;
private Button _addButton;
private Button _removeButton;
private string _headerName = nameof(ReorderableListView);
/// <summary>
/// 源数据
/// </summary>
public IList SourceData
{
set
{
if (value is ArrayList)
throw new Exception($"{nameof(SourceData)} not support {nameof(ArrayList)}");
_listView.Clear();
_listView.ClearSelection();
_listView.itemsSource = value;
_listView.Rebuild();
RefreshFoldoutName();
RefreshRemoveButton();
}
get
{
return _listView.itemsSource;
}
}
/// <summary>
/// 元素固定高度
/// </summary>
public float ElementHeight
{
set
{
_listView.fixedItemHeight = value;
_listView.Rebuild();
}
get
{
return _listView.fixedItemHeight;
}
}
/// <summary>
/// 增加按钮显隐
/// </summary>
public bool DisplayAdd
{
set
{
UIElementsTools.SetElementVisible(_addButton, value);
}
get
{
return _addButton.style.visibility == Visibility.Visible;
}
}
/// <summary>
/// 移除按钮显隐
/// </summary>
public bool DisplayRemove
{
set
{
UIElementsTools.SetElementVisible(_removeButton, value);
}
get
{
return _removeButton.style.visibility == Visibility.Visible;
}
}
/// <summary>
/// 标题名称
/// </summary>
public string HeaderName
{
set
{
_headerName = value;
RefreshFoldoutName();
}
get
{
return _headerName;
}
}
/// <summary>
/// 制作元素的回调
/// </summary>
public MakeElementDelegate MakeElementCallback;
/// <summary>
/// 绑定元素的回调
/// </summary>
public BindElementDelegqate BindElementCallback;
public ReorderableListView()
{
CreateView(true);
}
public ReorderableListView(bool foldout)
{
CreateView(foldout);
}
private void CreateView(bool foldout)
{
this.style.flexGrow = 1;
this.style.flexShrink = 1;
// 折叠栏
if (foldout)
{
_foldout = new Foldout();
_foldout.style.flexGrow = 1f;
_foldout.style.flexShrink = 1f;
_foldout.text = $"{nameof(ReorderableListView)}";
}
else
{
_headerLabel = new Label();
}
// 列表视图
_listView = new ListView();
_listView.style.flexGrow = 1;
_listView.style.flexShrink = 1;
_listView.reorderable = true;
_listView.reorderMode = ListViewReorderMode.Animated;
_listView.makeItem = MakeListViewElement;
_listView.bindItem = BindListViewElement;
#if UNITY_2022_3_OR_NEWER
_listView.selectionChanged += OnSelectionChanged;
#elif UNITY_2020_1_OR_NEWER
_listView.onSelectionChange += OnSelectionChanged;
#else
_listView.onSelectionChanged += OnSelectionChanged;
#endif
// 按钮组
var buttonContainer = new VisualElement();
buttonContainer.style.flexDirection = FlexDirection.RowReverse;
// 移除按钮
_removeButton = new Button();
_removeButton.text = " - ";
_removeButton.clicked += OnClickRemoveButton;
_removeButton.SetEnabled(false);
buttonContainer.Add(_removeButton);
// 增加按钮
_addButton = new Button();
_addButton.text = " + ";
_addButton.clicked += OnClickAddButton;
buttonContainer.Add(_addButton);
// 组织页面
if (foldout)
{
_foldout.Add(_listView);
_foldout.Add(buttonContainer);
this.Add(_foldout);
}
else
{
this.Add(_headerLabel);
this.Add(_listView);
this.Add(buttonContainer);
}
}
private void OnClickAddButton()
{
if (_listView.itemsSource != null)
{
object defaultValue = GetElementDefaultValue();
_listView.itemsSource.Add(defaultValue);
_listView.Rebuild();
RefreshFoldoutName();
RefreshRemoveButton();
}
else
{
Debug.LogWarning("The source data is null !");
}
}
private void OnClickRemoveButton()
{
if (_listView.itemsSource != null)
{
if (_listView.selectedIndex >= 0)
{
_listView.itemsSource.RemoveAt(_listView.selectedIndex);
_listView.Rebuild();
RefreshFoldoutName();
RefreshRemoveButton();
}
}
else
{
Debug.LogWarning("The source data is null !");
}
}
private void OnSelectionChanged(IEnumerable<object> objs)
{
RefreshRemoveButton();
}
/// <summary>
/// 生成元素
/// </summary>
private VisualElement MakeListViewElement()
{
if (MakeElementCallback != null)
{
return MakeElementCallback.Invoke();
}
Type elementType = GetElementType();
if (elementType == typeof(string))
{
TextField textField = new TextField();
textField.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)textField.userData;
_listView.itemsSource[itemIndex] = textField.value;
});
return textField;
}
else if (elementType == typeof(int))
{
IntegerField intField = new IntegerField();
intField.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)intField.userData;
_listView.itemsSource[itemIndex] = intField.value;
});
return intField;
}
else if (elementType == typeof(long))
{
LongField longField = new LongField();
longField.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)longField.userData;
_listView.itemsSource[itemIndex] = longField.value;
});
return longField;
}
else if (elementType == typeof(float))
{
FloatField floatField = new FloatField();
floatField.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)floatField.userData;
_listView.itemsSource[itemIndex] = floatField.value;
});
return floatField;
}
else if (elementType == typeof(double))
{
DoubleField doubleField = new DoubleField();
doubleField.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)doubleField.userData;
_listView.itemsSource[itemIndex] = doubleField.value;
});
return doubleField;
}
else if (elementType == typeof(bool))
{
Toggle toggle = new Toggle();
toggle.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)toggle.userData;
_listView.itemsSource[itemIndex] = toggle.value;
});
return toggle;
}
else if (elementType == typeof(Hash128))
{
Hash128Field hash128Field = new Hash128Field();
hash128Field.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)hash128Field.userData;
_listView.itemsSource[itemIndex] = hash128Field.value;
});
return hash128Field;
}
else if (elementType == typeof(Vector2))
{
Vector2Field vector2Field = new Vector2Field();
vector2Field.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)vector2Field.userData;
_listView.itemsSource[itemIndex] = vector2Field.value;
});
return vector2Field;
}
else if (elementType == typeof(Vector3))
{
Vector3Field vector3Field = new Vector3Field();
vector3Field.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)vector3Field.userData;
_listView.itemsSource[itemIndex] = vector3Field.value;
});
return vector3Field;
}
else if (elementType == typeof(Vector4))
{
Vector4Field vector4Field = new Vector4Field();
vector4Field.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)vector4Field.userData;
_listView.itemsSource[itemIndex] = vector4Field.value;
});
return vector4Field;
}
else if (elementType == typeof(Rect))
{
RectField rectField = new RectField();
rectField.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)rectField.userData;
_listView.itemsSource[itemIndex] = rectField.value;
});
return rectField;
}
else if (elementType == typeof(Bounds))
{
BoundsField boundsField = new BoundsField();
boundsField.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)boundsField.userData;
_listView.itemsSource[itemIndex] = boundsField.value;
});
return boundsField;
}
else if (elementType == typeof(Color))
{
ColorField colorField = new ColorField();
colorField.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)colorField.userData;
_listView.itemsSource[itemIndex] = colorField.value;
});
return colorField;
}
else if (elementType == typeof(Gradient))
{
GradientField gradientField = new GradientField();
gradientField.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)gradientField.userData;
_listView.itemsSource[itemIndex] = gradientField.value;
});
return gradientField;
}
else if (elementType == typeof(AnimationCurve))
{
CurveField curveField = new CurveField();
curveField.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)curveField.userData;
_listView.itemsSource[itemIndex] = curveField.value;
});
return curveField;
}
else if (elementType == typeof(UnityEngine.Object))
{
ObjectField objectField = new ObjectField();
objectField.objectType = typeof(UnityEngine.Object);
objectField.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)objectField.userData;
_listView.itemsSource[itemIndex] = objectField.value;
});
return objectField;
}
else if (elementType.IsEnum)
{
EnumField enumField = new EnumField();
enumField.RegisterValueChangedCallback(evt =>
{
int itemIndex = (int)enumField.userData;
_listView.itemsSource[itemIndex] = enumField.value;
});
return enumField;
}
else
{
Label label = new Label();
label.text = $"Not support element type : {elementType.Name}";
return label;
}
}
/// <summary>
/// 绑定元素
/// </summary>
private void BindListViewElement(VisualElement listViewElement, int index)
{
if (BindElementCallback != null)
{
BindElementCallback.Invoke(listViewElement, index);
return;
}
var elementValue = _listView.itemsSource[index];
string elementName = GetElementName(index);
Type elementType = GetElementType();
if (elementType == typeof(string))
{
TextField textField = listViewElement as TextField;
textField.userData = index;
textField.label = elementName;
textField.SetValueWithoutNotify(elementValue as string);
}
else if (elementType == typeof(int))
{
IntegerField intField = listViewElement as IntegerField;
intField.userData = index;
intField.label = elementName;
intField.SetValueWithoutNotify((int)elementValue);
}
else if (elementType == typeof(long))
{
LongField longField = listViewElement as LongField;
longField.userData = index;
longField.label = elementName;
longField.SetValueWithoutNotify((long)elementValue);
}
else if (elementType == typeof(float))
{
FloatField floatField = listViewElement as FloatField;
floatField.userData = index;
floatField.label = elementName;
floatField.SetValueWithoutNotify((float)elementValue);
}
else if (elementType == typeof(double))
{
DoubleField doubleField = listViewElement as DoubleField;
doubleField.userData = index;
doubleField.label = elementName;
doubleField.SetValueWithoutNotify((double)elementValue);
}
else if (elementType == typeof(bool))
{
Toggle toggle = listViewElement as Toggle;
toggle.userData = index;
toggle.label = elementName;
toggle.SetValueWithoutNotify((bool)elementValue);
}
else if (elementType == typeof(Hash128))
{
Hash128Field hash128Field = listViewElement as Hash128Field;
hash128Field.userData = index;
hash128Field.label = elementName;
hash128Field.SetValueWithoutNotify((Hash128)elementValue);
}
else if (elementType == typeof(Vector2))
{
Vector2Field vector2Field = listViewElement as Vector2Field;
vector2Field.userData = index;
vector2Field.label = elementName;
vector2Field.SetValueWithoutNotify((Vector2)elementValue);
}
else if (elementType == typeof(Vector3))
{
Vector3Field vector3Field = listViewElement as Vector3Field;
vector3Field.userData = index;
vector3Field.label = elementName;
vector3Field.SetValueWithoutNotify((Vector3)elementValue);
}
else if (elementType == typeof(Vector4))
{
Vector4Field vector4Field = listViewElement as Vector4Field;
vector4Field.userData = index;
vector4Field.label = elementName;
vector4Field.SetValueWithoutNotify((Vector4)elementValue);
}
else if (elementType == typeof(Rect))
{
RectField rectField = listViewElement as RectField;
rectField.userData = index;
rectField.label = elementName;
rectField.SetValueWithoutNotify((Rect)elementValue);
}
else if (elementType == typeof(Bounds))
{
BoundsField boundsField = listViewElement as BoundsField;
boundsField.userData = index;
boundsField.label = elementName;
boundsField.SetValueWithoutNotify((Bounds)elementValue);
}
else if (elementType == typeof(Color))
{
ColorField colorField = listViewElement as ColorField;
colorField.userData = index;
colorField.label = elementName;
colorField.SetValueWithoutNotify((Color)elementValue);
}
else if (elementType == typeof(Gradient))
{
GradientField gradientField = listViewElement as GradientField;
gradientField.userData = index;
gradientField.label = elementName;
gradientField.SetValueWithoutNotify((Gradient)elementValue);
}
else if (elementType == typeof(AnimationCurve))
{
CurveField curveField = listViewElement as CurveField;
curveField.userData = index;
curveField.label = elementName;
curveField.SetValueWithoutNotify((AnimationCurve)elementValue);
}
else if (elementType == typeof(UnityEngine.Object))
{
ObjectField objectField = listViewElement as ObjectField;
objectField.userData = index;
objectField.label = elementName;
objectField.SetValueWithoutNotify(elementValue as UnityEngine.Object);
}
else if (elementType.IsEnum)
{
EnumField enumField = listViewElement as EnumField;
enumField.userData = index;
enumField.label = elementName;
enumField.Init((Enum)elementValue);
enumField.SetValueWithoutNotify((Enum)elementValue);
}
else
{
}
}
private Type GetElementType()
{
Type elementType = _listView.itemsSource.GetType().GetGenericArguments()[0];
return elementType;
}
private object GetElementDefaultValue()
{
Type type = GetElementType();
if (type.IsValueType)
{
return Activator.CreateInstance(type);
}
return null;
}
private string GetElementName(int index)
{
return $"Element {index}";
}
private void RefreshRemoveButton()
{
if (_listView.itemsSource == null)
{
_removeButton.SetEnabled(false);
return;
}
// 注意:数据列表移除元素的时候有可能会越界!
if (_listView.selectedIndex >= _listView.itemsSource.Count)
_listView.ClearSelection();
if (_listView.selectedIndex >= 0)
_removeButton.SetEnabled(true);
else
_removeButton.SetEnabled(false);
}
private void RefreshFoldoutName()
{
if (_listView.itemsSource == null)
{
if (_foldout != null)
_foldout.text = _headerName;
if (_headerLabel != null)
_headerLabel.text = _headerName;
}
else
{
if (_foldout != null)
_foldout.text = _headerName + $" ({_listView.itemsSource.Count}) ";
if (_headerLabel != null)
_headerLabel.text = _headerName + $" ({_listView.itemsSource.Count}) ";
}
}
}
}
#endif

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 640ec7bd883b8314db53b508278aea6e
guid: 111ec0d18888d7e4396b2192f7b4f347
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -9,15 +9,9 @@ namespace YooAsset.Editor
{
public class ResizeHandle : VisualElement
{
#if UNITY_6000_0_OR_NEWER
public new class UxmlFactory : UxmlElementAttribute
{
}
#else
public new class UxmlFactory : UxmlFactory<ResizeHandle, UxmlTraits>
{
}
#endif
private bool _isResizing = false;
private float _initialWidth;

View File

@@ -15,15 +15,9 @@ namespace YooAsset.Editor
/// </summary>
public class TableView : VisualElement
{
#if UNITY_6000_0_OR_NEWER
public new class UxmlFactory : UxmlElementAttribute
{
}
#else
public new class UxmlFactory : UxmlFactory<TableView, UxmlTraits>
{
}
#endif
private readonly Toolbar _toolbar;
private readonly ListView _listView;
@@ -90,10 +84,16 @@ namespace YooAsset.Editor
public TableView()
{
_toolbar = new Toolbar();
this.Add(_toolbar);
this.style.flexShrink = 1f;
this.style.flexGrow = 1f;
// 定义标题栏
_toolbar = new Toolbar();
// 定义列表视图
_listView = new ListView();
_listView.style.flexShrink = 1f;
_listView.style.flexGrow = 1f;
_listView.makeItem = MakeListViewElement;
_listView.bindItem = BindListViewElement;
_listView.selectionType = SelectionType.Multiple;
@@ -107,6 +107,7 @@ namespace YooAsset.Editor
_listView.onSelectionChanged += OnSelectionChanged;
#endif
this.Add(_toolbar);
this.Add(_listView);
}

View File

@@ -21,7 +21,7 @@ namespace YooAsset
}
protected readonly Dictionary<string, FileWrapper> _wrappers = new Dictionary<string, FileWrapper>(10000);
protected readonly Dictionary<string, string> _buildinFilePaths = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _buildinFilePathMapping = new Dictionary<string, string>(10000);
protected IFileSystem _unpackFileSystem;
protected string _packageRoot;
@@ -309,10 +309,10 @@ namespace YooAsset
}
public string GetBuildinFileLoadPath(PackageBundle bundle)
{
if (_buildinFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_buildinFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(_packageRoot, bundle.FileName);
_buildinFilePaths.Add(bundle.BundleGUID, filePath);
_buildinFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}

View File

@@ -11,10 +11,10 @@ namespace YooAsset
/// </summary>
internal class DefaultCacheFileSystem : IFileSystem
{
protected readonly Dictionary<string, RecordFileElement> _wrappers = new Dictionary<string, RecordFileElement>(10000);
protected readonly Dictionary<string, string> _bundleDataFilePaths = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _bundleInfoFilePaths = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _tempFilePaths = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, RecordFileElement> _records = new Dictionary<string, RecordFileElement>(10000);
protected readonly Dictionary<string, string> _bundleDataFilePathMapping = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _bundleInfoFilePathMapping = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _tempFilePathMapping = new Dictionary<string, string>(10000);
protected DefaultCacheDownloadCenter _downloadCenter;
protected string _packageRoot;
@@ -45,7 +45,7 @@ namespace YooAsset
{
get
{
return _wrappers.Count;
return _records.Count;
}
}
@@ -245,7 +245,7 @@ namespace YooAsset
}
public virtual bool Exists(PackageBundle bundle)
{
return _wrappers.ContainsKey(bundle.BundleGUID);
return _records.ContainsKey(bundle.BundleGUID);
}
public virtual bool NeedDownload(PackageBundle bundle)
{
@@ -330,60 +330,60 @@ namespace YooAsset
#region
public List<string> GetAllCachedBundleGUIDs()
{
return _wrappers.Keys.ToList();
return _records.Keys.ToList();
}
public string GetTempFilePath(PackageBundle bundle)
{
if (_tempFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_tempFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(_tempFilesRoot, bundle.BundleGUID);
_tempFilePaths.Add(bundle.BundleGUID, filePath);
_tempFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
public string GetBundleDataFilePath(PackageBundle bundle)
{
if (_bundleDataFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_bundleDataFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
string folderName = bundle.FileHash.Substring(0, 2);
filePath = PathUtility.Combine(_cacheBundleFilesRoot, folderName, bundle.BundleGUID, DefaultCacheFileSystemDefine.BundleDataFileName);
if (AppendFileExtension)
filePath += bundle.FileExtension;
_bundleDataFilePaths.Add(bundle.BundleGUID, filePath);
_bundleDataFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
public string GetBundleInfoFilePath(PackageBundle bundle)
{
if (_bundleInfoFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_bundleInfoFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
string folderName = bundle.FileHash.Substring(0, 2);
filePath = PathUtility.Combine(_cacheBundleFilesRoot, folderName, bundle.BundleGUID, DefaultCacheFileSystemDefine.BundleInfoFileName);
_bundleInfoFilePaths.Add(bundle.BundleGUID, filePath);
_bundleInfoFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
public bool IsRecordBundleFile(string bundleGUID)
{
return _wrappers.ContainsKey(bundleGUID);
return _records.ContainsKey(bundleGUID);
}
public bool RecordBundleFile(string bundleGUID, RecordFileElement element)
{
if (_wrappers.ContainsKey(bundleGUID))
if (_records.ContainsKey(bundleGUID))
{
YooLogger.Error($"{nameof(DefaultCacheFileSystem)} has element : {bundleGUID}");
return false;
}
_wrappers.Add(bundleGUID, element);
_records.Add(bundleGUID, element);
return true;
}
public EFileVerifyResult VerifyCacheFile(PackageBundle bundle)
{
if (_wrappers.TryGetValue(bundle.BundleGUID, out RecordFileElement wrapper) == false)
if (_records.TryGetValue(bundle.BundleGUID, out RecordFileElement wrapper) == false)
return EFileVerifyResult.CacheNotFound;
EFileVerifyResult result = FileVerifyHelper.FileVerify(wrapper.DataFilePath, wrapper.DataFileSize, wrapper.DataFileCRC, EFileVerifyLevel.High);
@@ -391,7 +391,7 @@ namespace YooAsset
}
public bool WriteCacheBundleFile(PackageBundle bundle, string copyPath)
{
if (_wrappers.ContainsKey(bundle.BundleGUID))
if (_records.ContainsKey(bundle.BundleGUID))
{
throw new Exception("Should never get here !");
}
@@ -426,7 +426,7 @@ namespace YooAsset
}
public bool DeleteCacheBundleFile(string bundleGUID)
{
if (_wrappers.TryGetValue(bundleGUID, out RecordFileElement wrapper))
if (_records.TryGetValue(bundleGUID, out RecordFileElement wrapper))
{
try
{
@@ -434,7 +434,7 @@ namespace YooAsset
FileInfo fileInfo = new FileInfo(dataFilePath);
if (fileInfo.Exists)
fileInfo.Directory.Delete(true);
_wrappers.Remove(bundleGUID);
_records.Remove(bundleGUID);
return true;
}
catch (Exception e)

View File

@@ -47,6 +47,11 @@ namespace YooAsset
/// 自定义参数:跨域下载服务接口
/// </summary>
public IRemoteServices RemoteServices { private set; get; } = null;
/// <summary>
/// 自定义参数:解密方法类
/// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; }
#endregion
@@ -108,6 +113,10 @@ namespace YooAsset
{
RemoteServices = (IRemoteServices)value;
}
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES)
{
DecryptionServices = (IWebDecryptionServices)value;
}
else
{
YooLogger.Warning($"Invalid parameter : {name}");

View File

@@ -1,6 +1,4 @@

using UnityEngine;
namespace YooAsset
{
internal class DWRFSLoadAssetBundleOperation : FSLoadBundleOperation
@@ -8,13 +6,13 @@ namespace YooAsset
private enum ESteps
{
None,
DownloadFile,
DownloadAssetBundle,
Done,
}
private readonly DefaultWebRemoteFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private DownloadHandlerAssetBundleOperation _downloadhanlderAssetBundleOp;
private DownloadAssetBundleOperation _downloadAssetBundleOp;
private ESteps _steps = ESteps.None;
@@ -25,38 +23,47 @@ namespace YooAsset
}
internal override void InternalOnStart()
{
_steps = ESteps.DownloadFile;
_steps = ESteps.DownloadAssetBundle;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadFile)
if (_steps == ESteps.DownloadAssetBundle)
{
if (_downloadhanlderAssetBundleOp == null)
if (_downloadAssetBundleOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
downloadParam.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
downloadParam.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
_downloadhanlderAssetBundleOp = new DownloadHandlerAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadhanlderAssetBundleOp);
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
}
DownloadProgress = _downloadhanlderAssetBundleOp.DownloadProgress;
DownloadedBytes = _downloadhanlderAssetBundleOp.DownloadedBytes;
Progress = _downloadhanlderAssetBundleOp.Progress;
if (_downloadhanlderAssetBundleOp.IsDone == false)
DownloadProgress = _downloadAssetBundleOp.DownloadProgress;
DownloadedBytes = _downloadAssetBundleOp.DownloadedBytes;
Progress = _downloadAssetBundleOp.Progress;
if (_downloadAssetBundleOp.IsDone == false)
return;
if (_downloadhanlderAssetBundleOp.Status == EOperationStatus.Succeed)
if (_downloadAssetBundleOp.Status == EOperationStatus.Succeed)
{
var assetBundle = _downloadhanlderAssetBundleOp.Result;
if(assetBundle == null)
var assetBundle = _downloadAssetBundleOp.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(DownloadHandlerAssetBundleOperation)} loaded asset bundle is null !";
Error = $"{nameof(DownloadAssetBundleOperation)} loaded asset bundle is null !";
}
else
{
@@ -69,7 +76,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadhanlderAssetBundleOp.Error;
Error = _downloadAssetBundleOp.Error;
}
}
}
@@ -85,10 +92,10 @@ namespace YooAsset
}
public override void AbortDownloadOperation()
{
if (_steps == ESteps.DownloadFile)
if (_steps == ESteps.DownloadAssetBundle)
{
if (_downloadhanlderAssetBundleOp != null)
_downloadhanlderAssetBundleOp.SetAbort();
if (_downloadAssetBundleOp != null)
_downloadAssetBundleOp.SetAbort();
}
}
}

View File

@@ -21,7 +21,7 @@ namespace YooAsset
}
protected readonly Dictionary<string, FileWrapper> _wrappers = new Dictionary<string, FileWrapper>(10000);
protected readonly Dictionary<string, string> _webFilePaths = new Dictionary<string, string>(10000);
protected readonly Dictionary<string, string> _webFilePathMapping = new Dictionary<string, string>(10000);
protected string _webPackageRoot = string.Empty;
/// <summary>
@@ -56,6 +56,11 @@ namespace YooAsset
/// 禁用Unity的网络缓存
/// </summary>
public bool DisableUnityWebCache { private set; get; } = false;
/// <summary>
/// 自定义参数:解密方法类
/// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; }
#endregion
@@ -113,6 +118,10 @@ namespace YooAsset
{
DisableUnityWebCache = (bool)value;
}
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES)
{
DecryptionServices = (IWebDecryptionServices)value;
}
else
{
YooLogger.Warning($"Invalid parameter : {name}");
@@ -173,10 +182,10 @@ namespace YooAsset
}
public string GetWebFileLoadPath(PackageBundle bundle)
{
if (_webFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_webFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(_webPackageRoot, bundle.FileName);
_webFilePaths.Add(bundle.BundleGUID, filePath);
_webFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}

View File

@@ -6,13 +6,13 @@ namespace YooAsset
private enum ESteps
{
None,
DownloadFile,
DownloadAssetBundle,
Done,
}
private readonly DefaultWebServerFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private DownloadHandlerAssetBundleOperation _downloadhanlderAssetBundleOp;
private DownloadAssetBundleOperation _downloadAssetBundleOp;
private ESteps _steps = ESteps.None;
@@ -23,39 +23,48 @@ namespace YooAsset
}
internal override void InternalOnStart()
{
_steps = ESteps.DownloadFile;
_steps = ESteps.DownloadAssetBundle;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.DownloadFile)
if (_steps == ESteps.DownloadAssetBundle)
{
if (_downloadhanlderAssetBundleOp == null)
if (_downloadAssetBundleOp == null)
{
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
string fileLoadPath = _fileSystem.GetWebFileLoadPath(_bundle);
downloadParam.MainURL = DownloadSystemHelper.ConvertToWWWPath(fileLoadPath);
downloadParam.FallbackURL = downloadParam.MainURL;
_downloadhanlderAssetBundleOp = new DownloadHandlerAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadhanlderAssetBundleOp);
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(true, _fileSystem.DecryptionServices, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadWebNormalAssetBundleOperation(_fileSystem.DisableUnityWebCache, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
}
DownloadProgress = _downloadhanlderAssetBundleOp.DownloadProgress;
DownloadedBytes = _downloadhanlderAssetBundleOp.DownloadedBytes;
Progress = _downloadhanlderAssetBundleOp.Progress;
if (_downloadhanlderAssetBundleOp.IsDone == false)
DownloadProgress = _downloadAssetBundleOp.DownloadProgress;
DownloadedBytes = _downloadAssetBundleOp.DownloadedBytes;
Progress = _downloadAssetBundleOp.Progress;
if (_downloadAssetBundleOp.IsDone == false)
return;
if (_downloadhanlderAssetBundleOp.Status == EOperationStatus.Succeed)
if (_downloadAssetBundleOp.Status == EOperationStatus.Succeed)
{
var assetBundle = _downloadhanlderAssetBundleOp.Result;
var assetBundle = _downloadAssetBundleOp.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(DownloadHandlerAssetBundleOperation)} loaded asset bundle is null !";
Error = $"{nameof(DownloadAssetBundleOperation)} loaded asset bundle is null !";
}
else
{
@@ -68,7 +77,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadhanlderAssetBundleOp.Error;
Error = _downloadAssetBundleOp.Error;
}
}
}
@@ -84,10 +93,10 @@ namespace YooAsset
}
public override void AbortDownloadOperation()
{
if (_steps == ESteps.DownloadFile)
if (_steps == ESteps.DownloadAssetBundle)
{
if (_downloadhanlderAssetBundleOp != null)
_downloadhanlderAssetBundleOp.SetAbort();
if (_downloadAssetBundleOp != null)
_downloadAssetBundleOp.SetAbort();
}
}
}

View File

@@ -109,11 +109,13 @@ namespace YooAsset
/// <summary>
/// 创建默认的WebServer文件系统参数
/// </summary>
/// <param name="decryptionServices">加密文件解密服务类</param>
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</param>
public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(bool disableUnityWebCache = false)
public static FileSystemParameters CreateDefaultWebServerFileSystemParameters(IWebDecryptionServices decryptionServices = null, bool disableUnityWebCache = false)
{
string fileSystemClass = typeof(DefaultWebServerFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache);
return fileSystemParams;
}
@@ -122,12 +124,14 @@ namespace YooAsset
/// 创建默认的WebRemote文件系统参数
/// </summary>
/// <param name="remoteServices">远端资源地址查询服务类</param>
/// <param name="decryptionServices">加密文件解密服务类</param>
/// <param name="disableUnityWebCache">禁用Unity的网络缓存</param>
public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteServices remoteServices, bool disableUnityWebCache = false)
public static FileSystemParameters CreateDefaultWebRemoteFileSystemParameters(IRemoteServices remoteServices, IWebDecryptionServices decryptionServices = null, bool disableUnityWebCache = false)
{
string fileSystemClass = typeof(DefaultWebRemoteFileSystem).FullName;
var fileSystemParams = new FileSystemParameters(fileSystemClass, null);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DISABLE_UNITY_WEB_CACHE, disableUnityWebCache);
return fileSystemParams;
}

View File

@@ -20,7 +20,7 @@ namespace YooAsset
/// <summary>
/// 初始化缓存系统
/// 初始化文件系统
/// </summary>
FSInitializeFileSystemOperation InitializeFileSystemAsync();
@@ -30,7 +30,7 @@ namespace YooAsset
FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout);
/// <summary>
/// 查询最新的版本
/// 查询包裹版本
/// </summary>
FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout);
@@ -40,7 +40,7 @@ namespace YooAsset
FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, string clearMode, object clearParam);
/// <summary>
/// 下载远端文件
/// 下载Bundle文件
/// </summary>
FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadParam param);

View File

@@ -0,0 +1,14 @@
using UnityEngine;
using UnityEngine.Networking;
namespace YooAsset
{
internal abstract class DownloadAssetBundleOperation : DefaultDownloadFileOperation
{
internal DownloadAssetBundleOperation(PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
}
public AssetBundle Result;
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e4420bd73f37dec468a9b23425be68f2
guid: 0f65d2f6038b95246b7a09cec4055b3a
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,157 @@
using UnityEngine;
using UnityEngine.Networking;
namespace YooAsset
{
internal class DownloadWebEncryptAssetBundleOperation : DownloadAssetBundleOperation
{
private readonly bool _checkTimeout;
private readonly IWebDecryptionServices _decryptionServices;
private DownloadHandlerBuffer _downloadhandler;
private ESteps _steps = ESteps.None;
internal DownloadWebEncryptAssetBundleOperation(bool checkTimeout, IWebDecryptionServices decryptionServices, PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
_checkTimeout = checkTimeout;
_decryptionServices = decryptionServices;
}
internal override void InternalOnStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 重置变量
ResetRequestFiled();
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
if (_checkTimeout)
CheckRequestTimeout();
return;
}
// 检查网络错误
if (CheckRequestResult())
{
if (_decryptionServices == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The {nameof(IWebDecryptionServices)} is null !";
YooLogger.Error(Error);
return;
}
var fileData = _downloadhandler.data;
if (fileData == null || fileData.Length == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The download handler data is null or empty !";
YooLogger.Error(Error);
return;
}
AssetBundle assetBundle = LoadEncryptedAssetBundle(fileData);
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Download handler asset bundle object is null !";
}
else
{
_steps = ESteps.Done;
Result = assetBundle;
Status = EOperationStatus.Succeed;
}
}
else
{
_steps = ESteps.TryAgain;
}
// 注意:最终释放请求器
DisposeWebRequest();
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
FailedTryAgain--;
_steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
}
}
}
internal override void InternalOnAbort()
{
_steps = ESteps.Done;
DisposeWebRequest();
}
private void CreateWebRequest()
{
_downloadhandler = new DownloadHandlerBuffer();
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
_webRequest.downloadHandler = _downloadhandler;
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
/// <summary>
/// 加载加密资源文件
/// </summary>
private AssetBundle LoadEncryptedAssetBundle(byte[] fileData)
{
var fileInfo = new WebDecryptFileInfo();
fileInfo.BundleName = Bundle.BundleName;
fileInfo.FileLoadCRC = Bundle.UnityCRC;
fileInfo.FileData = fileData;
var decryptResult = _decryptionServices.LoadAssetBundle(fileInfo);
return decryptResult.Result;
}
}
}

View File

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

View File

@@ -3,16 +3,13 @@ using UnityEngine.Networking;
namespace YooAsset
{
internal class DownloadHandlerAssetBundleOperation : DefaultDownloadFileOperation
internal class DownloadWebNormalAssetBundleOperation : DownloadAssetBundleOperation
{
private readonly bool _disableUnityWebCache;
private DownloadHandlerAssetBundle _downloadhandler;
private ESteps _steps = ESteps.None;
public AssetBundle Result { private set; get; }
internal DownloadHandlerAssetBundleOperation(bool disableUnityWebCache, PackageBundle bundle, DownloadParam param) : base(bundle, param)
internal DownloadWebNormalAssetBundleOperation(bool disableUnityWebCache, PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
_disableUnityWebCache = disableUnityWebCache;
}
@@ -55,12 +52,12 @@ namespace YooAsset
// 检查网络错误
if (CheckRequestResult())
{
var assetBundle = _downloadhandler.assetBundle;
AssetBundle assetBundle = _downloadhandler.assetBundle;
if (assetBundle == null)
{
_steps = ESteps.Done;
Error = "Download handler asset bundle object is null !";
Status = EOperationStatus.Failed;
Error = "Download handler asset bundle object is null !";
}
else
{
@@ -106,7 +103,7 @@ namespace YooAsset
private void CreateWebRequest()
{
_downloadhandler = CreateDownloadHandler();
_downloadhandler = CreateWebDownloadHandler();
_webRequest = DownloadSystemHelper.NewUnityWebRequestGet(_requestURL);
_webRequest.downloadHandler = _downloadhandler;
_webRequest.disposeDownloadHandlerOnDispose = true;
@@ -121,7 +118,7 @@ namespace YooAsset
_webRequest = null;
}
}
private DownloadHandlerAssetBundle CreateDownloadHandler()
private DownloadHandlerAssetBundle CreateWebDownloadHandler()
{
if (_disableUnityWebCache)
{

View File

@@ -13,6 +13,11 @@ namespace YooAsset
private static Stopwatch _watch;
private static long _frameTime;
/// <summary>
/// 快速启动模式
/// </summary>
public static bool QuickStartMode = false;
/// <summary>
/// 异步操作的最小时间片段
/// </summary>
@@ -136,6 +141,11 @@ namespace YooAsset
_newList.Add(operation);
operation.SetPackageName(packageName);
operation.SetStart();
if (QuickStartMode)
{
operation.InternalOnUpdate();
}
}
}
}

View File

@@ -153,7 +153,23 @@ namespace YooAsset
if (IsDone == false)
return false;
return RefCount <= 0;
if (RefCount > 0)
return false;
#region YOOASSET_LEGACY_DEPENDENCY
// 检查引用链上的资源包是否已经全部销毁
// 注意:互相引用的资源包无法卸载!
if (LoadBundleInfo.Bundle.ReferenceBundleIDs.Length > 0)
{
foreach (var bundleID in LoadBundleInfo.Bundle.ReferenceBundleIDs)
{
if (_resourceManager.CheckBundleDestroyed(bundleID) == false)
return false;
}
}
#endregion
return true;
}
/// <summary>

View File

@@ -3,38 +3,88 @@ using UnityEngine;
namespace YooAsset
{
public sealed class UnloadAllAssetsOptions
{
/// <summary>
/// 释放所有资源句柄,防止卸载过程中触发完成回调!
/// </summary>
public bool ReleaseAllHandles = false;
/// <summary>
/// 卸载过程中锁定加载操作,防止新的任务请求!
/// </summary>
public bool LockLoadOperation = false;
}
public sealed class UnloadAllAssetsOperation : AsyncOperationBase
{
private enum ESteps
{
None,
CheckOptions,
ReleaseAll,
AbortDownload,
CheckLoading,
UnloadAll,
DestroyAll,
Done,
}
private readonly ResourceManager _resManager;
private readonly UnloadAllAssetsOptions _options;
private ESteps _steps = ESteps.None;
internal UnloadAllAssetsOperation(ResourceManager resourceManager)
internal UnloadAllAssetsOperation(ResourceManager resourceManager, UnloadAllAssetsOptions options)
{
_resManager = resourceManager;
_options = options;
}
internal override void InternalOnStart()
{
_steps = ESteps.AbortDownload;
_steps = ESteps.CheckOptions;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CheckOptions)
{
if (_options == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"{nameof(UnloadAllAssetsOptions)} is null.";
return;
}
// 设置锁定状态
if (_options.LockLoadOperation)
_resManager.LockLoadOperation = true;
_steps = ESteps.ReleaseAll;
}
if (_steps == ESteps.ReleaseAll)
{
// 清空所有场景句柄
_resManager.SceneHandles.Clear();
// 释放所有资源句柄
if (_options.ReleaseAllHandles)
{
foreach (var provider in _resManager.ProviderDic.Values)
{
provider.ReleaseAllHandles();
}
}
_steps = ESteps.AbortDownload;
}
if (_steps == ESteps.AbortDownload)
{
// 注意:终止所有下载任务
var loaderDic = _resManager._loaderDic;
foreach (var loader in loaderDic.Values)
foreach (var loader in _resManager.LoaderDic.Values)
{
loader.AbortDownloadOperation();
}
@@ -44,44 +94,32 @@ namespace YooAsset
if (_steps == ESteps.CheckLoading)
{
// 注意:等待所有任务完成
var providerDic = _resManager._providerDic;
foreach (var provider in providerDic.Values)
foreach (var provider in _resManager.ProviderDic.Values)
{
if (provider.IsDone == false)
return;
}
_steps = ESteps.UnloadAll;
_steps = ESteps.DestroyAll;
}
if (_steps == ESteps.UnloadAll)
if (_steps == ESteps.DestroyAll)
{
var loaderDic = _resManager._loaderDic;
var providerDic = _resManager._providerDic;
// 清空所有场景句柄
_resManager._sceneHandles.Clear();
// 释放所有资源句柄
foreach (var provider in providerDic.Values)
{
provider.ReleaseAllHandles();
}
// 强制销毁资源提供者
foreach (var provider in providerDic.Values)
foreach (var provider in _resManager.ProviderDic.Values)
{
provider.DestroyProvider();
}
// 强制销毁文件加载器
foreach (var loader in loaderDic.Values)
foreach (var loader in _resManager.LoaderDic.Values)
{
loader.DestroyLoader();
}
// 清空数据
providerDic.Clear();
loaderDic.Clear();
_resManager.ProviderDic.Clear();
_resManager.LoaderDic.Clear();
_resManager.LockLoadOperation = false;
// 注意:调用底层接口释放所有资源
Resources.UnloadUnusedAssets();

View File

@@ -31,17 +31,16 @@ namespace YooAsset
if (_steps == ESteps.UnloadUnused)
{
var loaderDic = _resManager._loaderDic;
var removeList = new List<LoadBundleFileOperation>(loaderDic.Count);
var removeList = new List<LoadBundleFileOperation>(_resManager.LoaderDic.Count);
// 注意:优先销毁资源提供者
foreach (var loader in loaderDic.Values)
foreach (var loader in _resManager.LoaderDic.Values)
{
loader.TryDestroyProviders();
}
// 获取销毁列表
foreach (var loader in loaderDic.Values)
foreach (var loader in _resManager.LoaderDic.Values)
{
if (loader.CanDestroyLoader())
{
@@ -54,13 +53,9 @@ namespace YooAsset
{
string bundleName = loader.LoadBundleInfo.Bundle.BundleName;
loader.DestroyLoader();
_resManager._loaderDic.Remove(bundleName);
_resManager.LoaderDic.Remove(bundleName);
}
// 注意:调用底层接口释放所有资源
if (removeList.Count > 0)
Resources.UnloadUnusedAssets();
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}

View File

@@ -86,7 +86,7 @@ namespace YooAsset
// 依赖资源包加载器集合
var dependLoaders = manager.CreateDependBundleFileLoaders(assetInfo);
if(dependLoaders.Count > 0)
if (dependLoaders.Count > 0)
_bundleLoaders.AddRange(dependLoaders);
// 增加引用计数

View File

@@ -9,9 +9,9 @@ namespace YooAsset
{
internal class ResourceManager
{
internal readonly Dictionary<string, ProviderOperation> _providerDic = new Dictionary<string, ProviderOperation>(5000);
internal readonly Dictionary<string, LoadBundleFileOperation> _loaderDic = new Dictionary<string, LoadBundleFileOperation>(5000);
internal readonly List<SceneHandle> _sceneHandles = new List<SceneHandle>(100);
internal readonly Dictionary<string, ProviderOperation> ProviderDic = new Dictionary<string, ProviderOperation>(5000);
internal readonly Dictionary<string, LoadBundleFileOperation> LoaderDic = new Dictionary<string, LoadBundleFileOperation>(5000);
internal readonly List<SceneHandle> SceneHandles = new List<SceneHandle>(100);
private long _sceneCreateIndex = 0;
private IBundleQuery _bundleQuery;
@@ -20,6 +20,11 @@ namespace YooAsset
/// </summary>
public readonly string PackageName;
/// <summary>
/// 锁定加载操作
/// </summary>
public bool LockLoadOperation = false;
public ResourceManager(string packageName)
{
@@ -64,7 +69,7 @@ namespace YooAsset
{
string bundleName = mainLoader.LoadBundleInfo.Bundle.BundleName;
mainLoader.DestroyLoader();
_loaderDic.Remove(bundleName);
LoaderDic.Remove(bundleName);
}
}
@@ -79,7 +84,7 @@ namespace YooAsset
{
string bundleName = dependLoader.LoadBundleInfo.Bundle.BundleName;
dependLoader.DestroyLoader();
_loaderDic.Remove(bundleName);
LoaderDic.Remove(bundleName);
}
}
}
@@ -92,6 +97,15 @@ namespace YooAsset
/// </summary>
public SceneHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneParameters loadSceneParams, bool suspendLoad, uint priority)
{
if (LockLoadOperation)
{
string error = $"The load operation locked !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompletedWithError(error);
return completedProvider.CreateHandle<SceneHandle>();
}
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load scene ! {assetInfo.Error}");
@@ -106,14 +120,14 @@ namespace YooAsset
{
provider = new SceneProvider(this, providerGUID, assetInfo, loadSceneParams, suspendLoad);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
ProviderDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
provider.Priority = priority;
var handle = provider.CreateHandle<SceneHandle>();
handle.PackageName = PackageName;
_sceneHandles.Add(handle);
SceneHandles.Add(handle);
return handle;
}
@@ -122,6 +136,15 @@ namespace YooAsset
/// </summary>
public AssetHandle LoadAssetAsync(AssetInfo assetInfo, uint priority)
{
if (LockLoadOperation)
{
string error = $"The load operation locked !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompletedWithError(error);
return completedProvider.CreateHandle<AssetHandle>();
}
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load asset ! {assetInfo.Error}");
@@ -136,7 +159,7 @@ namespace YooAsset
{
provider = new AssetProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
ProviderDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
@@ -149,6 +172,15 @@ namespace YooAsset
/// </summary>
public SubAssetsHandle LoadSubAssetsAsync(AssetInfo assetInfo, uint priority)
{
if (LockLoadOperation)
{
string error = $"The load operation locked !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompletedWithError(error);
return completedProvider.CreateHandle<SubAssetsHandle>();
}
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load sub assets ! {assetInfo.Error}");
@@ -163,7 +195,7 @@ namespace YooAsset
{
provider = new SubAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
ProviderDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
@@ -176,6 +208,15 @@ namespace YooAsset
/// </summary>
public AllAssetsHandle LoadAllAssetsAsync(AssetInfo assetInfo, uint priority)
{
if (LockLoadOperation)
{
string error = $"The load operation locked !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompletedWithError(error);
return completedProvider.CreateHandle<AllAssetsHandle>();
}
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load all assets ! {assetInfo.Error}");
@@ -190,7 +231,7 @@ namespace YooAsset
{
provider = new AllAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
ProviderDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
@@ -203,6 +244,15 @@ namespace YooAsset
/// </summary>
public RawFileHandle LoadRawFileAsync(AssetInfo assetInfo, uint priority)
{
if (LockLoadOperation)
{
string error = $"The load operation locked !";
YooLogger.Error(error);
CompletedProvider completedProvider = new CompletedProvider(this, assetInfo);
completedProvider.SetCompletedWithError(error);
return completedProvider.CreateHandle<RawFileHandle>();
}
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load raw file ! {assetInfo.Error}");
@@ -217,7 +267,7 @@ namespace YooAsset
{
provider = new RawFileProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerDic.Add(providerGUID, provider);
ProviderDic.Add(providerGUID, provider);
OperationSystem.StartOperation(PackageName, provider);
}
@@ -245,12 +295,20 @@ namespace YooAsset
{
foreach (var provider in removeList)
{
_providerDic.Remove(provider.ProviderGUID);
ProviderDic.Remove(provider.ProviderGUID);
}
}
internal bool CheckBundleDestroyed(int bundleID)
{
string bundleName = _bundleQuery.GetMainBundleName(bundleID);
var bundleFileLoader = TryGetBundleFileLoader(bundleName);
if (bundleFileLoader == null)
return true;
return bundleFileLoader.IsDestroyed;
}
internal bool HasAnyLoader()
{
return _loaderDic.Count > 0;
return LoaderDic.Count > 0;
}
private LoadBundleFileOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo)
@@ -264,19 +322,19 @@ namespace YooAsset
// 新增下载需求
loaderOperation = new LoadBundleFileOperation(this, bundleInfo);
OperationSystem.StartOperation(PackageName, loaderOperation);
_loaderDic.Add(bundleName, loaderOperation);
LoaderDic.Add(bundleName, loaderOperation);
return loaderOperation;
}
private LoadBundleFileOperation TryGetBundleFileLoader(string bundleName)
{
if (_loaderDic.TryGetValue(bundleName, out LoadBundleFileOperation value))
if (LoaderDic.TryGetValue(bundleName, out LoadBundleFileOperation value))
return value;
else
return null;
}
private ProviderOperation TryGetAssetProvider(string providerGUID)
{
if (_providerDic.TryGetValue(providerGUID, out ProviderOperation value))
if (ProviderDic.TryGetValue(providerGUID, out ProviderOperation value))
return value;
else
return null;
@@ -284,7 +342,7 @@ namespace YooAsset
private void OnSceneUnloaded(Scene scene)
{
List<SceneHandle> removeList = new List<SceneHandle>();
foreach (var sceneHandle in _sceneHandles)
foreach (var sceneHandle in SceneHandles)
{
if (sceneHandle.IsValid)
{
@@ -297,15 +355,15 @@ namespace YooAsset
}
foreach (var sceneHandle in removeList)
{
_sceneHandles.Remove(sceneHandle);
SceneHandles.Remove(sceneHandle);
}
}
#region
internal List<DebugProviderInfo> GetDebugReportInfos()
{
List<DebugProviderInfo> result = new List<DebugProviderInfo>(_providerDic.Count);
foreach (var provider in _providerDic.Values)
List<DebugProviderInfo> result = new List<DebugProviderInfo>(ProviderDic.Count);
foreach (var provider in ProviderDic.Values)
{
DebugProviderInfo providerInfo = new DebugProviderInfo();
providerInfo.AssetPath = provider.MainAssetInfo.AssetPath;

View File

@@ -1,7 +1,7 @@

namespace YooAsset
{
internal enum EBuildBundleType
public enum EBuildBundleType
{
/// <summary>
/// 未知类型

View File

@@ -13,6 +13,11 @@ namespace YooAsset
/// </summary>
BundleInfo[] GetDependBundleInfos(AssetInfo assetPath);
/// <summary>
/// 获取主资源包名称
/// </summary>
string GetMainBundleName(int bundleID);
/// <summary>
/// 获取主资源包名称
/// </summary>

View File

@@ -35,6 +35,7 @@ namespace YooAsset
buffer.WriteUTF8(manifest.FileVersion);
// 写入文件头信息
buffer.WriteBool(manifest.LegacyDependency);
buffer.WriteBool(manifest.EnableAddressable);
buffer.WriteBool(manifest.LocationToLower);
buffer.WriteBool(manifest.IncludeAssetGUID);
@@ -55,6 +56,7 @@ namespace YooAsset
buffer.WriteUTF8(packageAsset.AssetGUID);
buffer.WriteUTF8Array(packageAsset.AssetTags);
buffer.WriteInt32(packageAsset.BundleID);
buffer.WriteInt32Array(packageAsset.DependBundleIDs);
}
// 写入资源包列表
@@ -70,6 +72,7 @@ namespace YooAsset
buffer.WriteBool(packageBundle.Encrypted);
buffer.WriteUTF8Array(packageBundle.Tags);
buffer.WriteInt32Array(packageBundle.DependIDs);
buffer.WriteInt32Array(packageBundle.ReferenceBundleIDs);
}
// 写入文件流
@@ -108,6 +111,7 @@ namespace YooAsset
{
// 读取文件头信息
manifest.FileVersion = fileVersion;
manifest.LegacyDependency = buffer.ReadBool();
manifest.EnableAddressable = buffer.ReadBool();
manifest.LocationToLower = buffer.ReadBool();
manifest.IncludeAssetGUID = buffer.ReadBool();
@@ -133,6 +137,7 @@ namespace YooAsset
packageAsset.AssetGUID = buffer.ReadUTF8();
packageAsset.AssetTags = buffer.ReadUTF8Array();
packageAsset.BundleID = buffer.ReadInt32();
packageAsset.DependBundleIDs = buffer.ReadInt32Array();
FillAssetCollection(manifest, packageAsset);
}
@@ -150,6 +155,7 @@ namespace YooAsset
packageBundle.Encrypted = buffer.ReadBool();
packageBundle.Tags = buffer.ReadUTF8Array();
packageBundle.DependIDs = buffer.ReadInt32Array();
packageBundle.ReferenceBundleIDs = buffer.ReadInt32Array();
FillBundleCollection(manifest, packageBundle);
}
}

View File

@@ -78,6 +78,7 @@ namespace YooAsset
// 读取文件头信息
Manifest = new PackageManifest();
Manifest.FileVersion = fileVersion;
Manifest.LegacyDependency = _buffer.ReadBool();
Manifest.EnableAddressable = _buffer.ReadBool();
Manifest.LocationToLower = _buffer.ReadBool();
Manifest.IncludeAssetGUID = _buffer.ReadBool();
@@ -112,6 +113,7 @@ namespace YooAsset
packageAsset.AssetGUID = _buffer.ReadUTF8();
packageAsset.AssetTags = _buffer.ReadUTF8Array();
packageAsset.BundleID = _buffer.ReadInt32();
packageAsset.DependBundleIDs = _buffer.ReadInt32Array();
ManifestTools.FillAssetCollection(Manifest, packageAsset);
_packageAssetCount--;
@@ -146,6 +148,7 @@ namespace YooAsset
packageBundle.Encrypted = _buffer.ReadBool();
packageBundle.Tags = _buffer.ReadUTF8Array();
packageBundle.DependIDs = _buffer.ReadInt32Array();
packageBundle.ReferenceBundleIDs = _buffer.ReadInt32Array();
ManifestTools.FillBundleCollection(Manifest, packageBundle);
_packageBundleCount--;

View File

@@ -31,11 +31,18 @@ namespace YooAsset
/// </summary>
public int BundleID;
#region YOOASSET_LEGACY_DEPENDENCY
/// <summary>
/// 所属资源包名称(仅编辑器有效)
/// 依赖的资源包列表
/// </summary>
public int[] DependBundleIDs;
#endregion
/// <summary>
/// 临时数据对象(仅编辑器有效)
/// </summary>
[NonSerialized]
public string BundleNameInEditor;
public object TempDataInEditor;
/// <summary>
/// 是否包含Tag

View File

@@ -47,6 +47,14 @@ namespace YooAsset
/// </summary>
public int[] DependIDs;
#region YOOASSET_LEGACY_DEPENDENCY
/// <summary>
/// 引用该资源包的资源包列表
/// 说明:谁引用了该资源包
/// </summary>
public int[] ReferenceBundleIDs;
#endregion
/// <summary>
/// 资源包GUID
/// </summary>
@@ -101,6 +109,12 @@ namespace YooAsset
[NonSerialized]
public readonly List<PackageAsset> IncludeMainAssets = new List<PackageAsset>(10);
/// <summary>
/// 临时数据对象(仅编辑器有效)
/// </summary>
[NonSerialized]
public object TempDataInEditor;
public PackageBundle()
{

View File

@@ -17,6 +17,11 @@ namespace YooAsset
/// </summary>
public string FileVersion;
/// <summary>
/// 怀旧版依赖模式
/// </summary>
public bool LegacyDependency;
/// <summary>
/// 启用可寻址资源定位
/// </summary>
@@ -155,16 +160,7 @@ namespace YooAsset
{
if (AssetDic.TryGetValue(assetPath, out PackageAsset packageAsset))
{
int bundleID = packageAsset.BundleID;
if (bundleID >= 0 && bundleID < BundleList.Count)
{
var packageBundle = BundleList[bundleID];
return packageBundle;
}
else
{
throw new Exception($"Invalid bundle id : {bundleID} Asset path : {assetPath}");
}
return GetMainPackageBundle(packageAsset.BundleID);
}
else
{
@@ -172,27 +168,58 @@ namespace YooAsset
}
}
/// <summary>
/// 获取主资源包
/// 注意传入的资源包ID一定合法有效
/// </summary>
public PackageBundle GetMainPackageBundle(int bundleID)
{
if (bundleID >= 0 && bundleID < BundleList.Count)
{
var packageBundle = BundleList[bundleID];
return packageBundle;
}
else
{
throw new Exception($"Invalid bundle id : {bundleID}");
}
}
/// <summary>
/// 获取资源依赖列表
/// 注意:传入的资源路径一定合法有效!
/// </summary>
public PackageBundle[] GetAllDependencies(string assetPath)
{
var packageBundle = GetMainPackageBundle(assetPath);
List<PackageBundle> result = new List<PackageBundle>(packageBundle.DependIDs.Length);
foreach (var dependID in packageBundle.DependIDs)
// YOOASSET_LEGACY_DEPENDENCY
if (LegacyDependency)
{
if (dependID >= 0 && dependID < BundleList.Count)
if (TryGetPackageAsset(assetPath, out PackageAsset packageAsset))
{
var dependBundle = BundleList[dependID];
result.Add(dependBundle);
List<PackageBundle> result = new List<PackageBundle>(packageAsset.DependBundleIDs.Length);
foreach (var dependID in packageAsset.DependBundleIDs)
{
var dependBundle = GetMainPackageBundle(dependID);
result.Add(dependBundle);
}
return result.ToArray();
}
else
{
throw new Exception($"Invalid bundle id : {dependID} Asset path : {assetPath}");
throw new Exception("Should never get here !");
}
}
return result.ToArray();
else
{
var packageBundle = GetMainPackageBundle(assetPath);
List<PackageBundle> result = new List<PackageBundle>(packageBundle.DependIDs.Length);
foreach (var dependID in packageBundle.DependIDs)
{
var dependBundle = GetMainPackageBundle(dependID);
result.Add(dependBundle);
}
return result.ToArray();
}
}
/// <summary>

View File

@@ -135,6 +135,12 @@ namespace YooAsset
}
return result.ToArray();
}
string IBundleQuery.GetMainBundleName(int bundleID)
{
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = ActiveManifest.GetMainPackageBundle(bundleID);
return packageBundle.BundleName;
}
string IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)

View File

@@ -144,6 +144,12 @@ namespace YooAsset
}
return result.ToArray();
}
string IBundleQuery.GetMainBundleName(int bundleID)
{
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = ActiveManifest.GetMainPackageBundle(bundleID);
return packageBundle.BundleName;
}
string IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)

View File

@@ -135,6 +135,12 @@ namespace YooAsset
}
return result.ToArray();
}
string IBundleQuery.GetMainBundleName(int bundleID)
{
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = ActiveManifest.GetMainPackageBundle(bundleID);
return packageBundle.BundleName;
}
string IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)

View File

@@ -163,6 +163,12 @@ namespace YooAsset
}
return result.ToArray();
}
string IBundleQuery.GetMainBundleName(int bundleID)
{
// 注意:如果清单里未找到资源包会抛出异常!
var packageBundle = ActiveManifest.GetMainPackageBundle(bundleID);
return packageBundle.BundleName;
}
string IBundleQuery.GetMainBundleName(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)

View File

@@ -318,9 +318,19 @@ namespace YooAsset
/// 强制回收所有资源
/// </summary>
public UnloadAllAssetsOperation UnloadAllAssetsAsync()
{
var options = new UnloadAllAssetsOptions();
return UnloadAllAssetsAsync(options);
}
/// <summary>
/// 强制回收所有资源
/// </summary>
/// <param name="options">卸载选项</param>
public UnloadAllAssetsOperation UnloadAllAssetsAsync(UnloadAllAssetsOptions options)
{
DebugCheckInitialize();
var operation = new UnloadAllAssetsOperation(_resourceManager);
var operation = new UnloadAllAssetsOperation(_resourceManager, options);
OperationSystem.StartOperation(PackageName, operation);
return operation;
}

View File

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

View File

@@ -29,7 +29,7 @@ namespace YooAsset
/// <summary>
/// 清单文件格式版本
/// </summary>
public const string ManifestFileVersion = "2.2.5";
public const string ManifestFileVersion = "2.3.0";
/// <summary>

View File

@@ -222,6 +222,15 @@ namespace YooAsset
}
OperationSystem.MaxTimeSlice = milliseconds;
}
/// <summary>
/// 设置异步系统参数,快速启动模式的开关
/// 注意:该模式默认开启
/// </summary>
public static void SetOperationSystemQuickStartMode(bool state)
{
OperationSystem.QuickStartMode = state;
}
#endregion
#region

View File

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

View File

@@ -0,0 +1,68 @@
#if UNITY_WEBGL && DOUYINMINIGAME
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
using TTSDK;
namespace YooAsset
{
internal class TTAssetBundleResult : BundleResult
{
private readonly IFileSystem _fileSystem;
private readonly PackageBundle _packageBundle;
private readonly AssetBundle _assetBundle;
public TTAssetBundleResult(IFileSystem fileSystem, PackageBundle packageBundle, AssetBundle assetBundle)
{
_fileSystem = fileSystem;
_packageBundle = packageBundle;
_assetBundle = assetBundle;
}
public override void UnloadBundleFile()
{
if (_assetBundle != null)
{
_assetBundle.TTUnload(true);
}
}
public override string GetBundleFilePath()
{
return _fileSystem.GetBundleFilePath(_packageBundle);
}
public override byte[] ReadBundleFileData()
{
return _fileSystem.ReadBundleFileData(_packageBundle);
}
public override string ReadBundleFileText()
{
return _fileSystem.ReadBundleFileText(_packageBundle);
}
public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo)
{
var operation = new AssetBundleLoadAssetOperation(_packageBundle, _assetBundle, assetInfo);
OperationSystem.StartOperation(_fileSystem.PackageName, operation);
return operation;
}
public override FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo)
{
var operation = new AssetBundleLoadAllAssetsOperation(_packageBundle, _assetBundle, assetInfo);
OperationSystem.StartOperation(_fileSystem.PackageName, operation);
return operation;
}
public override FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo)
{
var operation = new AssetBundleLoadSubAssetsOperation(_packageBundle, _assetBundle, assetInfo);
OperationSystem.StartOperation(_fileSystem.PackageName, operation);
return operation;
}
public override FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad)
{
var operation = new AssetBundleLoadSceneOperation(assetInfo, loadParams, suspendLoad);
OperationSystem.StartOperation(_fileSystem.PackageName, operation);
return operation;
}
}
}
#endif

View File

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

View File

@@ -7,7 +7,7 @@ internal class TTFSDownloadFileOperation : DefaultDownloadFileOperation
{
private TiktokFileSystem _fileSystem;
private ESteps _steps = ESteps.None;
internal TTFSDownloadFileOperation(TiktokFileSystem fileSystem, PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
_fileSystem = fileSystem;
@@ -84,7 +84,7 @@ internal class TTFSDownloadFileOperation : DefaultDownloadFileOperation
private void CreateWebRequest()
{
//TODO : 抖音小游戏没有找到预下载方法
_webRequest = UnityWebRequestAssetBundle.GetAssetBundle(_requestURL);
_webRequest = UnityWebRequest.Get(_requestURL);
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}

View File

@@ -3,16 +3,7 @@ using YooAsset;
internal partial class TTFSInitializeOperation : FSInitializeFileSystemOperation
{
private enum ESteps
{
None,
RecordCacheFiles,
Done,
}
private readonly TiktokFileSystem _fileSystem;
private RecordTiktokCacheFilesOperation _recordTiktokCacheFilesOp;
private ESteps _steps = ESteps.None;
public TTFSInitializeOperation(TiktokFileSystem fileSystem)
{
@@ -20,36 +11,10 @@ internal partial class TTFSInitializeOperation : FSInitializeFileSystemOperation
}
internal override void InternalOnStart()
{
_steps = ESteps.RecordCacheFiles;
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RecordCacheFiles)
{
if (_recordTiktokCacheFilesOp == null)
{
_recordTiktokCacheFilesOp = new RecordTiktokCacheFilesOperation(_fileSystem);
OperationSystem.StartOperation(_fileSystem.PackageName, _recordTiktokCacheFilesOp);
}
if (_recordTiktokCacheFilesOp.IsDone == false)
return;
if (_recordTiktokCacheFilesOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _recordTiktokCacheFilesOp.Error;
}
}
}
}
#endif

View File

@@ -2,20 +2,19 @@
using UnityEngine;
using UnityEngine.Networking;
using YooAsset;
using TTSDK;
internal class TTFSLoadBundleOperation : FSLoadBundleOperation
{
private enum ESteps
{
None,
LoadBundleFile,
DownloadAssetBundle,
Done,
}
private readonly TiktokFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private UnityWebRequest _webRequest;
private DownloadAssetBundleOperation _downloadAssetBundleOp;
private ESteps _steps = ESteps.None;
internal TTFSLoadBundleOperation(TiktokFileSystem fileSystem, PackageBundle bundle)
@@ -25,41 +24,52 @@ internal class TTFSLoadBundleOperation : FSLoadBundleOperation
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadBundleFile;
_steps = ESteps.DownloadAssetBundle;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadBundleFile)
if (_steps == ESteps.DownloadAssetBundle)
{
if (_webRequest == null)
if (_downloadAssetBundleOp == null)
{
string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
_webRequest = TTAssetBundle.GetAssetBundle(mainURL);
_webRequest.SendWebRequest();
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
downloadParam.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); ;
downloadParam.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(false, _fileSystem.DecryptionServices, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadTiktokAssetBundleOperation(_bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
}
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
DownloadProgress = _downloadAssetBundleOp.DownloadProgress;
DownloadedBytes = (long)_downloadAssetBundleOp.DownloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
if (_downloadAssetBundleOp.IsDone == false)
return;
if (CheckRequestResult())
if (_downloadAssetBundleOp.Status == EOperationStatus.Succeed)
{
var assetBundle = (_webRequest.downloadHandler as DownloadHandlerTTAssetBundle).assetBundle;
var assetBundle = _downloadAssetBundleOp.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Error = $"{nameof(DownloadHandlerTTAssetBundle)} loaded asset bundle is null !";
Status = EOperationStatus.Failed;
Error = $"{nameof(DownloadAssetBundleOperation)} loaded asset bundle is null !";
}
else
{
_steps = ESteps.Done;
Result = new AssetBundleResult(_fileSystem, _bundle, assetBundle, null);
Result = new TTAssetBundleResult(_fileSystem, _bundle, assetBundle);
Status = EOperationStatus.Succeed;
}
}
@@ -67,6 +77,7 @@ internal class TTFSLoadBundleOperation : FSLoadBundleOperation
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadAssetBundleOp.Error;
}
}
}
@@ -82,31 +93,11 @@ internal class TTFSLoadBundleOperation : FSLoadBundleOperation
}
public override void AbortDownloadOperation()
{
}
private bool CheckRequestResult()
{
#if UNITY_2020_3_OR_NEWER
if (_webRequest.result != UnityWebRequest.Result.Success)
if (_steps == ESteps.DownloadAssetBundle)
{
Error = _webRequest.error;
return false;
if (_downloadAssetBundleOp != null)
_downloadAssetBundleOp.SetAbort();
}
else
{
return true;
}
#else
if (_webRequest.isNetworkError || _webRequest.isHttpError)
{
Error = _webRequest.error;
return false;
}
else
{
return true;
}
#endif
}
}
#endif

View File

@@ -0,0 +1,127 @@
#if UNITY_WEBGL && DOUYINMINIGAME
using UnityEngine;
using UnityEngine.Networking;
using TTSDK;
namespace YooAsset
{
internal class DownloadTiktokAssetBundleOperation : DownloadAssetBundleOperation
{
private ESteps _steps = ESteps.None;
internal DownloadTiktokAssetBundleOperation(PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
}
internal override void InternalOnStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 重置变量
ResetRequestFiled();
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
//TODO 需要验证抖音插件请求器的下载进度
//CheckRequestTimeout();
return;
}
// 检查网络错误
if (CheckRequestResult())
{
var downloadHanlder = (DownloadHandlerTTAssetBundle)_webRequest.downloadHandler;
AssetBundle assetBundle = downloadHanlder.assetBundle;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Download handler asset bundle object is null !";
}
else
{
_steps = ESteps.Done;
Result = assetBundle;
Status = EOperationStatus.Succeed;
//TODO 需要验证抖音插件请求器的下载进度
DownloadProgress = 1f;
DownloadedBytes = Bundle.FileSize;
Progress = 1f;
}
}
else
{
_steps = ESteps.TryAgain;
}
// 注意:最终释放请求器
DisposeWebRequest();
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
FailedTryAgain--;
_steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
}
}
}
internal override void InternalOnAbort()
{
_steps = ESteps.Done;
DisposeWebRequest();
}
private void CreateWebRequest()
{
_webRequest = TTAssetBundle.GetAssetBundle(_requestURL);
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
}
}
#endif

View File

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

View File

@@ -1,57 +0,0 @@
#if UNITY_WEBGL && DOUYINMINIGAME
using YooAsset;
using TTSDK;
internal class RecordTiktokCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RecordCacheFiles,
WaitResponse,
Done,
}
private readonly TiktokFileSystem _fileSystem;
private ESteps _steps = ESteps.None;
public RecordTiktokCacheFilesOperation(TiktokFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
_steps = ESteps.RecordCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RecordCacheFiles)
{
_steps = ESteps.WaitResponse;
var fileSystemMgr = _fileSystem.GetFileSystemMgr();
var getSavedFileListParam = new GetSavedFileListParam();
getSavedFileListParam.success = (TTGetSavedFileListResponse response) =>
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
foreach (var fileInfo in response.fileList)
{
//TODO 需要确认存储文件为Bundle文件
_fileSystem.RecordBundleFile(fileInfo.filePath);
}
};
getSavedFileListParam.fail = (TTGetSavedFileListResponse response) =>
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = response.errMsg;
};
fileSystemMgr.GetSavedFileList(getSavedFileListParam);
}
}
}
#endif

View File

@@ -8,11 +8,20 @@ using System;
public static class TiktokFileSystemCreater
{
public static FileSystemParameters CreateByteGameFileSystemParameters(IRemoteServices remoteServices, string packageRoot)
public static FileSystemParameters CreateFileSystemParameters(string packageRoot, IRemoteServices remoteServices)
{
string fileSystemClass = $"{nameof(TiktokFileSystem)},YooAsset.RuntimeExtension";
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
return fileSystemParams;
}
public static FileSystemParameters CreateFileSystemParameters(string packageRoot, IRemoteServices remoteServices, IWebDecryptionServices decryptionServices)
{
string fileSystemClass = $"{nameof(TiktokFileSystem)},YooAsset.RuntimeExtension";
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices);
return fileSystemParams;
}
}
@@ -53,8 +62,7 @@ internal class TiktokFileSystem : IFileSystem
}
}
private readonly HashSet<string> _recorders = new HashSet<string>();
private readonly Dictionary<string, string> _cacheFilePaths = new Dictionary<string, string>(10000);
private readonly Dictionary<string, string> _cacheFilePathMapping = new Dictionary<string, string>(10000);
private TTFileSystemManager _fileSystemMgr;
private string _ttCacheRoot = string.Empty;
@@ -81,7 +89,7 @@ internal class TiktokFileSystem : IFileSystem
{
get
{
return _recorders.Count;
return 0;
}
}
@@ -90,6 +98,11 @@ internal class TiktokFileSystem : IFileSystem
/// 自定义参数:远程服务接口
/// </summary>
public IRemoteServices RemoteServices { private set; get; } = null;
/// <summary>
/// 自定义参数:解密方法类
/// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; }
#endregion
@@ -147,10 +160,14 @@ internal class TiktokFileSystem : IFileSystem
public virtual void SetParameter(string name, object value)
{
if (name == "REMOTE_SERVICES")
if (name == FileSystemParametersDefine.REMOTE_SERVICES)
{
RemoteServices = (IRemoteServices)value;
}
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES)
{
DecryptionServices = (IWebDecryptionServices)value;
}
else
{
YooLogger.Warning($"Invalid parameter : {name}");
@@ -185,8 +202,7 @@ internal class TiktokFileSystem : IFileSystem
}
public virtual bool Exists(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
return _recorders.Contains(filePath);
return CheckCacheFileExist(bundle);
}
public virtual bool NeedDownload(PackageBundle bundle)
{
@@ -210,19 +226,27 @@ internal class TiktokFileSystem : IFileSystem
}
public virtual byte[] ReadBundleFileData(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
if (CheckCacheFileExist(filePath))
if (CheckCacheFileExist(bundle))
{
string filePath = GetCacheFileLoadPath(bundle);
return _fileSystemMgr.ReadFileSync(filePath);
}
else
{
return Array.Empty<byte>();
}
}
public virtual string ReadBundleFileText(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
if (CheckCacheFileExist(filePath))
if (CheckCacheFileExist(bundle))
{
string filePath = GetCacheFileLoadPath(bundle);
return _fileSystemMgr.ReadFileSync(filePath, "utf8");
}
else
{
return string.Empty;
}
}
#region
@@ -230,56 +254,20 @@ internal class TiktokFileSystem : IFileSystem
{
return _fileSystemMgr;
}
public bool CheckCacheFileExist(string filePath)
public bool CheckCacheFileExist(PackageBundle bundle)
{
return _fileSystemMgr.AccessSync(filePath);
string url = RemoteServices.GetRemoteMainURL(bundle.FileName);
return _fileSystemMgr.IsUrlCached(url);
}
private string GetCacheFileLoadPath(PackageBundle bundle)
{
if (_cacheFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_cacheFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = _fileSystemMgr.GetLocalCachedPathForUrl(bundle.FileName);
_cacheFilePaths.Add(bundle.BundleGUID, filePath);
_cacheFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
#endregion
#region
public List<string> GetAllRecords()
{
return _recorders.ToList();
}
public bool RecordBundleFile(string filePath)
{
if (_recorders.Contains(filePath))
{
YooLogger.Error($"{nameof(TiktokFileSystem)} has element : {filePath}");
return false;
}
_recorders.Add(filePath);
return true;
}
public void TryRecordBundle(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
if (_recorders.Contains(filePath) == false)
{
_recorders.Add(filePath);
}
}
public void ClearAllRecords()
{
_recorders.Clear();
}
public void ClearRecord(string filePath)
{
if (_recorders.Contains(filePath))
{
_recorders.Remove(filePath);
}
}
#endregion
}
#endif

View File

@@ -42,7 +42,6 @@ internal class WXFSClearAllBundleFilesOperation : FSClearCacheFilesOperation
YooLogger.Log("微信缓存清理成功!");
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
_fileSystem.ClearAllRecords();
}
else
{

View File

@@ -4,6 +4,7 @@ using System.IO;
using UnityEngine;
using YooAsset;
using WeChatWASM;
using static UnityEngine.Networking.UnityWebRequest;
internal class WXFSClearUnusedBundleFilesAsync : FSClearCacheFilesOperation
{
@@ -11,6 +12,7 @@ internal class WXFSClearUnusedBundleFilesAsync : FSClearCacheFilesOperation
{
None,
GetUnusedCacheFiles,
WaitingSearch,
ClearUnusedCacheFiles,
Done,
}
@@ -37,20 +39,46 @@ internal class WXFSClearUnusedBundleFilesAsync : FSClearCacheFilesOperation
if (_steps == ESteps.GetUnusedCacheFiles)
{
_unusedCacheFiles = GetUnusedCacheFiles();
_unusedFileTotalCount = _unusedCacheFiles.Count;
_steps = ESteps.ClearUnusedCacheFiles;
YooLogger.Log($"Found unused cache files count : {_unusedFileTotalCount}");
_steps = ESteps.WaitingSearch;
var fileSystemMgr = _fileSystem.GetFileSystemMgr();
var statOption = new WXStatOption();
statOption.path = _fileSystem.FileRoot;
statOption.recursive = true;
statOption.success = (WXStatResponse response) =>
{
foreach (var fileStat in response.stats)
{
// 注意存储文件必须按照Bundle文件哈希值存储
string bundleGUID = Path.GetFileNameWithoutExtension(fileStat.path);
if (_manifest.TryGetPackageBundleByBundleGUID(bundleGUID, out PackageBundle value) == false)
{
string fullPath = WX.GetCachePath(fileStat.path);
if (_unusedCacheFiles.Contains(fullPath) == false)
_unusedCacheFiles.Add(fullPath);
}
}
_steps = ESteps.ClearUnusedCacheFiles;
_unusedFileTotalCount = _unusedCacheFiles.Count;
YooLogger.Log($"Found unused cache files count : {_unusedFileTotalCount}");
};
statOption.fail = (WXStatResponse response) =>
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = response.errMsg;
};
fileSystemMgr.Stat(statOption);
}
if (_steps == ESteps.ClearUnusedCacheFiles)
{
for (int i = _unusedCacheFiles.Count - 1; i >= 0; i--)
{
string clearFilePath = _unusedCacheFiles[i];
string filePath = _unusedCacheFiles[i];
_unusedCacheFiles.RemoveAt(i);
_fileSystem.ClearRecord(clearFilePath);
WX.RemoveFile(clearFilePath, null);
WX.RemoveFile(filePath, null);
if (OperationSystem.IsBusy)
break;
@@ -68,30 +96,5 @@ internal class WXFSClearUnusedBundleFilesAsync : FSClearCacheFilesOperation
}
}
}
private List<string> GetUnusedCacheFiles()
{
var allRecords = _fileSystem.GetAllRecords();
List<string> result = new List<string>(allRecords.Count);
foreach (var filePath in allRecords)
{
// 如果存储文件名是按照Bundle文件哈希值存储
string bundleGUID = Path.GetFileNameWithoutExtension(filePath);
if (_manifest.TryGetPackageBundleByBundleGUID(bundleGUID, out PackageBundle value) == false)
{
result.Add(filePath);
}
// 如果存储文件名是按照Bundle文件名称存储
/*
string bundleName = Path.GetFileNameWithoutExtension(filePath);
if (_manifest.TryGetPackageBundleByBundleName(bundleName, out PackageBundle value) == false)
{
result.Add(filePath);
}
*/
}
return result;
}
}
#endif

View File

@@ -42,7 +42,9 @@ internal class WXFSDownloadFileOperation : DefaultDownloadFileOperation
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
CheckRequestTimeout();
//TODO 由于微信小游戏插件的问题,暂时不能判定超时!
// Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108#
//CheckRequestTimeout();
return;
}
@@ -51,7 +53,12 @@ internal class WXFSDownloadFileOperation : DefaultDownloadFileOperation
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
_fileSystem.TryRecordBundle(Bundle); //记录下载文件
//TODO 解决微信小游戏插件问题
// Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108#
DownloadProgress = 1f;
DownloadedBytes = Bundle.FileSize;
Progress = 1f;
}
else
{
@@ -85,7 +92,7 @@ internal class WXFSDownloadFileOperation : DefaultDownloadFileOperation
private void CreateWebRequest()
{
_webRequest = WXAssetBundle.GetAssetBundle(_requestURL);
_webRequest = UnityWebRequest.Get(_requestURL);
_webRequest.SetRequestHeader("wechatminigame-preload", "1");
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();

View File

@@ -3,16 +3,7 @@ using YooAsset;
internal partial class WXFSInitializeOperation : FSInitializeFileSystemOperation
{
private enum ESteps
{
None,
RecordCacheFiles,
Done,
}
private readonly WechatFileSystem _fileSystem;
private RecordWechatCacheFilesOperation _recordWechatCacheFilesOp;
private ESteps _steps = ESteps.None;
public WXFSInitializeOperation(WechatFileSystem fileSystem)
{
@@ -20,36 +11,10 @@ internal partial class WXFSInitializeOperation : FSInitializeFileSystemOperation
}
internal override void InternalOnStart()
{
_steps = ESteps.RecordCacheFiles;
Status = EOperationStatus.Succeed;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RecordCacheFiles)
{
if (_recordWechatCacheFilesOp == null)
{
_recordWechatCacheFilesOp = new RecordWechatCacheFilesOperation(_fileSystem);
OperationSystem.StartOperation(_fileSystem.PackageName, _recordWechatCacheFilesOp);
}
if (_recordWechatCacheFilesOp.IsDone == false)
return;
if (_recordWechatCacheFilesOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _recordWechatCacheFilesOp.Error;
}
}
}
}
#endif

View File

@@ -1,21 +1,18 @@
#if UNITY_WEBGL && WEIXINMINIGAME
using UnityEngine;
using UnityEngine.Networking;
using YooAsset;
using WeChatWASM;
internal class WXFSLoadBundleOperation : FSLoadBundleOperation
{
private enum ESteps
{
None,
LoadBundleFile,
DownloadAssetBundle,
Done,
}
private readonly WechatFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private UnityWebRequest _webRequest;
private DownloadAssetBundleOperation _downloadAssetBundleOp;
private ESteps _steps = ESteps.None;
internal WXFSLoadBundleOperation(WechatFileSystem fileSystem, PackageBundle bundle)
@@ -25,49 +22,60 @@ internal class WXFSLoadBundleOperation : FSLoadBundleOperation
}
internal override void InternalOnStart()
{
_steps = ESteps.LoadBundleFile;
_steps = ESteps.DownloadAssetBundle;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadBundleFile)
if (_steps == ESteps.DownloadAssetBundle)
{
if (_webRequest == null)
if (_downloadAssetBundleOp == null)
{
string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
_webRequest = WXAssetBundle.GetAssetBundle(mainURL);
_webRequest.SendWebRequest();
DownloadParam downloadParam = new DownloadParam(int.MaxValue, 60);
downloadParam.MainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName); ;
downloadParam.FallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
if (_bundle.Encrypted)
{
_downloadAssetBundleOp = new DownloadWebEncryptAssetBundleOperation(false, _fileSystem.DecryptionServices, _bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
else
{
_downloadAssetBundleOp = new DownloadWechatAssetBundleOperation(_bundle, downloadParam);
OperationSystem.StartOperation(_fileSystem.PackageName, _downloadAssetBundleOp);
}
}
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
DownloadProgress = _downloadAssetBundleOp.DownloadProgress;
DownloadedBytes = (long)_downloadAssetBundleOp.DownloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
if (_downloadAssetBundleOp.IsDone == false)
return;
if (CheckRequestResult())
if (_downloadAssetBundleOp.Status == EOperationStatus.Succeed)
{
var assetBundle = (_webRequest.downloadHandler as DownloadHandlerWXAssetBundle).assetBundle;
var assetBundle = _downloadAssetBundleOp.Result;
if (assetBundle == null)
{
_steps = ESteps.Done;
Error = $"{nameof(DownloadHandlerWXAssetBundle)} loaded asset bundle is null !";
Status = EOperationStatus.Failed;
Error = $"{nameof(DownloadAssetBundleOperation)} loaded asset bundle is null !";
}
else
{
_steps = ESteps.Done;
Result = new WXAssetBundleResult(_fileSystem, _bundle, assetBundle);
Status = EOperationStatus.Succeed;
_fileSystem.TryRecordBundle(_bundle); //记录下载文件
}
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloadAssetBundleOp.Error;
}
}
}
@@ -83,31 +91,11 @@ internal class WXFSLoadBundleOperation : FSLoadBundleOperation
}
public override void AbortDownloadOperation()
{
}
private bool CheckRequestResult()
{
#if UNITY_2020_3_OR_NEWER
if (_webRequest.result != UnityWebRequest.Result.Success)
if (_steps == ESteps.DownloadAssetBundle)
{
Error = _webRequest.error;
return false;
if (_downloadAssetBundleOp != null)
_downloadAssetBundleOp.SetAbort();
}
else
{
return true;
}
#else
if (_webRequest.isNetworkError || _webRequest.isHttpError)
{
Error = _webRequest.error;
return false;
}
else
{
return true;
}
#endif
}
}
#endif

View File

@@ -0,0 +1,129 @@
#if UNITY_WEBGL && WEIXINMINIGAME
using UnityEngine;
using UnityEngine.Networking;
using WeChatWASM;
namespace YooAsset
{
internal class DownloadWechatAssetBundleOperation : DownloadAssetBundleOperation
{
private ESteps _steps = ESteps.None;
internal DownloadWechatAssetBundleOperation(PackageBundle bundle, DownloadParam param) : base(bundle, param)
{
}
internal override void InternalOnStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
// 获取请求地址
_requestURL = GetRequestURL();
// 重置变量
ResetRequestFiled();
// 创建下载器
CreateWebRequest();
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = DownloadProgress;
if (_webRequest.isDone == false)
{
//TODO 由于微信小游戏插件的问题,暂时不能判定超时!
// Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108#
//CheckRequestTimeout();
return;
}
// 检查网络错误
if (CheckRequestResult())
{
var downloadHanlder = (DownloadHandlerWXAssetBundle)_webRequest.downloadHandler;
AssetBundle assetBundle = downloadHanlder.assetBundle;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Download handler asset bundle object is null !";
}
else
{
_steps = ESteps.Done;
Result = assetBundle;
Status = EOperationStatus.Succeed;
//TODO 解决微信小游戏插件问题
// Issue : https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/issues/108#
DownloadProgress = 1f;
DownloadedBytes = Bundle.FileSize;
Progress = 1f;
}
}
else
{
_steps = ESteps.TryAgain;
}
// 注意:最终释放请求器
DisposeWebRequest();
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
if (FailedTryAgain <= 0)
{
Status = EOperationStatus.Failed;
_steps = ESteps.Done;
YooLogger.Error(Error);
return;
}
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
FailedTryAgain--;
_steps = ESteps.CreateRequest;
YooLogger.Warning(Error);
}
}
}
internal override void InternalOnAbort()
{
_steps = ESteps.Done;
DisposeWebRequest();
}
private void CreateWebRequest()
{
_webRequest = WXAssetBundle.GetAssetBundle(_requestURL);
_webRequest.disposeDownloadHandlerOnDispose = true;
_webRequest.SendWebRequest();
}
private void DisposeWebRequest()
{
if (_webRequest != null)
{
//注意引擎底层会自动调用Abort方法
_webRequest.Dispose();
_webRequest = null;
}
}
}
}
#endif

View File

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

View File

@@ -1,58 +0,0 @@
#if UNITY_WEBGL && WEIXINMINIGAME
using YooAsset;
using WeChatWASM;
using System.IO;
internal class RecordWechatCacheFilesOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RecordCacheFiles,
WaitResponse,
Done,
}
private readonly WechatFileSystem _fileSystem;
private ESteps _steps = ESteps.None;
public RecordWechatCacheFilesOperation(WechatFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalOnStart()
{
_steps = ESteps.RecordCacheFiles;
}
internal override void InternalOnUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RecordCacheFiles)
{
_steps = ESteps.WaitResponse;
var fileSystemMgr = _fileSystem.GetFileSystemMgr();
var getSavedFileListOption = new GetSavedFileListOption();
getSavedFileListOption.success = (GetSavedFileListSuccessCallbackResult response) =>
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
foreach (var fileInfo in response.fileList)
{
//TODO 需要确认存储文件为Bundle文件
_fileSystem.RecordBundleFile(fileInfo.filePath);
}
};
getSavedFileListOption.fail = (FileError fileError) =>
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = fileError.errMsg;
};
fileSystemMgr.GetSavedFileList(getSavedFileListOption);
}
}
}
#endif

View File

@@ -8,11 +8,19 @@ using WeChatWASM;
public static class WechatFileSystemCreater
{
public static FileSystemParameters CreateWechatFileSystemParameters(IRemoteServices remoteServices, string packageRoot)
public static FileSystemParameters CreateFileSystemParameters(string packageRoot, IRemoteServices remoteServices)
{
string fileSystemClass = $"{nameof(WechatFileSystem)},YooAsset.RuntimeExtension";
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter("REMOTE_SERVICES", remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
return fileSystemParams;
}
public static FileSystemParameters CreateFileSystemParameters(string packageRoot, IRemoteServices remoteServices, IWebDecryptionServices decryptionServices)
{
string fileSystemClass = $"{nameof(WechatFileSystem)},YooAsset.RuntimeExtension";
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
fileSystemParams.AddParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
fileSystemParams.AddParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, decryptionServices);
return fileSystemParams;
}
}
@@ -53,8 +61,7 @@ internal class WechatFileSystem : IFileSystem
}
}
private readonly HashSet<string> _recorders = new HashSet<string>();
private readonly Dictionary<string, string> _cacheFilePaths = new Dictionary<string, string>(10000);
private readonly Dictionary<string, string> _cacheFilePathMapping = new Dictionary<string, string>(10000);
private WXFileSystemManager _fileSystemMgr;
private string _wxCacheRoot = string.Empty;
@@ -63,6 +70,8 @@ internal class WechatFileSystem : IFileSystem
/// </summary>
public string PackageName { private set; get; }
private readonly string _packageRoot = YooAssetSettingsData.Setting.DefaultYooFolderName;
/// <summary>
/// 文件根目录
/// </summary>
@@ -81,7 +90,7 @@ internal class WechatFileSystem : IFileSystem
{
get
{
return _recorders.Count;
return 0;
}
}
@@ -90,6 +99,11 @@ internal class WechatFileSystem : IFileSystem
/// 自定义参数:远程服务接口
/// </summary>
public IRemoteServices RemoteServices { private set; get; } = null;
/// <summary>
/// 自定义参数:解密方法类
/// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; }
#endregion
@@ -163,25 +177,34 @@ internal class WechatFileSystem : IFileSystem
public virtual void SetParameter(string name, object value)
{
if (name == "REMOTE_SERVICES")
if (name == FileSystemParametersDefine.REMOTE_SERVICES)
{
RemoteServices = (IRemoteServices)value;
}
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES)
{
DecryptionServices = (IWebDecryptionServices)value;
}
else
{
YooLogger.Warning($"Invalid parameter : {name}");
}
}
public virtual void OnCreate(string packageName, string rootDirectory)
public virtual void OnCreate(string packageName, string packageRoot)
{
PackageName = packageName;
_wxCacheRoot = rootDirectory;
_wxCacheRoot = packageRoot;
if (string.IsNullOrEmpty(_wxCacheRoot))
{
throw new System.Exception("请配置微信小游戏缓存根目录!");
}
if (_wxCacheRoot.StartsWith(WX.PluginCachePath) == false)
{
_wxCacheRoot = PathUtility.Combine(WX.PluginCachePath, _wxCacheRoot);
}
// 注意CDN服务未启用的情况下使用微信WEB服务器
if (RemoteServices == null)
{
@@ -202,7 +225,7 @@ internal class WechatFileSystem : IFileSystem
public virtual bool Exists(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
return _recorders.Contains(filePath);
return CheckCacheFileExist(filePath);
}
public virtual bool NeedDownload(PackageBundle bundle)
{
@@ -248,55 +271,21 @@ internal class WechatFileSystem : IFileSystem
}
public bool CheckCacheFileExist(string filePath)
{
string result = _fileSystemMgr.AccessSync(filePath);
return result.Equals("access:ok");
string result = WX.GetCachePath(filePath);
if (string.IsNullOrEmpty(result))
return false;
else
return true;
}
public string GetCacheFileLoadPath(PackageBundle bundle)
{
if (_cacheFilePaths.TryGetValue(bundle.BundleGUID, out string filePath) == false)
if (_cacheFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(_wxCacheRoot, bundle.FileName);
_cacheFilePaths.Add(bundle.BundleGUID, filePath);
_cacheFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
#endregion
#region
public List<string> GetAllRecords()
{
return _recorders.ToList();
}
public bool RecordBundleFile(string filePath)
{
if (_recorders.Contains(filePath))
{
YooLogger.Error($"{nameof(WechatFileSystem)} has element : {filePath}");
return false;
}
_recorders.Add(filePath);
return true;
}
public void TryRecordBundle(PackageBundle bundle)
{
string filePath = GetCacheFileLoadPath(bundle);
if (_recorders.Contains(filePath) == false)
{
_recorders.Add(filePath);
}
}
public void ClearAllRecords()
{
_recorders.Clear();
}
public void ClearRecord(string filePath)
{
if (_recorders.Contains(filePath))
{
_recorders.Remove(filePath);
}
}
#endregion
}
#endif

View File

@@ -1,14 +1,12 @@
using System.Collections;
#if UNITY_2019_4_OR_NEWER
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
using YooAsset.Editor;
#if UNITY_2019_4_OR_NEWER
using UnityEditor.UIElements;
using UnityEngine.UIElements;
#endif
[CreateAssetMenu(fileName = "TextureSchema", menuName = "YooAssetArt/Create TextureSchema")]
public class TextureSchema : ScannerSchema
@@ -23,6 +21,12 @@ public class TextureSchema : ScannerSchema
/// </summary>
public int MaxHeight = 1024;
/// <summary>
/// 测试列表
/// </summary>
public List<string> TestStringValues = new List<string>();
/// <summary>
/// 获取用户指南信息
/// </summary>
@@ -37,9 +41,9 @@ public class TextureSchema : ScannerSchema
public override ScanReport RunScanner(AssetArtScanner scanner)
{
// 创建扫描报告
string title = "扫描所有纹理资产";
string name = "扫描所有纹理资产";
string desc = GetUserGuide();
var report = new ScanReport(title, desc);
var report = new ScanReport(name, desc);
report.AddHeader("资源路径", 600, 500, 1000).SetStretchable().SetSearchable().SetSortable().SetHeaderType(EHeaderType.AssetPath);
report.AddHeader("图片宽度", 100).SetSortable().SetHeaderType(EHeaderType.LongValue);
report.AddHeader("图片高度", 100).SetSortable().SetHeaderType(EHeaderType.LongValue);
@@ -105,9 +109,9 @@ public class TextureSchema : ScannerSchema
// 添加扫描信息
ReportElement result = new ReportElement(assetGUID);
result.AddScanInfo("资源路径", assetPath);
result.AddScanInfo("图片宽度", texture.width.ToString());
result.AddScanInfo("图片高度", texture.height.ToString());
result.AddScanInfo("内存大小", memorySize.ToString());
result.AddScanInfo("图片宽度", texture.width);
result.AddScanInfo("图片高度", texture.height);
result.AddScanInfo("内存大小", memorySize);
result.AddScanInfo("苹果格式", iosFormat.ToString());
result.AddScanInfo("安卓格式", androidFormat.ToString());
result.AddScanInfo("错误信息", errorInfo);
@@ -157,7 +161,6 @@ public class TextureSchema : ScannerSchema
/// </summary>
public override SchemaInspector CreateInspector()
{
#if UNITY_2019_4_OR_NEWER
var container = new VisualElement();
// 图片最大宽度
@@ -180,11 +183,16 @@ public class TextureSchema : ScannerSchema
});
container.Add(maxHeightField);
SchemaInspector inspector = new SchemaInspector();
inspector.Containner = container;
return inspector;
#else
return null;
// 创建测试列表
#if UNITY_2021_3_OR_NEWER
ReorderableListView reorderableListView = new ReorderableListView();
reorderableListView.SourceData = TestStringValues;
reorderableListView.HeaderName = "测试列表";
container.Add(reorderableListView);
#endif
SchemaInspector inspector = new SchemaInspector(container);
return inspector;
}
}
}
#endif

View File

@@ -74,10 +74,11 @@ internal class FsmInitializePackage : IStateNode
#if UNITY_WEBGL && WEIXINMINIGAME && !UNITY_EDITOR
string defaultHostServer = GetHostServerURL();
string fallbackHostServer = GetHostServerURL();
string packageRoot = $"{WeChatWASM.WX.env.USER_DATA_PATH}/__GAME_FILE_CACHE"; //注意:如果有子目录,请修改此处!
IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
createParameters.WebServerFileSystemParameters = WechatFileSystemCreater.CreateWechatFileSystemParameters(remoteServices);
createParameters.WebServerFileSystemParameters = WechatFileSystemCreater.CreateFileSystemParameters(packageRoot, remoteServices);
#else
createParameters.WebServerFileSystemParameters = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
createParameters.WebServerFileSystemParameters = FileSystemParameters.CreateDefaultWebServerFileSystemParameters(new WebDecryption());
#endif
initializationOperation = package.InitializeAsync(createParameters);
}
@@ -148,4 +149,24 @@ internal class FsmInitializePackage : IStateNode
return $"{_fallbackHostServer}/{fileName}";
}
}
private class WebDecryption : IWebDecryptionServices
{
public const byte KEY = 64;
public WebDecryptResult LoadAssetBundle(WebDecryptFileInfo fileInfo)
{
byte[] copyData = new byte[fileInfo.FileData.Length];
Buffer.BlockCopy(fileInfo.FileData, 0, copyData, 0, fileInfo.FileData.Length);
for (int i = 0; i < copyData.Length; i++)
{
copyData[i] ^= KEY;
}
WebDecryptResult decryptResult = new WebDecryptResult();
decryptResult.Result = AssetBundle.LoadFromMemory(copyData);
return decryptResult;
}
}
}

View File

@@ -26,7 +26,7 @@ MonoBehaviour:
Groups:
- GroupName: battle
GroupDesc: "\u6218\u6597"
AssetTags:
AssetTags: battle
ActiveRuleName: EnableGroup
Collectors:
- CollectPath: Assets/Samples/Space Shooter/GameRes/Effect
@@ -92,7 +92,7 @@ MonoBehaviour:
UserData:
- GroupName: scene
GroupDesc: "\u573A\u666F"
AssetTags:
AssetTags: scene
ActiveRuleName: EnableGroup
Collectors:
- CollectPath: Assets/Samples/Space Shooter/GameRes/Scene
@@ -113,7 +113,7 @@ MonoBehaviour:
UserData:
- GroupName: ugui
GroupDesc: "\u9762\u677F"
AssetTags:
AssetTags: ui
ActiveRuleName: EnableGroup
Collectors:
- CollectPath: Assets/Samples/Space Shooter/GameRes/UIPanel

View File

@@ -14,3 +14,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
MaxWidth: 1024
MaxHeight: 1024
TestStringValues:
- test1
- test2
- test3

View File

@@ -4,6 +4,7 @@ using System.Text;
using UnityEngine;
using YooAsset;
#region
/// <summary>
/// 资源文件解密流
/// </summary>
@@ -29,6 +30,35 @@ public class BundleStream : FileStream
}
}
/// <summary>
/// 文件流加密方式
/// </summary>
public class FileStreamEncryption : IEncryptionServices
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
if (fileInfo.BundleName.Contains("_gameres_audio"))
{
var fileData = File.ReadAllBytes(fileInfo.FileLoadPath);
for (int i = 0; i < fileData.Length; i++)
{
fileData[i] ^= BundleStream.KEY;
}
EncryptResult result = new EncryptResult();
result.Encrypted = true;
result.EncryptedData = fileData;
return result;
}
else
{
EncryptResult result = new EncryptResult();
result.Encrypted = false;
return result;
}
}
}
/// <summary>
/// 资源文件流加载解密类
/// </summary>
@@ -81,6 +111,37 @@ public class FileStreamDecryption : IDecryptionServices
return 1024;
}
}
#endregion
#region
/// <summary>
/// 文件偏移加密方式
/// </summary>
public class FileOffsetEncryption : IEncryptionServices
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
// 注意:只对音频资源包加密
if (fileInfo.BundleName.Contains("_gameres_audio"))
{
int offset = 32;
byte[] fileData = File.ReadAllBytes(fileInfo.FileLoadPath);
var encryptedData = new byte[fileData.Length + offset];
Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length);
EncryptResult result = new EncryptResult();
result.Encrypted = true;
result.EncryptedData = encryptedData;
return result;
}
else
{
EncryptResult result = new EncryptResult();
result.Encrypted = false;
return result;
}
}
}
/// <summary>
/// 资源文件偏移加载解密类
@@ -132,61 +193,4 @@ public class FileOffsetDecryption : IDecryptionServices
return 32;
}
}
/// <summary>
/// 文件偏移加密方式
/// </summary>
public class FileOffsetEncryption : IEncryptionServices
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
// 注意:只对音频资源包加密
if (fileInfo.BundleName.Contains("_gameres_audio"))
{
int offset = 32;
byte[] fileData = File.ReadAllBytes(fileInfo.FileLoadPath);
var encryptedData = new byte[fileData.Length + offset];
Buffer.BlockCopy(fileData, 0, encryptedData, offset, fileData.Length);
EncryptResult result = new EncryptResult();
result.Encrypted = true;
result.EncryptedData = encryptedData;
return result;
}
else
{
EncryptResult result = new EncryptResult();
result.Encrypted = false;
return result;
}
}
}
/// <summary>
/// 文件流加密方式
/// </summary>
public class FileStreamEncryption : IEncryptionServices
{
public EncryptResult Encrypt(EncryptFileInfo fileInfo)
{
if (fileInfo.BundleName.Contains("_gameres_audio"))
{
var fileData = File.ReadAllBytes(fileInfo.FileLoadPath);
for (int i = 0; i < fileData.Length; i++)
{
fileData[i] ^= BundleStream.KEY;
}
EncryptResult result = new EncryptResult();
result.Encrypted = true;
result.EncryptedData = fileData;
return result;
}
else
{
EncryptResult result = new EncryptResult();
result.Encrypted = false;
return result;
}
}
}
#endregion

View File

@@ -1,7 +1,7 @@
{
"name": "com.tuyoogame.yooasset",
"displayName": "YooAsset",
"version": "2.2.11",
"version": "2.3.0-preview",
"unity": "2019.4",
"description": "unity3d resources management system.",
"author": {