Compare commits

...

33 Commits
main ... 1.5.0

Author SHA1 Message Date
hevinci d3d15fc59f Update CHANGELOG.md 2023-07-05 17:04:35 +08:00
hevinci 8a3358c990 Update package.json 2023-07-05 17:04:12 +08:00
hevinci 8eadba3aa6 update space shooter 2023-07-05 16:31:29 +08:00
hevinci b0917623b6 update runtime code
变更IQueryServices.QueryStreamingAssets(string packageName, string fileName)方法
2023-07-05 16:31:06 +08:00
hevinci a7d9a4ecbc update extension sample 2023-07-05 15:20:34 +08:00
hevinci 2643ab81ed update runtime code
重构了PersistentTools类
2023-07-05 15:14:21 +08:00
hevinci c5314c72f0 update runtime code
1. 新增了ResourcePackage.GetPackageBuildinRootDirectory()方法
2. 新增了ResourcePackage.GetPackageSandboxRootDirectory()方法
3. 新增了ResourcePackage.ClearPackageSandbox()方法
2023-07-05 14:56:18 +08:00
hevinci fbb48ba330 Update InitializeParameters.cs
1. 新增了InitializeParameters.BuildinRootDirectory字段
2. 新增了InitializeParameters.SandboxRootDirectory字段
2023-07-05 14:52:13 +08:00
hevinci 4e6879e34f update runtime code
1. 移除了YooAssets.SetCacheSystemBuildinPath()方法
2. 移除了YooAssets.SetCacheSystemSandboxPath()方法
3. 移除了YooAssets.GetStreamingAssetBuildinFolderName()方法
4. 移除了YooAssets.GetSandboxRoot()方法
5. 移除了YooAssets.ClearSandbox()方法
2023-07-05 14:50:21 +08:00
hevinci 09c3d4e479 update editor code
1. BuildParameters.OutputRoot重命名为BuildOutputRoot
2. 新增了BuildParameters.StreamingAssetsRoot字段
2023-07-05 11:51:49 +08:00
hevinci 1e88bad73e update cache system
新增方法YooAssets.SetCacheSystemBuildinPath()
2023-06-30 18:51:55 +08:00
hevinci 9a2ed64b4e update download system
新增方法YooAssets.SetDownloadSystemRedirectLimit()
2023-06-29 15:47:10 +08:00
hevinci 60e93f9809 update AssetBundleBuilder
1. 移除了资源包构建流程任务节点可扩展功能
2. 新增了构建流程可扩展的方法。
2023-06-29 10:53:07 +08:00
hevinci f5c72e913f update runtime code
新增方法YooAssets.SetCacheSystemDisableCacheOnWebGL()
2023-06-28 17:46:32 +08:00
hevinci 3ca300d956 Update CHANGELOG.md 2023-06-27 18:13:27 +08:00
hevinci d1087aa74c Update package.json 2023-06-27 18:12:54 +08:00
hevinci 43c40e4bbe update runtime code
新增了场景加载参数suspendLoad
2023-06-27 17:33:04 +08:00
何冠峰 d9c4e5336b
Merge pull request #122 from liuweichicun/fix#121
修复场景加载时设置自动激活 false 无效 #121
2023-06-27 16:38:01 +08:00
Kele 772198255a 修复场景加载时设置自动激活 false 无效 #121 2023-06-27 15:56:39 +08:00
hevinci 19c46a2f60 update runtime code
1. 移除了LoadSceneAsync方法里的activateOnLoad参数
2023-06-27 15:04:47 +08:00
hevinci f54c8d6da4 update editor code
1. 移除了BuildParameters.AutoAnalyzeRedundancy字段
2. 移除了DefaultShareAssetPackRule
3. 新增了ZeroRedundancySharedPackRule
4. 新增了FullRedundancySharedPackRule
2023-06-27 14:18:54 +08:00
hevinci 84f9d1985e update editor code
1. IShareAssetPackRule重命名为ISharedPackRule
2. DefaultShareAssetPackRule重命名为DefaultSharedPackRule
2023-06-27 11:00:01 +08:00
hevinci 0b2a2bf97d update AssetBundleCollector 2023-06-27 10:40:09 +08:00
hevinci 561cf411ef update asset system 2023-06-27 10:28:16 +08:00
hevinci f24ae6eb2a update extension sample
1. 增加了GameObjectAssetReference示例脚本。
2023-06-26 18:31:37 +08:00
hevinci 3bb3d4382c update runtime code
1. 移除了InitializeParameters.LocationToLower参数
2. 资源收集界面增加了LocationToLower选项
3. 资源收集界面增加了IncludeAssetGUID选项
4. 资源清单版本升级了
5. 新增了ResourcePackage.GetAssetInfoByGUID()方法
2023-06-26 18:30:29 +08:00
hevinci 43db19c257 update editor code 2023-06-26 17:40:47 +08:00
hevinci 1d5663d93a update runtime code 2023-06-26 10:42:56 +08:00
hevinci b98d4cb091 update package system
离线模式支持内置资源解压到沙盒
2023-06-26 10:25:12 +08:00
hevinci 14ee95615f update AssetBundleBuilder
资源包构建流程可扩展支持
2023-06-25 15:58:08 +08:00
hevinci 8ccddce0f8 update runtime code
新增LoadAllAssetsAsync方法
2023-06-25 12:03:19 +08:00
hevinci 9dde15ac41 update space shooter 2023-06-21 14:21:12 +08:00
hevinci 95111ef1e1 update cache system
优化了缓存的信息文件写入方式
2023-06-21 14:18:51 +08:00
107 changed files with 2023 additions and 818 deletions

View File

@ -2,6 +2,190 @@
All notable changes to this package will be documented in this file. All notable changes to this package will be documented in this file.
## [1.5.0] - 2023-07-05
该版本重构了Persistent类导致沙盒目录和内置目录的存储结构发生了变化。
该版本支持按照Package自定义沙盒存储目录和内置存储目录。
**注意低版本升级用户请使用Space Shooter目录下的StreamingAssetsHelper插件覆盖到本地工程**
### Changed
- BuildParameters.OutputRoot重命名为BuildOutputRoot
- 变更了IQueryServices.QueryStreamingAssets(string packageName, string fileName)方法
### Added
- 新增了YooAssets.SetCacheSystemDisableCacheOnWebGL()方法
```c#
/// <summary>
/// 设置缓存系统参数禁用缓存在WebGL平台
/// </summary>
public static void SetCacheSystemDisableCacheOnWebGL()
```
- 新增了YooAssets.SetDownloadSystemRedirectLimit()方法
```c#
/// <summary>
/// 设置下载系统参数网络重定向次数Unity引擎默认值32
/// 注意:不支持设置为负值
/// </summary>
public static void SetDownloadSystemRedirectLimit(int redirectLimit)
```
- 新增了构建流程可扩展的方法。
```c#
public class AssetBundleBuilder
{
/// <summary>
/// 构建资源包
/// </summary>
public BuildResult Run(BuildParameters buildParameters, List<IBuildTask> buildPipeline)
}
```
- 新增了BuildParameters.StreamingAssetsRoot字段
```c#
public class BuildParameters
{
/// <summary>
/// 内置资源的根目录
/// </summary>
public string StreamingAssetsRoot;
}
```
- 新增了InitializeParameters.BuildinRootDirectory字段
```c#
/// <summary>
/// 内置文件的根路径
/// 注意:当参数为空的时候会使用默认的根目录。
/// </summary>
public string BuildinRootDirectory = string.Empty;
```
- 新增了InitializeParameters.SandboxRootDirectory字段
```c#
/// <summary>
/// 沙盒文件的根路径
/// 注意:当参数为空的时候会使用默认的根目录。
/// </summary>
public string SandboxRootDirectory = string.Empty;
```
- 新增了ResourcePackage.GetPackageBuildinRootDirectory()方法
```c#
/// <summary>
/// 获取包裹的内置文件根路径
/// </summary>
public string GetPackageBuildinRootDirectory()
```
- 新增了ResourcePackage.GetPackageSandboxRootDirectory()方法
```c#
/// <summary>
/// 获取包裹的沙盒文件根路径
/// </summary>
public string GetPackageSandboxRootDirectory()
```
- 新增了ResourcePackage.ClearPackageSandbox()方法
```c#
/// <summary>
/// 清空包裹的沙盒目录
/// </summary>
public void ClearPackageSandbox()
```
### Removed
- 移除了资源包构建流程任务节点可扩展功能。
- 移除了YooAssets.SetCacheSystemSandboxPath()方法
- 移除了YooAssets.GetStreamingAssetBuildinFolderName()方法
- 移除了YooAssets.GetSandboxRoot()方法
- 移除了YooAssets.ClearSandbox()方法
## [1.4.17] - 2023-06-27
### Changed
- 优化了缓存的信息文件写入方式
- 离线模式支持内置资源解压到沙盒
- 资源包构建流程任务节点支持可扩展
```c#
using YooAsset.Editor
[TaskAttribute(ETaskPipeline.AllPipeline, 100, "自定义任务节点")]
public class CustomTask : IBuildTask
```
- 资源收集界面增加了LocationToLower选项
- 资源收集界面增加了IncludeAssetGUID选项
- IShareAssetPackRule 重命名为 ISharedPackRule
### Added
- 新增了ResourcePackage.LoadAllAssetsAsync方法
```c#
/// <summary>
/// 异步加载资源包内所有资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public AllAssetsOperationHandle LoadAllAssetsAsync(AssetInfo assetInfo)
```
- 新增了ResourcePackage.GetAssetInfoByGUID()方法
```c#
/// <summary>
/// 获取资源信息
/// </summary>
/// <param name="assetGUID">资源GUID</param>
public AssetInfo GetAssetInfoByGUID(string assetGUID)
```
- 新增了场景加载参数suspendLoad
```c#
/// <summary>
/// 异步加载场景
/// </summary>
/// <param name="location">场景的定位地址</param>
/// <param name="sceneMode">场景加载模式</param>
/// <param name="suspendLoad">场景加载到90%自动挂起</param>
/// <param name="priority">优先级</param>
public SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100)
```
- Extension Sample 增加了GameObjectAssetReference示例脚本
- 新增加了ZeroRedundancySharedPackRule类零冗余的共享资源打包规则
- 新增加了FullRedundancySharedPackRule类全部冗余的共享资源打包规则
### Removed
- 移除了InitializeParameters.LocationToLower成员字段
- 移除了LoadSceneAsync方法里的activateOnLoad形参参数
- 移除了BuildParameters.AutoAnalyzeRedundancy成员字段
- 移除了DefaultShareAssetPackRule编辑器类
## [1.4.16] - 2023-06-14 ## [1.4.16] - 2023-06-14
### Changed ### Changed

View File

@ -1,6 +1,8 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using UnityEngine; using UnityEngine;
using UnityEditor; using UnityEditor;
@ -11,80 +13,30 @@ namespace YooAsset.Editor
private readonly BuildContext _buildContext = new BuildContext(); private readonly BuildContext _buildContext = new BuildContext();
/// <summary> /// <summary>
/// 开始构建 /// 构建资源包
/// </summary> /// </summary>
public BuildResult Run(BuildParameters buildParameters) public BuildResult Run(BuildParameters buildParameters, List<IBuildTask> buildPipeline)
{ {
// 清空旧数据
_buildContext.ClearAllContext();
// 检测构建参数是否为空 // 检测构建参数是否为空
if (buildParameters == null) if (buildParameters == null)
throw new Exception($"{nameof(buildParameters)} is null !"); throw new Exception($"{nameof(buildParameters)} is null !");
// 检测可编程构建管线参数 // 检测构建参数是否为空
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline) if (buildPipeline.Count == 0)
{ throw new Exception($"Build pipeline is empty !");
if (buildParameters.SBPParameters == null)
throw new Exception($"{nameof(BuildParameters.SBPParameters)} is null !");
if (buildParameters.BuildMode == EBuildMode.DryRunBuild) // 清空旧数据
throw new Exception($"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.DryRunBuild)} build mode !"); _buildContext.ClearAllContext();
if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
throw new Exception($"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.ForceRebuild)} build mode !");
}
// 构建参数 // 构建参数
var buildParametersContext = new BuildParametersContext(buildParameters); var buildParametersContext = new BuildParametersContext(buildParameters);
_buildContext.SetContextObject(buildParametersContext); _buildContext.SetContextObject(buildParametersContext);
// 创建构建节点
List<IBuildTask> pipeline;
if (buildParameters.BuildPipeline == EBuildPipeline.BuiltinBuildPipeline)
{
pipeline = new List<IBuildTask>
{
new TaskPrepare(), //前期准备工作
new TaskGetBuildMap(), //获取构建列表
new TaskBuilding(), //开始执行构建
new TaskCopyRawFile(), //拷贝原生文件
new TaskVerifyBuildResult(), //验证构建结果
new TaskEncryption(), //加密资源文件
new TaskUpdateBundleInfo(), //更新资源包信息
new TaskCreateManifest(), //创建清单文件
new TaskCreateReport(), //创建报告文件
new TaskCreatePackage(), //制作包裹
new TaskCopyBuildinFiles(), //拷贝内置文件
};
}
else if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
pipeline = new List<IBuildTask>
{
new TaskPrepare(), //前期准备工作
new TaskGetBuildMap(), //获取构建列表
new TaskBuilding_SBP(), //开始执行构建
new TaskCopyRawFile(), //拷贝原生文件
new TaskVerifyBuildResult_SBP(), //验证构建结果
new TaskEncryption(), //加密资源文件
new TaskUpdateBundleInfo(), //更新补丁信息
new TaskCreateManifest(), //创建清单文件
new TaskCreateReport(), //创建报告文件
new TaskCreatePackage(), //制作补丁包
new TaskCopyBuildinFiles(), //拷贝内置文件
};
}
else
{
throw new NotImplementedException();
}
// 初始化日志 // 初始化日志
BuildLogger.InitLogger(buildParameters.EnableLog); BuildLogger.InitLogger(buildParameters.EnableLog);
// 执行构建流程 // 执行构建流程
var buildResult = BuildRunner.Run(pipeline, _buildContext); var buildResult = BuildRunner.Run(buildPipeline, _buildContext);
if (buildResult.Success) if (buildResult.Success)
{ {
buildResult.OutputPackageDirectory = buildParametersContext.GetPackageOutputDirectory(); buildResult.OutputPackageDirectory = buildParametersContext.GetPackageOutputDirectory();
@ -99,5 +51,62 @@ namespace YooAsset.Editor
return buildResult; return buildResult;
} }
/// <summary>
/// 构建资源包
/// </summary>
public BuildResult Run(BuildParameters buildParameters)
{
var buildPipeline = GetDefaultBuildPipeline(buildParameters.BuildPipeline);
return Run(buildParameters, buildPipeline);
}
/// <summary>
/// 获取默认的构建流程
/// </summary>
private List<IBuildTask> GetDefaultBuildPipeline(EBuildPipeline buildPipeline)
{
// 获取任务节点的属性集合
if (buildPipeline == EBuildPipeline.BuiltinBuildPipeline)
{
List<IBuildTask> pipeline = new List<IBuildTask>
{
new TaskPrepare(), //前期准备工作
new TaskGetBuildMap(), //获取构建列表
new TaskBuilding(), //开始执行构建
new TaskCopyRawFile(), //拷贝原生文件
new TaskVerifyBuildResult(), //验证构建结果
new TaskEncryption(), //加密资源文件
new TaskUpdateBundleInfo(), //更新资源包信息
new TaskCreateManifest(), //创建清单文件
new TaskCreateReport(), //创建报告文件
new TaskCreatePackage(), //制作包裹
new TaskCopyBuildinFiles(), //拷贝内置文件
};
return pipeline;
}
else if (buildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
List<IBuildTask> pipeline = new List<IBuildTask>
{
new TaskPrepare(), //前期准备工作
new TaskGetBuildMap(), //获取构建列表
new TaskBuilding_SBP(), //开始执行构建
new TaskCopyRawFile(), //拷贝原生文件
new TaskVerifyBuildResult_SBP(), //验证构建结果
new TaskEncryption(), //加密资源文件
new TaskUpdateBundleInfo(), //更新补丁信息
new TaskCreateManifest(), //创建清单文件
new TaskCreateReport(), //创建报告文件
new TaskCreatePackage(), //制作补丁包
new TaskCopyBuildinFiles(), //拷贝内置文件
};
return pipeline;
}
else
{
throw new NotImplementedException();
}
}
} }
} }

View File

@ -11,7 +11,7 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 获取默认的输出根路录 /// 获取默认的输出根路录
/// </summary> /// </summary>
public static string GetDefaultOutputRoot() public static string GetDefaultBuildOutputRoot()
{ {
string projectPath = EditorTools.GetProjectPath(); string projectPath = EditorTools.GetProjectPath();
return $"{projectPath}/Bundles"; return $"{projectPath}/Bundles";
@ -20,43 +20,9 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 获取流文件夹路径 /// 获取流文件夹路径
/// </summary> /// </summary>
public static string GetStreamingAssetsFolderPath() public static string GetDefaultStreamingAssetsRoot()
{ {
return $"{Application.dataPath}/StreamingAssets/{YooAssetSettings.StreamingAssetsBuildinFolder}/"; return $"{Application.dataPath}/StreamingAssets/{YooAssetSettings.DefaultYooFolderName}/";
}
/// <summary>
/// 清空流文件夹
/// </summary>
public static void ClearStreamingAssetsFolder()
{
string streamingFolderPath = GetStreamingAssetsFolderPath();
EditorTools.ClearFolder(streamingFolderPath);
}
/// <summary>
/// 删除流文件夹内无关的文件
/// 删除.manifest文件和.meta文件
/// </summary>
public static void DeleteStreamingAssetsIgnoreFiles()
{
string streamingFolderPath = GetStreamingAssetsFolderPath();
if (Directory.Exists(streamingFolderPath))
{
string[] files = Directory.GetFiles(streamingFolderPath, "*.manifest", SearchOption.AllDirectories);
foreach (var file in files)
{
FileInfo info = new FileInfo(file);
info.Delete();
}
files = Directory.GetFiles(streamingFolderPath, "*.meta", SearchOption.AllDirectories);
foreach (var item in files)
{
FileInfo info = new FileInfo(item);
info.Delete();
}
}
} }
} }
} }

View File

@ -63,7 +63,7 @@ namespace YooAsset.Editor
_encryptionServicesClassNames = _encryptionServicesClassTypes.Select(t => t.Name).ToList(); _encryptionServicesClassNames = _encryptionServicesClassTypes.Select(t => t.Name).ToList();
// 输出目录 // 输出目录
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot(); string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
_buildOutputField = root.Q<TextField>("BuildOutput"); _buildOutputField = root.Q<TextField>("BuildOutput");
_buildOutputField.SetValueWithoutNotify(defaultOutputRoot); _buildOutputField.SetValueWithoutNotify(defaultOutputRoot);
_buildOutputField.SetEnabled(false); _buildOutputField.SetEnabled(false);
@ -266,17 +266,16 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
private void ExecuteBuild() private void ExecuteBuild()
{ {
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot();
BuildParameters buildParameters = new BuildParameters(); BuildParameters buildParameters = new BuildParameters();
buildParameters.OutputRoot = defaultOutputRoot; buildParameters.StreamingAssetsRoot = AssetBundleBuilderHelper.GetDefaultStreamingAssetsRoot();
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildTarget = _buildTarget; buildParameters.BuildTarget = _buildTarget;
buildParameters.BuildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline; buildParameters.BuildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline;
buildParameters.BuildMode = AssetBundleBuilderSettingData.Setting.BuildMode; buildParameters.BuildMode = AssetBundleBuilderSettingData.Setting.BuildMode;
buildParameters.PackageName = AssetBundleBuilderSettingData.Setting.BuildPackage; buildParameters.PackageName = AssetBundleBuilderSettingData.Setting.BuildPackage;
buildParameters.PackageVersion = _buildVersionField.value; buildParameters.PackageVersion = _buildVersionField.value;
buildParameters.VerifyBuildingResult = true; buildParameters.VerifyBuildingResult = true;
buildParameters.AutoAnalyzeRedundancy = true; buildParameters.SharedPackRule = new ZeroRedundancySharedPackRule();
buildParameters.ShareAssetPackRule = new DefaultShareAssetPackRule();
buildParameters.EncryptionServices = CreateEncryptionServicesInstance(); buildParameters.EncryptionServices = CreateEncryptionServicesInstance();
buildParameters.CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption; buildParameters.CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption;
buildParameters.OutputNameStyle = AssetBundleBuilderSettingData.Setting.OutputNameStyle; buildParameters.OutputNameStyle = AssetBundleBuilderSettingData.Setting.OutputNameStyle;

View File

@ -11,9 +11,9 @@ namespace YooAsset.Editor
public static string SimulateBuild(string packageName) public static string SimulateBuild(string packageName)
{ {
Debug.Log($"Begin to create simulate package : {packageName}"); Debug.Log($"Begin to create simulate package : {packageName}");
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot();
BuildParameters buildParameters = new BuildParameters(); BuildParameters buildParameters = new BuildParameters();
buildParameters.OutputRoot = defaultOutputRoot; buildParameters.StreamingAssetsRoot = AssetBundleBuilderHelper.GetDefaultStreamingAssetsRoot();
buildParameters.BuildOutputRoot = AssetBundleBuilderHelper.GetDefaultBuildOutputRoot();
buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget; buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget;
buildParameters.BuildMode = EBuildMode.SimulateBuild; buildParameters.BuildMode = EBuildMode.SimulateBuild;
buildParameters.PackageName = packageName; buildParameters.PackageName = packageName;

View File

@ -30,6 +30,11 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public string AssetPath { private set; get; } public string AssetPath { private set; get; }
/// <summary>
/// 资源GUID
/// </summary>
public string AssetGUID { private set; get; }
/// <summary> /// <summary>
/// 是否为原生资源 /// 是否为原生资源
/// </summary> /// </summary>
@ -65,6 +70,7 @@ namespace YooAsset.Editor
AssetPath = assetPath; AssetPath = assetPath;
IsRawAsset = isRawAsset; IsRawAsset = isRawAsset;
AssetGUID = UnityEditor.AssetDatabase.AssetPathToGUID(assetPath);
System.Type assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(assetPath); System.Type assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection)) if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection))
IsShaderAsset = true; IsShaderAsset = true;
@ -78,6 +84,7 @@ namespace YooAsset.Editor
AssetPath = assetPath; AssetPath = assetPath;
IsRawAsset = false; IsRawAsset = false;
AssetGUID = UnityEditor.AssetDatabase.AssetPathToGUID(assetPath);
System.Type assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(assetPath); System.Type assetType = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(assetPath);
if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection)) if (assetType == typeof(UnityEngine.Shader) || assetType == typeof(UnityEngine.ShaderVariantCollection))
IsShaderAsset = true; IsShaderAsset = true;
@ -157,7 +164,7 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 计算共享资源包的完整包名 /// 计算共享资源包的完整包名
/// </summary> /// </summary>
public void CalculateShareBundleName(IShareAssetPackRule packRule, bool uniqueBundleName, string packageName, string shadersBundleName) public void CalculateShareBundleName(ISharedPackRule sharedPackRule, bool uniqueBundleName, string packageName, string shadersBundleName)
{ {
if (CollectorType != ECollectorType.None) if (CollectorType != ECollectorType.None)
return; return;
@ -173,7 +180,7 @@ namespace YooAsset.Editor
{ {
if (_referenceBundleNames.Count > 1) if (_referenceBundleNames.Count > 1)
{ {
PackRuleResult packRuleResult = packRule.GetPackRuleResult(AssetPath); PackRuleResult packRuleResult = sharedPackRule.GetPackRuleResult(AssetPath);
BundleName = packRuleResult.GetShareBundleName(packageName, uniqueBundleName); BundleName = packRuleResult.GetShareBundleName(packageName, uniqueBundleName);
} }
else else
@ -189,12 +196,9 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public bool IsRedundancyAsset() public bool IsRedundancyAsset()
{ {
if (CollectorType != ECollectorType.None) if (HasBundleName())
return false; return false;
if (IsRawAsset)
throw new Exception("Should never get here !");
return _referenceBundleNames.Count > 1; return _referenceBundleNames.Count > 1;
} }

View File

@ -49,7 +49,7 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 参与构建的资源列表 /// 参与构建的资源列表
/// 注意:不包含零依赖资源 /// 注意:不包含零依赖资源和冗余资源
/// </summary> /// </summary>
public readonly List<BuildAssetInfo> AllMainAssets = new List<BuildAssetInfo>(); public readonly List<BuildAssetInfo> AllMainAssets = new List<BuildAssetInfo>();
@ -149,7 +149,15 @@ namespace YooAsset.Editor
} }
/// <summary> /// <summary>
/// 获取该资源包内的所有资源(包括零依赖资源) /// 获取构建的资源路径列表
/// </summary>
public string[] GetAllMainAssetPaths()
{
return AllMainAssets.Select(t => t.AssetPath).ToArray();
}
/// <summary>
/// 获取该资源包内的所有资源(包括零依赖资源和冗余资源)
/// </summary> /// </summary>
public List<string> GetAllBuiltinAssetPaths() public List<string> GetAllBuiltinAssetPaths()
{ {
@ -161,6 +169,7 @@ namespace YooAsset.Editor
continue; continue;
foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos) foreach (var dependAssetInfo in assetInfo.AllDependAssetInfos)
{ {
// 注意:依赖资源里只添加零依赖资源和冗余资源
if (dependAssetInfo.HasBundleName() == false) if (dependAssetInfo.HasBundleName() == false)
{ {
if (result.Contains(dependAssetInfo.AssetPath) == false) if (result.Contains(dependAssetInfo.AssetPath) == false)
@ -171,22 +180,6 @@ namespace YooAsset.Editor
return result; return result;
} }
/// <summary>
/// 获取构建的资源路径列表
/// </summary>
public string[] GetAllMainAssetPaths()
{
return AllMainAssets.Select(t => t.AssetPath).ToArray();
}
/// <summary>
/// 获取所有写入补丁清单的资源
/// </summary>
public BuildAssetInfo[] GetAllMainAssetInfos()
{
return AllMainAssets.Where(t => t.CollectorType == ECollectorType.MainAssetCollector).ToArray();
}
/// <summary> /// <summary>
/// 创建AssetBundleBuild类 /// 创建AssetBundleBuild类
/// </summary> /// </summary>
@ -200,6 +193,14 @@ namespace YooAsset.Editor
return build; return build;
} }
/// <summary>
/// 获取所有写入补丁清单的资源
/// </summary>
public BuildAssetInfo[] GetAllManifestAssetInfos()
{
return AllMainAssets.Where(t => t.CollectorType == ECollectorType.MainAssetCollector).ToArray();
}
/// <summary> /// <summary>
/// 创建PackageBundle类 /// 创建PackageBundle类
/// </summary> /// </summary>

View File

@ -22,19 +22,9 @@ namespace YooAsset.Editor
public int AssetFileCount; public int AssetFileCount;
/// <summary> /// <summary>
/// 是否启用可寻址资源定位 /// 收集命令
/// </summary> /// </summary>
public bool EnableAddressable; public CollectCommand Command { set; get; }
/// <summary>
/// 资源包名唯一化
/// </summary>
public bool UniqueBundleName;
/// <summary>
/// 着色器统一的全名称
/// </summary>
public string ShadersBundleName;
/// <summary> /// <summary>
/// 资源包信息列表 /// 资源包信息列表

View File

@ -37,9 +37,14 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 输出的根目录 /// 内置资源的根目录
/// </summary> /// </summary>
public string OutputRoot; public string StreamingAssetsRoot;
/// <summary>
/// 构建输出的根目录
/// </summary>
public string BuildOutputRoot;
/// <summary> /// <summary>
/// 构建的平台 /// 构建的平台
@ -76,16 +81,11 @@ namespace YooAsset.Editor
/// 验证构建结果 /// 验证构建结果
/// </summary> /// </summary>
public bool VerifyBuildingResult = false; public bool VerifyBuildingResult = false;
/// <summary>
/// 自动分析冗余资源
/// </summary>
public bool AutoAnalyzeRedundancy = true;
/// <summary> /// <summary>
/// 共享资源的打包规则 /// 共享资源的打包规则
/// </summary> /// </summary>
public IShareAssetPackRule ShareAssetPackRule = null; public ISharedPackRule SharedPackRule = null;
/// <summary> /// <summary>
/// 资源的加密接口 /// 资源的加密接口

View File

@ -9,6 +9,8 @@ namespace YooAsset.Editor
{ {
private string _pipelineOutputDirectory = string.Empty; private string _pipelineOutputDirectory = string.Empty;
private string _packageOutputDirectory = string.Empty; private string _packageOutputDirectory = string.Empty;
private string _packageRootDirectory = string.Empty;
private string _streamingAssetsDirectory = string.Empty;
/// <summary> /// <summary>
/// 构建参数 /// 构建参数
@ -29,23 +31,47 @@ namespace YooAsset.Editor
{ {
if (string.IsNullOrEmpty(_pipelineOutputDirectory)) if (string.IsNullOrEmpty(_pipelineOutputDirectory))
{ {
_pipelineOutputDirectory = $"{Parameters.OutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}/{YooAssetSettings.OutputFolderName}"; _pipelineOutputDirectory = $"{Parameters.BuildOutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}/{YooAssetSettings.OutputFolderName}";
} }
return _pipelineOutputDirectory; return _pipelineOutputDirectory;
} }
/// <summary> /// <summary>
/// 获取本次构建的补丁目录 /// 获取本次构建的补丁输出目录
/// </summary> /// </summary>
public string GetPackageOutputDirectory() public string GetPackageOutputDirectory()
{ {
if (string.IsNullOrEmpty(_packageOutputDirectory)) if (string.IsNullOrEmpty(_packageOutputDirectory))
{ {
_packageOutputDirectory = $"{Parameters.OutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}/{Parameters.PackageVersion}"; _packageOutputDirectory = $"{Parameters.BuildOutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}/{Parameters.PackageVersion}";
} }
return _packageOutputDirectory; return _packageOutputDirectory;
} }
/// <summary>
/// 获取本次构建的补丁根目录
/// </summary>
public string GetPackageRootDirectory()
{
if (string.IsNullOrEmpty(_packageRootDirectory))
{
_packageRootDirectory = $"{Parameters.BuildOutputRoot}/{Parameters.BuildTarget}/{Parameters.PackageName}";
}
return _packageRootDirectory;
}
/// <summary>
/// 获取内置资源的目录
/// </summary>
public string GetStreamingAssetsDirectory()
{
if (string.IsNullOrEmpty(_streamingAssetsDirectory))
{
_streamingAssetsDirectory = $"{Parameters.StreamingAssetsRoot}/{Parameters.PackageName}";
}
return _streamingAssetsDirectory;
}
/// <summary> /// <summary>
/// 获取内置构建管线的构建选项 /// 获取内置构建管线的构建选项
/// </summary> /// </summary>

View File

@ -58,20 +58,25 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public bool EnableAddressable; public bool EnableAddressable;
/// <summary>
/// 资源定位地址大小写不敏感
/// </summary>
public bool LocationToLower;
/// <summary>
/// 包含资源GUID数据
/// </summary>
public bool IncludeAssetGUID;
/// <summary> /// <summary>
/// 资源包名唯一化 /// 资源包名唯一化
/// </summary> /// </summary>
public bool UniqueBundleName; public bool UniqueBundleName;
/// <summary> /// <summary>
/// 自动分析冗余 /// 共享资源的打包规则类名
/// </summary> /// </summary>
public bool AutoAnalyzeRedundancy; public string SharedPackRuleClassName;
/// <summary>
/// 共享资源的打包类名称
/// </summary>
public string ShareAssetPackRuleClassName;
/// <summary> /// <summary>
/// 加密服务类名称 /// 加密服务类名称

View File

@ -38,7 +38,7 @@ namespace YooAsset.Editor
_buildWatch = Stopwatch.StartNew(); _buildWatch = Stopwatch.StartNew();
var taskAttribute = task.GetType().GetCustomAttribute<TaskAttribute>(); var taskAttribute = task.GetType().GetCustomAttribute<TaskAttribute>();
if (taskAttribute != null) if (taskAttribute != null)
BuildLogger.Log($"---------------------------------------->{taskAttribute.Desc}<---------------------------------------"); BuildLogger.Log($"---------------------------------------->{taskAttribute.TaskDesc}<---------------------------------------");
task.Run(context); task.Run(context);
_buildWatch.Stop(); _buildWatch.Stop();
@ -46,7 +46,7 @@ namespace YooAsset.Editor
int seconds = GetBuildSeconds(); int seconds = GetBuildSeconds();
TotalSeconds += seconds; TotalSeconds += seconds;
if (taskAttribute != null) if (taskAttribute != null)
BuildLogger.Log($"{taskAttribute.Desc}耗时:{seconds}秒"); BuildLogger.Log($"{taskAttribute.TaskDesc}耗时:{seconds}秒");
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -5,10 +5,14 @@ namespace YooAsset.Editor
[AttributeUsage(AttributeTargets.Class)] [AttributeUsage(AttributeTargets.Class)]
public class TaskAttribute : Attribute public class TaskAttribute : Attribute
{ {
public string Desc; /// <summary>
public TaskAttribute(string desc) /// 任务说明
/// </summary>
public string TaskDesc;
public TaskAttribute(string taskDesc)
{ {
Desc = desc; TaskDesc = taskDesc;
} }
} }
} }

View File

@ -33,7 +33,7 @@ namespace YooAsset.Editor
// 开始构建 // 开始构建
IBundleBuildResults buildResults; IBundleBuildResults buildResults;
var buildParameters = buildParametersContext.GetSBPBuildParameters(); var buildParameters = buildParametersContext.GetSBPBuildParameters();
var taskList = SBPBuildTasks.Create(buildMapContext.ShadersBundleName); var taskList = SBPBuildTasks.Create(buildMapContext.Command.ShadersBundleName);
ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParameters, buildContent, out buildResults, taskList); ReturnCode exitCode = ContentPipeline.BuildAssetBundles(buildParameters, buildContent, out buildResults, taskList);
if (exitCode < 0) if (exitCode < 0)
{ {
@ -43,7 +43,7 @@ namespace YooAsset.Editor
// 创建着色器信息 // 创建着色器信息
// 说明:解决因为着色器资源包导致验证失败。 // 说明:解决因为着色器资源包导致验证失败。
// 例如:当项目里没有着色器,如果有依赖内置着色器就会验证失败。 // 例如:当项目里没有着色器,如果有依赖内置着色器就会验证失败。
string shadersBundleName = buildMapContext.ShadersBundleName; string shadersBundleName = buildMapContext.Command.ShadersBundleName;
if (buildResults.BundleInfos.ContainsKey(shadersBundleName)) if (buildResults.BundleInfos.ContainsKey(shadersBundleName))
{ {
buildMapContext.CreateShadersBundleInfo(shadersBundleName); buildMapContext.CreateShadersBundleInfo(shadersBundleName);

View File

@ -30,7 +30,7 @@ namespace YooAsset.Editor
{ {
ECopyBuildinFileOption option = buildParametersContext.Parameters.CopyBuildinFileOption; ECopyBuildinFileOption option = buildParametersContext.Parameters.CopyBuildinFileOption;
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory(); string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
string streamingAssetsDirectory = AssetBundleBuilderHelper.GetStreamingAssetsFolderPath(); string streamingAssetsDirectory = buildParametersContext.GetStreamingAssetsDirectory();
string buildPackageName = buildParametersContext.Parameters.PackageName; string buildPackageName = buildParametersContext.Parameters.PackageName;
string buildPackageVersion = buildParametersContext.Parameters.PackageVersion; string buildPackageVersion = buildParametersContext.Parameters.PackageVersion;
@ -40,7 +40,7 @@ namespace YooAsset.Editor
// 清空流目录 // 清空流目录
if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.ClearAndCopyByTags) if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.ClearAndCopyByTags)
{ {
AssetBundleBuilderHelper.ClearStreamingAssetsFolder(); EditorTools.ClearFolder(streamingAssetsDirectory);
} }
// 拷贝补丁清单文件 // 拷贝补丁清单文件
@ -69,7 +69,7 @@ namespace YooAsset.Editor
// 拷贝文件列表(所有文件) // 拷贝文件列表(所有文件)
if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.OnlyCopyAll) if (option == ECopyBuildinFileOption.ClearAndCopyAll || option == ECopyBuildinFileOption.OnlyCopyAll)
{ {
foreach (var packageBundle in manifest.BundleList) foreach (var packageBundle in manifest.BundleList)
{ {
string sourcePath = $"{packageOutputDirectory}/{packageBundle.FileName}"; string sourcePath = $"{packageOutputDirectory}/{packageBundle.FileName}";

View File

@ -34,7 +34,9 @@ namespace YooAsset.Editor
// 创建新补丁清单 // 创建新补丁清单
PackageManifest manifest = new PackageManifest(); PackageManifest manifest = new PackageManifest();
manifest.FileVersion = YooAssetSettings.ManifestFileVersion; manifest.FileVersion = YooAssetSettings.ManifestFileVersion;
manifest.EnableAddressable = buildMapContext.EnableAddressable; manifest.EnableAddressable = buildMapContext.Command.EnableAddressable;
manifest.LocationToLower = buildMapContext.Command.LocationToLower;
manifest.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID;
manifest.OutputNameStyle = (int)buildParameters.OutputNameStyle; manifest.OutputNameStyle = (int)buildParameters.OutputNameStyle;
manifest.PackageName = buildParameters.PackageName; manifest.PackageName = buildParameters.PackageName;
manifest.PackageVersion = buildParameters.PackageVersion; manifest.PackageVersion = buildParameters.PackageVersion;
@ -47,7 +49,7 @@ namespace YooAsset.Editor
if (buildParameters.BuildMode == EBuildMode.IncrementalBuild) if (buildParameters.BuildMode == EBuildMode.IncrementalBuild)
{ {
var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>(); var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
UpdateBuiltInBundleReference(manifest, buildResultContext, buildMapContext.ShadersBundleName); UpdateBuiltInBundleReference(manifest, buildResultContext, buildMapContext.Command.ShadersBundleName);
} }
} }
@ -137,15 +139,13 @@ namespace YooAsset.Editor
List<PackageAsset> result = new List<PackageAsset>(1000); List<PackageAsset> result = new List<PackageAsset>(1000);
foreach (var bundleInfo in buildMapContext.Collection) foreach (var bundleInfo in buildMapContext.Collection)
{ {
var assetInfos = bundleInfo.GetAllMainAssetInfos(); var assetInfos = bundleInfo.GetAllManifestAssetInfos();
foreach (var assetInfo in assetInfos) foreach (var assetInfo in assetInfos)
{ {
PackageAsset packageAsset = new PackageAsset(); PackageAsset packageAsset = new PackageAsset();
if (buildMapContext.EnableAddressable) packageAsset.Address = buildMapContext.Command.EnableAddressable ? assetInfo.Address : string.Empty;
packageAsset.Address = assetInfo.Address;
else
packageAsset.Address = string.Empty;
packageAsset.AssetPath = assetInfo.AssetPath; packageAsset.AssetPath = assetInfo.AssetPath;
packageAsset.AssetGUID = buildMapContext.Command.IncludeAssetGUID ? assetInfo.AssetGUID : string.Empty;
packageAsset.AssetTags = assetInfo.AssetTags.ToArray(); packageAsset.AssetTags = assetInfo.AssetTags.ToArray();
packageAsset.BundleID = GetAssetBundleID(assetInfo.BundleName, manifest); packageAsset.BundleID = GetAssetBundleID(assetInfo.BundleName, manifest);
packageAsset.DependIDs = GetAssetBundleDependIDs(packageAsset.BundleID, assetInfo, manifest); packageAsset.DependIDs = GetAssetBundleDependIDs(packageAsset.BundleID, assetInfo, manifest);

View File

@ -45,11 +45,12 @@ namespace YooAsset.Editor
buildReport.Summary.BuildMode = buildParameters.BuildMode; buildReport.Summary.BuildMode = buildParameters.BuildMode;
buildReport.Summary.BuildPackageName = buildParameters.PackageName; buildReport.Summary.BuildPackageName = buildParameters.PackageName;
buildReport.Summary.BuildPackageVersion = buildParameters.PackageVersion; buildReport.Summary.BuildPackageVersion = buildParameters.PackageVersion;
buildReport.Summary.EnableAddressable = buildMapContext.EnableAddressable; buildReport.Summary.EnableAddressable = buildMapContext.Command.EnableAddressable;
buildReport.Summary.UniqueBundleName = buildMapContext.UniqueBundleName; buildReport.Summary.LocationToLower = buildMapContext.Command.LocationToLower;
buildReport.Summary.AutoAnalyzeRedundancy = buildParameters.AutoAnalyzeRedundancy; buildReport.Summary.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID;
buildReport.Summary.ShareAssetPackRuleClassName = buildParameters.ShareAssetPackRule == null ? buildReport.Summary.UniqueBundleName = buildMapContext.Command.UniqueBundleName;
"null" : buildParameters.ShareAssetPackRule.GetType().FullName; buildReport.Summary.SharedPackRuleClassName = buildParameters.SharedPackRule == null ?
"null" : buildParameters.SharedPackRule.GetType().FullName;
buildReport.Summary.EncryptionServicesClassName = buildParameters.EncryptionServices == null ? buildReport.Summary.EncryptionServicesClassName = buildParameters.EncryptionServices == null ?
"null" : buildParameters.EncryptionServices.GetType().FullName; "null" : buildParameters.EncryptionServices.GetType().FullName;
@ -159,7 +160,7 @@ namespace YooAsset.Editor
} }
/// <summary> /// <summary>
/// 获取该资源包内的所有资源(包括零依赖资源) /// 获取该资源包内的所有资源
/// </summary> /// </summary>
private List<string> GetAllBuiltinAssets(BuildMapContext buildMapContext, string bundleName) private List<string> GetAllBuiltinAssets(BuildMapContext buildMapContext, string bundleName)
{ {

View File

@ -26,10 +26,9 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public BuildMapContext CreateBuildMap(BuildParameters buildParameters) public BuildMapContext CreateBuildMap(BuildParameters buildParameters)
{ {
EBuildMode buildMode = buildParameters.BuildMode; var buildMode = buildParameters.BuildMode;
string packageName = buildParameters.PackageName; var packageName = buildParameters.PackageName;
IShareAssetPackRule sharePackRule = buildParameters.ShareAssetPackRule; var sharedPackRule = buildParameters.SharedPackRule;
bool autoAnalyzeRedundancy = buildParameters.AutoAnalyzeRedundancy;
Dictionary<string, BuildAssetInfo> allBuildAssetInfoDic = new Dictionary<string, BuildAssetInfo>(1000); Dictionary<string, BuildAssetInfo> allBuildAssetInfoDic = new Dictionary<string, BuildAssetInfo>(1000);
@ -98,38 +97,31 @@ namespace YooAsset.Editor
// 7. 记录关键信息 // 7. 记录关键信息
BuildMapContext context = new BuildMapContext(); BuildMapContext context = new BuildMapContext();
context.AssetFileCount = allBuildAssetInfoDic.Count; context.AssetFileCount = allBuildAssetInfoDic.Count;
context.EnableAddressable = collectResult.Command.EnableAddressable; context.Command = collectResult.Command;
context.UniqueBundleName = collectResult.Command.UniqueBundleName;
context.ShadersBundleName = collectResult.Command.ShadersBundleName;
// 8. 计算共享的资源包名 // 8. 计算共享资源的包名
if (autoAnalyzeRedundancy) var command = collectResult.Command;
foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
{ {
var command = collectResult.Command; buildAssetInfo.CalculateShareBundleName(sharedPackRule, command.UniqueBundleName, command.PackageName, command.ShadersBundleName);
foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
{
buildAssetInfo.CalculateShareBundleName(sharePackRule, command.UniqueBundleName, command.PackageName, command.ShadersBundleName);
}
} }
else
// 9. 记录冗余资源
foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
{ {
// 记录冗余资源 if (buildAssetInfo.IsRedundancyAsset())
foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
{ {
if (buildAssetInfo.IsRedundancyAsset()) var redundancyInfo = new ReportRedundancyInfo();
{ redundancyInfo.AssetPath = buildAssetInfo.AssetPath;
var redundancyInfo = new ReportRedundancyInfo(); redundancyInfo.AssetType = AssetDatabase.GetMainAssetTypeAtPath(buildAssetInfo.AssetPath).Name;
redundancyInfo.AssetPath = buildAssetInfo.AssetPath; redundancyInfo.AssetGUID = AssetDatabase.AssetPathToGUID(buildAssetInfo.AssetPath);
redundancyInfo.AssetType = AssetDatabase.GetMainAssetTypeAtPath(buildAssetInfo.AssetPath).Name; redundancyInfo.FileSize = FileUtility.GetFileSize(buildAssetInfo.AssetPath);
redundancyInfo.AssetGUID = AssetDatabase.AssetPathToGUID(buildAssetInfo.AssetPath); redundancyInfo.Number = buildAssetInfo.GetReferenceBundleCount();
redundancyInfo.FileSize = FileUtility.GetFileSize(buildAssetInfo.AssetPath); context.RedundancyInfos.Add(redundancyInfo);
redundancyInfo.Number = buildAssetInfo.GetReferenceBundleCount();
context.RedundancyInfos.Add(redundancyInfo);
}
} }
} }
// 9. 移除不参与构建的资源 // 10. 移除不参与构建的资源
List<BuildAssetInfo> removeBuildList = new List<BuildAssetInfo>(); List<BuildAssetInfo> removeBuildList = new List<BuildAssetInfo>();
foreach (var buildAssetInfo in allBuildAssetInfoDic.Values) foreach (var buildAssetInfo in allBuildAssetInfoDic.Values)
{ {
@ -141,7 +133,7 @@ namespace YooAsset.Editor
allBuildAssetInfoDic.Remove(removeValue.AssetPath); allBuildAssetInfoDic.Remove(removeValue.AssetPath);
} }
// 10. 构建资源包 // 11. 构建资源列表
var allPackAssets = allBuildAssetInfoDic.Values.ToList(); var allPackAssets = allBuildAssetInfoDic.Values.ToList();
if (allPackAssets.Count == 0) if (allPackAssets.Count == 0)
throw new Exception("构建的资源列表不能为空"); throw new Exception("构建的资源列表不能为空");
@ -149,22 +141,23 @@ namespace YooAsset.Editor
{ {
context.PackAsset(assetInfo); context.PackAsset(assetInfo);
} }
return context; return context;
} }
private void RemoveZeroReferenceAssets(List<CollectAssetInfo> allCollectAssetInfos) private void RemoveZeroReferenceAssets(List<CollectAssetInfo> allCollectAssetInfos)
{ {
// 1. 检测是否任何存在依赖资源 // 1. 检测是否任何存在依赖资源
bool hasAnyDependAsset = false; bool hasAnyDependCollector = false;
foreach (var collectAssetInfo in allCollectAssetInfos) foreach (var collectAssetInfo in allCollectAssetInfos)
{ {
var collectorType = collectAssetInfo.CollectorType; var collectorType = collectAssetInfo.CollectorType;
if (collectorType == ECollectorType.DependAssetCollector) if (collectorType == ECollectorType.DependAssetCollector)
{ {
hasAnyDependAsset = true; hasAnyDependCollector = true;
break; break;
} }
} }
if (hasAnyDependAsset == false) if (hasAnyDependCollector == false)
return; return;
// 2. 获取所有主资源的依赖资源集合 // 2. 获取所有主资源的依赖资源集合

View File

@ -16,11 +16,27 @@ namespace YooAsset.Editor
// 检测构建参数合法性 // 检测构建参数合法性
if (buildParameters.BuildTarget == BuildTarget.NoTarget) if (buildParameters.BuildTarget == BuildTarget.NoTarget)
throw new Exception("请选择目标平台"); throw new Exception("请选择目标平台");
if (string.IsNullOrEmpty(buildParameters.PackageName)) if (string.IsNullOrEmpty(buildParameters.PackageName))
throw new Exception("包裹名称不能为空"); throw new Exception("包裹名称不能为空");
if (string.IsNullOrEmpty(buildParameters.PackageVersion)) if (string.IsNullOrEmpty(buildParameters.PackageVersion))
throw new Exception("包裹版本不能为空"); throw new Exception("包裹版本不能为空!");
if (string.IsNullOrEmpty(buildParameters.BuildOutputRoot))
throw new Exception("构建输出的根目录为空!");
if (string.IsNullOrEmpty(buildParameters.StreamingAssetsRoot))
throw new Exception("内置资源根目录为空!");
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
if (buildParameters.SBPParameters == null)
throw new Exception($"{nameof(BuildParameters.SBPParameters)} is null !");
if (buildParameters.BuildMode == EBuildMode.DryRunBuild)
throw new Exception($"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.DryRunBuild)} build mode !");
if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
throw new Exception($"{nameof(EBuildPipeline.ScriptableBuildPipeline)} not support {nameof(EBuildMode.ForceRebuild)} build mode !");
}
if (buildParameters.BuildMode != EBuildMode.SimulateBuild) if (buildParameters.BuildMode != EBuildMode.SimulateBuild)
{ {
@ -48,7 +64,7 @@ namespace YooAsset.Editor
} }
// 检测共享资源打包规则 // 检测共享资源打包规则
if (buildParameters.ShareAssetPackRule == null) if (buildParameters.SharedPackRule == null)
throw new Exception("共享资源打包规则不能为空!"); throw new Exception("共享资源打包规则不能为空!");
#if UNITY_WEBGL #if UNITY_WEBGL
@ -72,11 +88,10 @@ namespace YooAsset.Editor
if (buildParameters.BuildMode == EBuildMode.ForceRebuild) if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
{ {
// 删除总目录 string packageRootDirectory = buildParametersContext.GetPackageRootDirectory();
string platformDirectory = $"{buildParameters.OutputRoot}/{buildParameters.BuildTarget}/{buildParameters.PackageName}"; if (EditorTools.DeleteDirectory(packageRootDirectory))
if (EditorTools.DeleteDirectory(platformDirectory))
{ {
BuildLogger.Log($"删除平台总目录:{platformDirectory}"); BuildLogger.Log($"删除包裹目录:{packageRootDirectory}");
} }
} }

View File

@ -15,6 +15,8 @@ namespace YooAsset.Editor
public const string XmlVersion = "Version"; public const string XmlVersion = "Version";
public const string XmlCommon = "Common"; public const string XmlCommon = "Common";
public const string XmlEnableAddressable = "AutoAddressable"; public const string XmlEnableAddressable = "AutoAddressable";
public const string XmlLocationToLower = "LocationToLower";
public const string XmlIncludeAssetGUID = "IncludeAssetGUID";
public const string XmlUniqueBundleName = "UniqueBundleName"; public const string XmlUniqueBundleName = "UniqueBundleName";
public const string XmlShowPackageView = "ShowPackageView"; public const string XmlShowPackageView = "ShowPackageView";
public const string XmlShowEditorAlias = "ShowEditorAlias"; public const string XmlShowEditorAlias = "ShowEditorAlias";
@ -66,6 +68,8 @@ namespace YooAsset.Editor
// 读取公共配置 // 读取公共配置
bool enableAddressable = false; bool enableAddressable = false;
bool locationToLower = false;
bool includeAssetGUID = false;
bool uniqueBundleName = false; bool uniqueBundleName = false;
bool showPackageView = false; bool showPackageView = false;
bool showEditorAlias = false; bool showEditorAlias = false;
@ -73,19 +77,18 @@ namespace YooAsset.Editor
if (commonNodeList.Count > 0) if (commonNodeList.Count > 0)
{ {
XmlElement commonElement = commonNodeList[0] as XmlElement; XmlElement commonElement = commonNodeList[0] as XmlElement;
if (commonElement.HasAttribute(XmlEnableAddressable) == false) if (commonElement.HasAttribute(XmlEnableAddressable))
throw new Exception($"Not found attribute {XmlEnableAddressable} in {XmlCommon}"); enableAddressable = commonElement.GetAttribute(XmlEnableAddressable) == "True" ? true : false;
if (commonElement.HasAttribute(XmlUniqueBundleName) == false) if (commonElement.HasAttribute(XmlLocationToLower))
throw new Exception($"Not found attribute {XmlUniqueBundleName} in {XmlCommon}"); locationToLower = commonElement.GetAttribute(XmlLocationToLower) == "True" ? true : false;
if (commonElement.HasAttribute(XmlShowPackageView) == false) if (commonElement.HasAttribute(XmlIncludeAssetGUID))
throw new Exception($"Not found attribute {XmlShowPackageView} in {XmlCommon}"); includeAssetGUID = commonElement.GetAttribute(XmlIncludeAssetGUID) == "True" ? true : false;
if (commonElement.HasAttribute(XmlShowEditorAlias) == false) if (commonElement.HasAttribute(XmlUniqueBundleName))
throw new Exception($"Not found attribute {XmlShowEditorAlias} in {XmlCommon}"); uniqueBundleName = commonElement.GetAttribute(XmlUniqueBundleName) == "True" ? true : false;
if (commonElement.HasAttribute(XmlShowPackageView))
enableAddressable = commonElement.GetAttribute(XmlEnableAddressable) == "True" ? true : false; showPackageView = commonElement.GetAttribute(XmlShowPackageView) == "True" ? true : false;
uniqueBundleName = commonElement.GetAttribute(XmlUniqueBundleName) == "True" ? true : false; if (commonElement.HasAttribute(XmlShowEditorAlias))
showPackageView = commonElement.GetAttribute(XmlShowPackageView) == "True" ? true : false; showEditorAlias = commonElement.GetAttribute(XmlShowEditorAlias) == "True" ? true : false;
showEditorAlias = commonElement.GetAttribute(XmlShowEditorAlias) == "True" ? true : false;
} }
// 读取包裹配置 // 读取包裹配置
@ -162,7 +165,7 @@ namespace YooAsset.Editor
} }
// 检测配置错误 // 检测配置错误
foreach(var package in packages) foreach (var package in packages)
{ {
package.CheckConfigError(); package.CheckConfigError();
} }
@ -170,6 +173,8 @@ namespace YooAsset.Editor
// 保存配置数据 // 保存配置数据
AssetBundleCollectorSettingData.ClearAll(); AssetBundleCollectorSettingData.ClearAll();
AssetBundleCollectorSettingData.Setting.EnableAddressable = enableAddressable; AssetBundleCollectorSettingData.Setting.EnableAddressable = enableAddressable;
AssetBundleCollectorSettingData.Setting.LocationToLower = locationToLower;
AssetBundleCollectorSettingData.Setting.IncludeAssetGUID = includeAssetGUID;
AssetBundleCollectorSettingData.Setting.UniqueBundleName = uniqueBundleName; AssetBundleCollectorSettingData.Setting.UniqueBundleName = uniqueBundleName;
AssetBundleCollectorSettingData.Setting.ShowPackageView = showPackageView; AssetBundleCollectorSettingData.Setting.ShowPackageView = showPackageView;
AssetBundleCollectorSettingData.Setting.ShowEditorAlias = showEditorAlias; AssetBundleCollectorSettingData.Setting.ShowEditorAlias = showEditorAlias;
@ -201,6 +206,8 @@ namespace YooAsset.Editor
// 设置公共配置 // 设置公共配置
var commonElement = xmlDoc.CreateElement(XmlCommon); var commonElement = xmlDoc.CreateElement(XmlCommon);
commonElement.SetAttribute(XmlEnableAddressable, AssetBundleCollectorSettingData.Setting.EnableAddressable.ToString()); commonElement.SetAttribute(XmlEnableAddressable, AssetBundleCollectorSettingData.Setting.EnableAddressable.ToString());
commonElement.SetAttribute(XmlLocationToLower, AssetBundleCollectorSettingData.Setting.LocationToLower.ToString());
commonElement.SetAttribute(XmlIncludeAssetGUID, AssetBundleCollectorSettingData.Setting.IncludeAssetGUID.ToString());
commonElement.SetAttribute(XmlUniqueBundleName, AssetBundleCollectorSettingData.Setting.UniqueBundleName.ToString()); commonElement.SetAttribute(XmlUniqueBundleName, AssetBundleCollectorSettingData.Setting.UniqueBundleName.ToString());
commonElement.SetAttribute(XmlShowPackageView, AssetBundleCollectorSettingData.Setting.ShowPackageView.ToString()); commonElement.SetAttribute(XmlShowPackageView, AssetBundleCollectorSettingData.Setting.ShowPackageView.ToString());
commonElement.SetAttribute(XmlShowEditorAlias, AssetBundleCollectorSettingData.Setting.ShowEditorAlias.ToString()); commonElement.SetAttribute(XmlShowEditorAlias, AssetBundleCollectorSettingData.Setting.ShowEditorAlias.ToString());
@ -359,14 +366,14 @@ namespace YooAsset.Editor
} }
// 2.3 -> 2.4 // 2.3 -> 2.4
if(configVersion == "2.3") if (configVersion == "2.3")
{ {
// 获取所有分组元素 // 获取所有分组元素
var groupNodeList = root.GetElementsByTagName(XmlGroup); var groupNodeList = root.GetElementsByTagName(XmlGroup);
foreach (var groupNode in groupNodeList) foreach (var groupNode in groupNodeList)
{ {
XmlElement groupElement = groupNode as XmlElement; XmlElement groupElement = groupNode as XmlElement;
if(groupElement.HasAttribute(XmlGroupActiveRule) == false) if (groupElement.HasAttribute(XmlGroupActiveRule) == false)
groupElement.SetAttribute(XmlGroupActiveRule, $"{nameof(EnableGroup)}"); groupElement.SetAttribute(XmlGroupActiveRule, $"{nameof(EnableGroup)}");
} }

View File

@ -10,15 +10,25 @@ namespace YooAsset.Editor
public class AssetBundleCollectorSetting : ScriptableObject public class AssetBundleCollectorSetting : ScriptableObject
{ {
/// <summary> /// <summary>
/// 是否显示包裹列表视图 /// 显示包裹列表视图
/// </summary> /// </summary>
public bool ShowPackageView = false; public bool ShowPackageView = false;
/// <summary> /// <summary>
/// 是否启用可寻址资源定位 /// 启用可寻址资源定位
/// </summary> /// </summary>
public bool EnableAddressable = false; public bool EnableAddressable = false;
/// <summary>
/// 资源定位地址大小写不敏感
/// </summary>
public bool LocationToLower = false;
/// <summary>
/// 包含资源GUID数据
/// </summary>
public bool IncludeAssetGUID = false;
/// <summary> /// <summary>
/// 资源包名唯一化 /// 资源包名唯一化
/// </summary> /// </summary>
@ -41,7 +51,12 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public void ClearAll() public void ClearAll()
{ {
ShowPackageView = false;
EnableAddressable = false; EnableAddressable = false;
LocationToLower = false;
IncludeAssetGUID = false;
UniqueBundleName = false;
ShowEditorAlias = false;
Packages.Clear(); Packages.Clear();
} }
@ -101,7 +116,8 @@ namespace YooAsset.Editor
{ {
if (package.PackageName == packageName) if (package.PackageName == packageName)
{ {
CollectCommand command = new CollectCommand(buildMode, packageName, EnableAddressable, UniqueBundleName); CollectCommand command = new CollectCommand(buildMode, packageName,
EnableAddressable, LocationToLower, IncludeAssetGUID, UniqueBundleName);
CollectResult collectResult = new CollectResult(command); CollectResult collectResult = new CollectResult(command);
collectResult.SetCollectAssets(package.GetAllCollectAssets(command)); collectResult.SetCollectAssets(package.GetAllCollectAssets(command));
return collectResult; return collectResult;

View File

@ -331,6 +331,16 @@ namespace YooAsset.Editor
Setting.EnableAddressable = enableAddressable; Setting.EnableAddressable = enableAddressable;
IsDirty = true; IsDirty = true;
} }
public static void ModifyLocationToLower(bool locationToLower)
{
Setting.LocationToLower = locationToLower;
IsDirty = true;
}
public static void ModifyIncludeAssetGUID(bool includeAssetGUID)
{
Setting.IncludeAssetGUID = includeAssetGUID;
IsDirty = true;
}
public static void ModifyUniqueBundleName(bool uniqueBundleName) public static void ModifyUniqueBundleName(bool uniqueBundleName)
{ {
Setting.UniqueBundleName = uniqueBundleName; Setting.UniqueBundleName = uniqueBundleName;

View File

@ -25,8 +25,13 @@ namespace YooAsset.Editor
private List<RuleDisplayName> _packRuleList; private List<RuleDisplayName> _packRuleList;
private List<RuleDisplayName> _filterRuleList; private List<RuleDisplayName> _filterRuleList;
private Button _settingsButton;
private VisualElement _setting1Container;
private VisualElement _setting2Container;
private Toggle _showPackageToogle; private Toggle _showPackageToogle;
private Toggle _enableAddressableToogle; private Toggle _enableAddressableToogle;
private Toggle _locationToLowerToogle;
private Toggle _includeAssetGUIDToogle;
private Toggle _uniqueBundleNameToogle; private Toggle _uniqueBundleNameToogle;
private Toggle _showEditorAliasToggle; private Toggle _showEditorAliasToggle;
@ -47,6 +52,7 @@ namespace YooAsset.Editor
private int _lastModifyPackageIndex = 0; private int _lastModifyPackageIndex = 0;
private int _lastModifyGroupIndex = 0; private int _lastModifyGroupIndex = 0;
private bool _showSettings = false;
public void CreateGUI() public void CreateGUI()
@ -77,6 +83,10 @@ namespace YooAsset.Editor
visualAsset.CloneTree(root); visualAsset.CloneTree(root);
// 公共设置相关 // 公共设置相关
_settingsButton = root.Q<Button>("SettingsButton");
_settingsButton.clicked += SettingsBtn_clicked;
_setting1Container = root.Q("PublicContainer1");
_setting2Container = root.Q("PublicContainer2");
_showPackageToogle = root.Q<Toggle>("ShowPackages"); _showPackageToogle = root.Q<Toggle>("ShowPackages");
_showPackageToogle.RegisterValueChangedCallback(evt => _showPackageToogle.RegisterValueChangedCallback(evt =>
{ {
@ -89,13 +99,24 @@ namespace YooAsset.Editor
AssetBundleCollectorSettingData.ModifyAddressable(evt.newValue); AssetBundleCollectorSettingData.ModifyAddressable(evt.newValue);
RefreshWindow(); RefreshWindow();
}); });
_locationToLowerToogle = root.Q<Toggle>("LocationToLower");
_locationToLowerToogle.RegisterValueChangedCallback(evt =>
{
AssetBundleCollectorSettingData.ModifyLocationToLower(evt.newValue);
RefreshWindow();
});
_includeAssetGUIDToogle = root.Q<Toggle>("IncludeAssetGUID");
_includeAssetGUIDToogle.RegisterValueChangedCallback(evt =>
{
AssetBundleCollectorSettingData.ModifyIncludeAssetGUID(evt.newValue);
RefreshWindow();
});
_uniqueBundleNameToogle = root.Q<Toggle>("UniqueBundleName"); _uniqueBundleNameToogle = root.Q<Toggle>("UniqueBundleName");
_uniqueBundleNameToogle.RegisterValueChangedCallback(evt => _uniqueBundleNameToogle.RegisterValueChangedCallback(evt =>
{ {
AssetBundleCollectorSettingData.ModifyUniqueBundleName(evt.newValue); AssetBundleCollectorSettingData.ModifyUniqueBundleName(evt.newValue);
RefreshWindow(); RefreshWindow();
}); });
_showEditorAliasToggle = root.Q<Toggle>("ShowEditorAlias"); _showEditorAliasToggle = root.Q<Toggle>("ShowEditorAlias");
_showEditorAliasToggle.RegisterValueChangedCallback(evt => _showEditorAliasToggle.RegisterValueChangedCallback(evt =>
{ {
@ -302,9 +323,22 @@ namespace YooAsset.Editor
{ {
_showPackageToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowPackageView); _showPackageToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowPackageView);
_enableAddressableToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.EnableAddressable); _enableAddressableToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.EnableAddressable);
_locationToLowerToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.LocationToLower);
_includeAssetGUIDToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.IncludeAssetGUID);
_uniqueBundleNameToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.UniqueBundleName); _uniqueBundleNameToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.UniqueBundleName);
_showEditorAliasToggle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowEditorAlias); _showEditorAliasToggle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowEditorAlias);
if (_showSettings)
{
_setting1Container.style.display = DisplayStyle.Flex;
_setting2Container.style.display = DisplayStyle.Flex;
}
else
{
_setting1Container.style.display = DisplayStyle.None;
_setting2Container.style.display = DisplayStyle.None;
}
_groupContainer.visible = false; _groupContainer.visible = false;
_collectorContainer.visible = false; _collectorContainer.visible = false;
@ -336,6 +370,11 @@ namespace YooAsset.Editor
{ {
AssetBundleCollectorSettingData.SaveFile(); AssetBundleCollectorSettingData.SaveFile();
} }
private void SettingsBtn_clicked()
{
_showSettings = !_showSettings;
RefreshWindow();
}
private string FormatListItemCallback(RuleDisplayName ruleDisplayName) private string FormatListItemCallback(RuleDisplayName ruleDisplayName)
{ {
if (_showEditorAliasToggle.value) if (_showEditorAliasToggle.value)
@ -796,7 +835,8 @@ namespace YooAsset.Editor
try try
{ {
CollectCommand command = new CollectCommand(EBuildMode.SimulateBuild, _packageNameTxt.value, _enableAddressableToogle.value, _uniqueBundleNameToogle.value); CollectCommand command = new CollectCommand(EBuildMode.SimulateBuild, _packageNameTxt.value,
_enableAddressableToogle.value, _locationToLowerToogle.value, _includeAssetGUIDToogle.value, _uniqueBundleNameToogle.value);
collectAssetInfos = collector.GetAllCollectAssets(command, group); collectAssetInfos = collector.GetAllCollectAssets(command, group);
} }
catch (System.Exception e) catch (System.Exception e)

View File

@ -1,15 +1,22 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements"> <ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<uie:Toolbar name="Toolbar" style="display: flex; flex-direction: row-reverse;"> <uie:Toolbar name="Toolbar" style="display: flex; flex-direction: row-reverse;">
<ui:Button text="Save" display-tooltip-when-elided="true" name="SaveButton" style="width: 50px; background-color: rgb(56, 147, 58);" /> <ui:Button text="Save" display-tooltip-when-elided="true" name="SaveButton" style="width: 50px; background-color: rgb(56, 147, 58);" />
<ui:Button text="导出" display-tooltip-when-elided="true" name="ExportButton" style="width: 50px; background-color: rgb(56, 147, 58);" /> <ui:Button text="导出" display-tooltip-when-elided="true" name="ExportButton" style="width: 50px; background-color: rgb(56, 147, 58);" />
<ui:Button text="导入" display-tooltip-when-elided="true" name="ImportButton" style="width: 50px; background-color: rgb(56, 147, 58);" /> <ui:Button text="导入" display-tooltip-when-elided="true" name="ImportButton" style="width: 50px; background-color: rgb(56, 147, 58);" />
<ui:Button text="修复" display-tooltip-when-elided="true" name="FixButton" style="width: 50px; background-color: rgb(56, 147, 58);" /> <ui:Button text="修复" display-tooltip-when-elided="true" name="FixButton" style="width: 50px; background-color: rgb(56, 147, 58);" />
</uie:Toolbar> </uie:Toolbar>
<ui:VisualElement name="PublicContainer" style="height: 30px; background-color: rgb(67, 67, 67); flex-direction: row; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;"> <ui:VisualElement name="PublicContainer" style="background-color: rgb(79, 79, 79); flex-direction: column; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
<ui:Toggle label="Show Packages" name="ShowPackages" style="width: 196px; -unity-text-align: middle-left;" /> <ui:Button text="Settings" display-tooltip-when-elided="true" name="SettingsButton" />
<ui:Toggle label="Show Editor Alias" name="ShowEditorAlias" style="width: 196px; -unity-text-align: middle-left;" /> <ui:VisualElement name="PublicContainer1" style="flex-direction: row; flex-wrap: nowrap; height: 28px;">
<ui:Toggle label="Enable Addressable" name="EnableAddressable" style="width: 196px; -unity-text-align: middle-left;" /> <ui:Toggle label="Show Packages" name="ShowPackages" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Unique Bundle Name" name="UniqueBundleName" style="width: 196px; -unity-text-align: middle-left;" /> <ui:Toggle label="Show Editor Alias" name="ShowEditorAlias" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Enable Addressable" name="EnableAddressable" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Unique Bundle Name" name="UniqueBundleName" style="width: 196px; -unity-text-align: middle-left;" />
</ui:VisualElement>
<ui:VisualElement name="PublicContainer2" style="flex-direction: row; flex-wrap: nowrap; height: 28px;">
<ui:Toggle label="Location To Lower" name="LocationToLower" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Include Asset GUID" name="IncludeAssetGUID" style="width: 196px; -unity-text-align: middle-left;" />
</ui:VisualElement>
</ui:VisualElement> </ui:VisualElement>
<ui:VisualElement name="ContentContainer" style="flex-grow: 1; flex-direction: row;"> <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: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;">

View File

@ -14,10 +14,20 @@ namespace YooAsset.Editor
public string PackageName { private set; get; } public string PackageName { private set; get; }
/// <summary> /// <summary>
/// 是否启用可寻址资源定位 /// 启用可寻址资源定位
/// </summary> /// </summary>
public bool EnableAddressable { private set; get; } public bool EnableAddressable { private set; get; }
/// <summary>
/// 资源定位地址大小写不敏感
/// </summary>
public bool LocationToLower { private set; get; }
/// <summary>
/// 包含资源GUID数据
/// </summary>
public bool IncludeAssetGUID { private set; get; }
/// <summary> /// <summary>
/// 资源包名唯一化 /// 资源包名唯一化
/// </summary> /// </summary>
@ -29,11 +39,13 @@ namespace YooAsset.Editor
public string ShadersBundleName { private set; get; } public string ShadersBundleName { private set; get; }
public CollectCommand(EBuildMode buildMode, string packageName, bool enableAddressable, bool uniqueBundleName) public CollectCommand(EBuildMode buildMode, string packageName, bool enableAddressable, bool locationToLower, bool includeAssetGUID, bool uniqueBundleName)
{ {
BuildMode = buildMode; BuildMode = buildMode;
PackageName = packageName; PackageName = packageName;
EnableAddressable = enableAddressable; EnableAddressable = enableAddressable;
LocationToLower = locationToLower;
IncludeAssetGUID = includeAssetGUID;
UniqueBundleName = uniqueBundleName; UniqueBundleName = uniqueBundleName;
// 着色器统一全名称 // 着色器统一全名称

View File

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

View File

@ -48,12 +48,16 @@ namespace YooAsset.Editor
fullName = $"{bundleName}.{_bundleExtension}"; fullName = $"{bundleName}.{_bundleExtension}";
return fullName.ToLower(); return fullName.ToLower();
} }
/// <summary> /// <summary>
/// 获取共享资源包全名称 /// 获取共享资源包全名称
/// </summary> /// </summary>
public string GetShareBundleName(string packageName, bool uniqueBundleName) public string GetShareBundleName(string packageName, bool uniqueBundleName)
{ {
// 注意:冗余的共享资源包名返回空
if (string.IsNullOrEmpty(_bundleName) && string.IsNullOrEmpty(_bundleExtension))
return string.Empty;
string fullName; string fullName;
string bundleName = EditorTools.GetRegularPath(_bundleName).Replace('/', '_').Replace('.', '_').ToLower(); string bundleName = EditorTools.GetRegularPath(_bundleName).Replace('/', '_').Replace('.', '_').ToLower();
if (uniqueBundleName) if (uniqueBundleName)

View File

@ -4,7 +4,7 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 共享资源的打包规则 /// 共享资源的打包规则
/// </summary> /// </summary>
public interface IShareAssetPackRule public interface ISharedPackRule
{ {
/// <summary> /// <summary>
/// 获取打包规则结果 /// 获取打包规则结果

View File

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

View File

@ -20,7 +20,7 @@ namespace YooAsset.Editor
} }
} }
[DisplayName("定位地址: 分组名+文件名")] [DisplayName("定位地址: 分组名_文件名")]
public class AddressByGroupAndFileName : IAddressRule public class AddressByGroupAndFileName : IAddressRule
{ {
string IAddressRule.GetAssetAddress(AddressRuleData data) string IAddressRule.GetAssetAddress(AddressRuleData data)
@ -30,7 +30,7 @@ namespace YooAsset.Editor
} }
} }
[DisplayName("定位地址: 文件夹名+文件名")] [DisplayName("定位地址: 文件夹名_文件名")]
public class AddressByFolderAndFileName : IAddressRule public class AddressByFolderAndFileName : IAddressRule
{ {
string IAddressRule.GetAssetAddress(AddressRuleData data) string IAddressRule.GetAssetAddress(AddressRuleData data)

View File

@ -0,0 +1,31 @@
using System;
using System.IO;
using UnityEditor;
namespace YooAsset.Editor
{
/// <summary>
/// 零冗余的共享资源打包规则
/// </summary>
public class ZeroRedundancySharedPackRule : ISharedPackRule
{
public PackRuleResult GetPackRuleResult(string assetPath)
{
string bundleName = Path.GetDirectoryName(assetPath);
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
}
/// <summary>
/// 全部冗余的共享资源打包规则
/// </summary>
public class FullRedundancySharedPackRule : ISharedPackRule
{
public PackRuleResult GetPackRuleResult(string assetPath)
{
PackRuleResult result = new PackRuleResult(string.Empty, string.Empty);
return result;
}
}
}

View File

@ -1,16 +0,0 @@
using System;
using System.IO;
using UnityEditor;
namespace YooAsset.Editor
{
public class DefaultShareAssetPackRule : IShareAssetPackRule
{
public PackRuleResult GetPackRuleResult(string assetPath)
{
string bundleName = Path.GetDirectoryName(assetPath);
PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
return result;
}
}
}

View File

@ -66,11 +66,13 @@ namespace YooAsset.Editor
_items.Add(new ItemWrapper("包裹名称", buildReport.Summary.BuildPackageName)); _items.Add(new ItemWrapper("包裹名称", buildReport.Summary.BuildPackageName));
_items.Add(new ItemWrapper("包裹版本", buildReport.Summary.BuildPackageVersion)); _items.Add(new ItemWrapper("包裹版本", buildReport.Summary.BuildPackageVersion));
_items.Add(new ItemWrapper(string.Empty, string.Empty));
_items.Add(new ItemWrapper("启用可寻址资源定位", $"{buildReport.Summary.EnableAddressable}")); _items.Add(new ItemWrapper("启用可寻址资源定位", $"{buildReport.Summary.EnableAddressable}"));
_items.Add(new ItemWrapper("资源定位地址大小写不敏感", $"{buildReport.Summary.LocationToLower}"));
_items.Add(new ItemWrapper("包含资源GUID数据", $"{buildReport.Summary.IncludeAssetGUID}"));
_items.Add(new ItemWrapper("资源包名唯一化", $"{buildReport.Summary.UniqueBundleName}")); _items.Add(new ItemWrapper("资源包名唯一化", $"{buildReport.Summary.UniqueBundleName}"));
_items.Add(new ItemWrapper("自动分析冗余资源", $"{buildReport.Summary.AutoAnalyzeRedundancy}")); _items.Add(new ItemWrapper("共享资源打包规则", buildReport.Summary.SharedPackRuleClassName));
_items.Add(new ItemWrapper("共享资源的打包类名称", buildReport.Summary.ShareAssetPackRuleClassName)); _items.Add(new ItemWrapper("资源加密服务类", buildReport.Summary.EncryptionServicesClassName));
_items.Add(new ItemWrapper("加密服务类名称", buildReport.Summary.EncryptionServicesClassName));
_items.Add(new ItemWrapper(string.Empty, string.Empty)); _items.Add(new ItemWrapper(string.Empty, string.Empty));
_items.Add(new ItemWrapper("构建参数", string.Empty)); _items.Add(new ItemWrapper("构建参数", string.Empty));

View File

@ -35,10 +35,20 @@ namespace YooAsset.Editor
TypeCache.TypeCollection collection = TypeCache.GetTypesDerivedFrom(parentType); TypeCache.TypeCollection collection = TypeCache.GetTypesDerivedFrom(parentType);
return collection.ToList(); return collection.ToList();
} }
/// <summary>
/// 获取带有指定属性的所有类的类型
/// </summary>
public static List<Type> GetTypesWithAttribute(System.Type attrType)
{
TypeCache.TypeCollection collection = TypeCache.GetTypesWithAttribute(attrType);
return collection.ToList();
}
#else #else
private static readonly List<Type> _cacheTypes = new List<Type>(10000); private static readonly List<Type> _cacheTypes = new List<Type>(10000);
private static void InitAssembly() private static void InitAssembly()
{ {
_cacheTypes.Clear();
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies) foreach (Assembly assembly in assemblies)
{ {
@ -65,6 +75,23 @@ namespace YooAsset.Editor
} }
return result; return result;
} }
/// <summary>
/// 获取带有指定属性的所有类的类型
/// </summary>
public static List<Type> GetTypesWithAttribute(System.Type attrType)
{
List<Type> result = new List<Type>();
for (int i = 0; i < _cacheTypes.Count; i++)
{
Type type = _cacheTypes[i];
if (type.GetCustomAttribute(attrType) != null)
{
result.Add(type);
}
}
return result;
}
#endif #endif
/// <summary> /// <summary>
@ -213,11 +240,11 @@ namespace YooAsset.Editor
public static void FocusUnitySceneWindow() public static void FocusUnitySceneWindow()
{ {
EditorWindow.FocusWindowIfItsOpen<SceneView>(); EditorWindow.FocusWindowIfItsOpen<SceneView>();
} }
public static void CloseUnityGameWindow() public static void CloseUnityGameWindow()
{ {
System.Type T = Assembly.Load("UnityEditor").GetType("UnityEditor.GameView"); System.Type T = Assembly.Load("UnityEditor").GetType("UnityEditor.GameView");
EditorWindow.GetWindow(T, false, "GameView", true).Close(); EditorWindow.GetWindow(T, false, "GameView", true).Close();
} }
public static void FocusUnityGameWindow() public static void FocusUnityGameWindow()
{ {
@ -399,7 +426,7 @@ namespace YooAsset.Editor
FileInfo fileInfo = new FileInfo(filePath); FileInfo fileInfo = new FileInfo(filePath);
fileInfo.MoveTo(destPath); fileInfo.MoveTo(destPath);
} }
/// <summary> /// <summary>
/// 拷贝文件夹 /// 拷贝文件夹
/// 注意:包括所有子目录的文件 /// 注意:包括所有子目录的文件

View File

@ -1,8 +0,0 @@
using UnityEngine;
namespace YooAsset
{
public class AssetReference
{
}
}

View File

@ -169,7 +169,7 @@ namespace YooAsset
/// <summary> /// <summary>
/// 加载场景 /// 加载场景
/// </summary> /// </summary>
public SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) public SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad, int priority)
{ {
if (assetInfo.IsInvalid) if (assetInfo.IsInvalid)
{ {
@ -190,9 +190,9 @@ namespace YooAsset
ProviderBase provider; ProviderBase provider;
{ {
if (_simulationOnEditor) if (_simulationOnEditor)
provider = new DatabaseSceneProvider(this, providerGUID, assetInfo, sceneMode, activateOnLoad, priority); provider = new DatabaseSceneProvider(this, providerGUID, assetInfo, sceneMode, suspendLoad, priority);
else else
provider = new BundledSceneProvider(this, providerGUID, assetInfo, sceneMode, activateOnLoad, priority); provider = new BundledSceneProvider(this, providerGUID, assetInfo, sceneMode, suspendLoad, priority);
provider.InitSpawnDebugInfo(); provider.InitSpawnDebugInfo();
_providerList.Add(provider); _providerList.Add(provider);
_providerDic.Add(providerGUID, provider); _providerDic.Add(providerGUID, provider);
@ -260,6 +260,34 @@ namespace YooAsset
return provider.CreateHandle<SubAssetsOperationHandle>(); return provider.CreateHandle<SubAssetsOperationHandle>();
} }
/// <summary>
/// 加载所有资源对象
/// </summary>
public AllAssetsOperationHandle LoadAllAssetsAsync(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
{
YooLogger.Error($"Failed to load all assets ! {assetInfo.Error}");
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
completedProvider.SetCompleted(assetInfo.Error);
return completedProvider.CreateHandle<AllAssetsOperationHandle>();
}
string providerGUID = assetInfo.GUID;
ProviderBase provider = TryGetProvider(providerGUID);
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseAllAssetsProvider(this, providerGUID, assetInfo);
else
provider = new BundledAllAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providerList.Add(provider);
_providerDic.Add(providerGUID, provider);
}
return provider.CreateHandle<AllAssetsOperationHandle>();
}
/// <summary> /// <summary>
/// 加载原生文件 /// 加载原生文件
/// </summary> /// </summary>
@ -377,10 +405,10 @@ namespace YooAsset
else else
{ {
#if UNITY_WEBGL #if UNITY_WEBGL
if (bundleInfo.Bundle.IsRawFile) if (bundleInfo.Bundle.IsRawFile)
loader = new RawBundleWebLoader(this, bundleInfo); loader = new RawBundleWebLoader(this, bundleInfo);
else else
loader = new AssetBundleWebLoader(this, bundleInfo); loader = new AssetBundleWebLoader(this, bundleInfo);
#else #else
if (bundleInfo.Bundle.IsRawFile) if (bundleInfo.Bundle.IsRawFile)
loader = new RawBundleFileLoader(this, bundleInfo); loader = new RawBundleFileLoader(this, bundleInfo);

View File

@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
namespace YooAsset
{
public sealed class AllAssetsOperationHandle : OperationHandleBase, IDisposable
{
private System.Action<AllAssetsOperationHandle> _callback;
internal AllAssetsOperationHandle(ProviderBase provider) : base(provider)
{
}
internal override void InvokeCallback()
{
_callback?.Invoke(this);
}
/// <summary>
/// 完成委托
/// </summary>
public event System.Action<AllAssetsOperationHandle> Completed
{
add
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(AllAssetsOperationHandle)} is invalid");
if (Provider.IsDone)
value.Invoke(this);
else
_callback += value;
}
remove
{
if (IsValidWithWarning == false)
throw new System.Exception($"{nameof(AllAssetsOperationHandle)} is invalid");
_callback -= value;
}
}
/// <summary>
/// 等待异步执行完毕
/// </summary>
public void WaitForAsyncComplete()
{
if (IsValidWithWarning == false)
return;
Provider.WaitForAsyncComplete();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Release()
{
this.ReleaseInternal();
}
/// <summary>
/// 释放资源句柄
/// </summary>
public void Dispose()
{
this.ReleaseInternal();
}
/// <summary>
/// 子资源对象集合
/// </summary>
public UnityEngine.Object[] AllAssetObjects
{
get
{
if (IsValidWithWarning == false)
return null;
return Provider.AllAssetObjects;
}
}
}
}

View File

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

View File

@ -3,7 +3,7 @@
namespace YooAsset namespace YooAsset
{ {
public class SceneOperationHandle : OperationHandleBase public class SceneOperationHandle : OperationHandleBase
{ {
private System.Action<SceneOperationHandle> _callback; private System.Action<SceneOperationHandle> _callback;
internal string PackageName { set; get; } internal string PackageName { set; get; }
@ -51,7 +51,7 @@ namespace YooAsset
} }
/// <summary> /// <summary>
/// 激活场景 /// 激活场景(当同时存在多个场景时用于切换激活场景)
/// </summary> /// </summary>
public bool ActivateScene() public bool ActivateScene()
{ {
@ -69,6 +69,38 @@ namespace YooAsset
} }
} }
/// <summary>
/// 解除场景加载挂起操作
/// </summary>
public bool UnSuspend()
{
if (IsValidWithWarning == false)
return false;
if (SceneObject.IsValid())
{
if (Provider is DatabaseSceneProvider)
{
var temp = Provider as DatabaseSceneProvider;
return temp.UnSuspendLoad();
}
else if (Provider is BundledSceneProvider)
{
var temp = Provider as BundledSceneProvider;
return temp.UnSuspendLoad();
}
else
{
throw new System.NotImplementedException();
}
}
else
{
YooLogger.Warning($"Scene is invalid : {SceneObject.name}");
return false;
}
}
/// <summary> /// <summary>
/// 是否为主场景 /// 是否为主场景
/// </summary> /// </summary>

View File

@ -111,7 +111,7 @@ namespace YooAsset
if (_steps == ESteps.Unpack) if (_steps == ESteps.Unpack)
{ {
int failedTryAgain = Impl.DownloadFailedTryAgain; int failedTryAgain = Impl.DownloadFailedTryAgain;
var bundleInfo = ManifestTools.GetUnpackInfo(MainBundleInfo.Bundle); var bundleInfo = ManifestTools.ConvertToUnpackInfo(MainBundleInfo.Bundle);
_unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain); _unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
_steps = ESteps.CheckUnpack; _steps = ESteps.CheckUnpack;
} }

View File

@ -168,8 +168,17 @@ namespace YooAsset
// 5. 从WEB网站获取AssetBundle文件 // 5. 从WEB网站获取AssetBundle文件
if (_steps == ESteps.LoadWebFile) if (_steps == ESteps.LoadWebFile)
{ {
var hash = Hash128.Parse(MainBundleInfo.Bundle.FileHash); if (CacheSystem.DisableUnityCacheOnWebGL)
_webRequest = UnityWebRequestAssetBundle.GetAssetBundle(FileLoadPath, hash); {
_webRequest = UnityWebRequestAssetBundle.GetAssetBundle(FileLoadPath);
}
else
{
var hash = Hash128.Parse(MainBundleInfo.Bundle.FileHash);
_webRequest = UnityWebRequestAssetBundle.GetAssetBundle(FileLoadPath, hash);
}
DownloadSystem.SetUnityWebRequest(_webRequest);
_webRequest.SendWebRequest(); _webRequest.SendWebRequest();
_steps = ESteps.CheckLoadWebFile; _steps = ESteps.CheckLoadWebFile;
} }

View File

@ -4,17 +4,17 @@ using System.Collections.Generic;
namespace YooAsset namespace YooAsset
{ {
internal class DependAssetBundleGroup internal class DependAssetBundles
{ {
/// <summary> /// <summary>
/// 依赖的资源包加载器列表 /// 依赖的资源包加载器列表
/// </summary> /// </summary>
internal readonly List<BundleLoaderBase> DependBundles; internal readonly List<BundleLoaderBase> DependList;
public DependAssetBundleGroup(List<BundleLoaderBase> dpendBundles) public DependAssetBundles(List<BundleLoaderBase> dpendList)
{ {
DependBundles = dpendBundles; DependList = dpendList;
} }
/// <summary> /// <summary>
@ -22,7 +22,7 @@ namespace YooAsset
/// </summary> /// </summary>
public bool IsDone() public bool IsDone()
{ {
foreach (var loader in DependBundles) foreach (var loader in DependList)
{ {
if (loader.IsDone() == false) if (loader.IsDone() == false)
return false; return false;
@ -35,7 +35,7 @@ namespace YooAsset
/// </summary> /// </summary>
public bool IsSucceed() public bool IsSucceed()
{ {
foreach (var loader in DependBundles) foreach (var loader in DependList)
{ {
if (loader.Status != BundleLoaderBase.EStatus.Succeed) if (loader.Status != BundleLoaderBase.EStatus.Succeed)
{ {
@ -50,7 +50,7 @@ namespace YooAsset
/// </summary> /// </summary>
public string GetLastError() public string GetLastError()
{ {
foreach (var loader in DependBundles) foreach (var loader in DependList)
{ {
if (loader.Status != BundleLoaderBase.EStatus.Succeed) if (loader.Status != BundleLoaderBase.EStatus.Succeed)
{ {
@ -65,7 +65,7 @@ namespace YooAsset
/// </summary> /// </summary>
public void WaitForAsyncComplete() public void WaitForAsyncComplete()
{ {
foreach (var loader in DependBundles) foreach (var loader in DependList)
{ {
if (loader.IsDone() == false) if (loader.IsDone() == false)
loader.WaitForAsyncComplete(); loader.WaitForAsyncComplete();
@ -77,7 +77,7 @@ namespace YooAsset
/// </summary> /// </summary>
public void Reference() public void Reference()
{ {
foreach (var loader in DependBundles) foreach (var loader in DependList)
{ {
loader.Reference(); loader.Reference();
} }
@ -88,7 +88,7 @@ namespace YooAsset
/// </summary> /// </summary>
public void Release() public void Release()
{ {
foreach (var loader in DependBundles) foreach (var loader in DependList)
{ {
loader.Release(); loader.Release();
} }
@ -99,7 +99,7 @@ namespace YooAsset
/// </summary> /// </summary>
internal void GetBundleDebugInfos(List<DebugBundleInfo> output) internal void GetBundleDebugInfos(List<DebugBundleInfo> output)
{ {
foreach (var loader in DependBundles) foreach (var loader in DependList)
{ {
var bundleInfo = new DebugBundleInfo(); var bundleInfo = new DebugBundleInfo();
bundleInfo.BundleName = loader.MainBundleInfo.Bundle.BundleName; bundleInfo.BundleName = loader.MainBundleInfo.Bundle.BundleName;

View File

@ -92,7 +92,7 @@ namespace YooAsset
if (_steps == ESteps.Unpack) if (_steps == ESteps.Unpack)
{ {
int failedTryAgain = Impl.DownloadFailedTryAgain; int failedTryAgain = Impl.DownloadFailedTryAgain;
var bundleInfo = ManifestTools.GetUnpackInfo(MainBundleInfo.Bundle); var bundleInfo = ManifestTools.ConvertToUnpackInfo(MainBundleInfo.Bundle);
_unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain); _unpacker = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
_steps = ESteps.CheckUnpack; _steps = ESteps.CheckUnpack;
} }

View File

@ -90,7 +90,7 @@ namespace YooAsset
if (_steps == ESteps.Website) if (_steps == ESteps.Website)
{ {
int failedTryAgain = Impl.DownloadFailedTryAgain; int failedTryAgain = Impl.DownloadFailedTryAgain;
var bundleInfo = ManifestTools.GetUnpackInfo(MainBundleInfo.Bundle); var bundleInfo = ManifestTools.ConvertToUnpackInfo(MainBundleInfo.Bundle);
_website = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain); _website = DownloadSystem.BeginDownload(bundleInfo, failedTryAgain);
_steps = ESteps.CheckWebsite; _steps = ESteps.CheckWebsite;
} }

View File

@ -0,0 +1,112 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal sealed class BundledAllAssetsProvider : ProviderBase
{
private AssetBundleRequest _cacheRequest;
public BundledAllAssetsProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
{
}
public override void Update()
{
DebugBeginRecording();
if (IsDone)
return;
if (Status == EStatus.None)
{
Status = EStatus.CheckBundle;
}
// 1. 检测资源包
if (Status == EStatus.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
DependBundles.WaitForAsyncComplete();
OwnerBundle.WaitForAsyncComplete();
}
if (DependBundles.IsDone() == false)
return;
if (OwnerBundle.IsDone() == false)
return;
if (DependBundles.IsSucceed() == false)
{
Status = EStatus.Failed;
LastError = DependBundles.GetLastError();
InvokeCompletion();
return;
}
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
Status = EStatus.Failed;
LastError = OwnerBundle.LastError;
InvokeCompletion();
return;
}
Status = EStatus.Loading;
}
// 2. 加载资源对象
if (Status == EStatus.Loading)
{
if (IsWaitForAsyncComplete)
{
if (MainAssetInfo.AssetType == null)
AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets();
else
AllAssetObjects = OwnerBundle.CacheBundle.LoadAllAssets(MainAssetInfo.AssetType);
}
else
{
if (MainAssetInfo.AssetType == null)
_cacheRequest = OwnerBundle.CacheBundle.LoadAllAssetsAsync();
else
_cacheRequest = OwnerBundle.CacheBundle.LoadAllAssetsAsync(MainAssetInfo.AssetType);
}
Status = EStatus.Checking;
}
// 3. 检测加载结果
if (Status == EStatus.Checking)
{
if (_cacheRequest != null)
{
if (IsWaitForAsyncComplete)
{
// 强制挂起主线程(注意:该操作会很耗时)
YooLogger.Warning("Suspend the main thread to load unity asset.");
AllAssetObjects = _cacheRequest.allAssets;
}
else
{
Progress = _cacheRequest.progress;
if (_cacheRequest.isDone == false)
return;
AllAssetObjects = _cacheRequest.allAssets;
}
}
Status = AllAssetObjects == null ? EStatus.Failed : EStatus.Succeed;
if (Status == EStatus.Failed)
{
if (MainAssetInfo.AssetType == null)
LastError = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
else
LastError = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.Bundle.BundleName}";
YooLogger.Error(LastError);
}
InvokeCompletion();
}
}
}
}

View File

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

View File

@ -28,19 +28,19 @@ namespace YooAsset
{ {
if (IsWaitForAsyncComplete) if (IsWaitForAsyncComplete)
{ {
DependBundleGroup.WaitForAsyncComplete(); DependBundles.WaitForAsyncComplete();
OwnerBundle.WaitForAsyncComplete(); OwnerBundle.WaitForAsyncComplete();
} }
if (DependBundleGroup.IsDone() == false) if (DependBundles.IsDone() == false)
return; return;
if (OwnerBundle.IsDone() == false) if (OwnerBundle.IsDone() == false)
return; return;
if (DependBundleGroup.IsSucceed() == false) if (DependBundles.IsSucceed() == false)
{ {
Status = EStatus.Failed; Status = EStatus.Failed;
LastError = DependBundleGroup.GetLastError(); LastError = DependBundles.GetLastError();
InvokeCompletion(); InvokeCompletion();
return; return;
} }

View File

@ -10,15 +10,15 @@ namespace YooAsset
{ {
public readonly LoadSceneMode SceneMode; public readonly LoadSceneMode SceneMode;
private readonly string _sceneName; private readonly string _sceneName;
private readonly bool _activateOnLoad; private readonly bool _suspendLoad;
private readonly int _priority; private readonly int _priority;
private AsyncOperation _asyncOp; private AsyncOperation _asyncOperation;
public BundledSceneProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) : base(impl, providerGUID, assetInfo) public BundledSceneProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad, int priority) : base(impl, providerGUID, assetInfo)
{ {
SceneMode = sceneMode; SceneMode = sceneMode;
_sceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath); _sceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath);
_activateOnLoad = activateOnLoad; _suspendLoad = suspendLoad;
_priority = priority; _priority = priority;
} }
public override void Update() public override void Update()
@ -36,15 +36,15 @@ namespace YooAsset
// 1. 检测资源包 // 1. 检测资源包
if (Status == EStatus.CheckBundle) if (Status == EStatus.CheckBundle)
{ {
if (DependBundleGroup.IsDone() == false) if (DependBundles.IsDone() == false)
return; return;
if (OwnerBundle.IsDone() == false) if (OwnerBundle.IsDone() == false)
return; return;
if (DependBundleGroup.IsSucceed() == false) if (DependBundles.IsSucceed() == false)
{ {
Status = EStatus.Failed; Status = EStatus.Failed;
LastError = DependBundleGroup.GetLastError(); LastError = DependBundles.GetLastError();
InvokeCompletion(); InvokeCompletion();
return; return;
} }
@ -64,11 +64,11 @@ namespace YooAsset
if (Status == EStatus.Loading) if (Status == EStatus.Loading)
{ {
// 注意如果场景不存在则返回NULL // 注意如果场景不存在则返回NULL
_asyncOp = SceneManager.LoadSceneAsync(MainAssetInfo.AssetPath, SceneMode); _asyncOperation = SceneManager.LoadSceneAsync(MainAssetInfo.AssetPath, SceneMode);
if (_asyncOp != null) if (_asyncOperation != null)
{ {
_asyncOp.allowSceneActivation = true; _asyncOperation.allowSceneActivation = !_suspendLoad;
_asyncOp.priority = _priority; _asyncOperation.priority = _priority;
SceneObject = SceneManager.GetSceneAt(SceneManager.sceneCount - 1); SceneObject = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
Status = EStatus.Checking; Status = EStatus.Checking;
} }
@ -84,12 +84,9 @@ namespace YooAsset
// 3. 检测加载结果 // 3. 检测加载结果
if (Status == EStatus.Checking) if (Status == EStatus.Checking)
{ {
Progress = _asyncOp.progress; Progress = _asyncOperation.progress;
if (_asyncOp.isDone) if (_asyncOperation.isDone)
{ {
if (SceneObject.IsValid() && _activateOnLoad)
SceneManager.SetActiveScene(SceneObject);
Status = SceneObject.IsValid() ? EStatus.Succeed : EStatus.Failed; Status = SceneObject.IsValid() ? EStatus.Succeed : EStatus.Failed;
if (Status == EStatus.Failed) if (Status == EStatus.Failed)
{ {
@ -100,5 +97,17 @@ namespace YooAsset
} }
} }
} }
/// <summary>
/// 解除场景加载挂起操作
/// </summary>
public bool UnSuspendLoad()
{
if (_asyncOperation == null)
return false;
_asyncOperation.allowSceneActivation = true;
return true;
}
} }
} }

View File

@ -28,19 +28,19 @@ namespace YooAsset
{ {
if (IsWaitForAsyncComplete) if (IsWaitForAsyncComplete)
{ {
DependBundleGroup.WaitForAsyncComplete(); DependBundles.WaitForAsyncComplete();
OwnerBundle.WaitForAsyncComplete(); OwnerBundle.WaitForAsyncComplete();
} }
if (DependBundleGroup.IsDone() == false) if (DependBundles.IsDone() == false)
return; return;
if (OwnerBundle.IsDone() == false) if (OwnerBundle.IsDone() == false)
return; return;
if (DependBundleGroup.IsSucceed() == false) if (DependBundles.IsSucceed() == false)
{ {
Status = EStatus.Failed; Status = EStatus.Failed;
LastError = DependBundleGroup.GetLastError(); LastError = DependBundles.GetLastError();
InvokeCompletion(); InvokeCompletion();
return; return;
} }

View File

@ -0,0 +1,105 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YooAsset
{
internal sealed class DatabaseAllAssetsProvider : ProviderBase
{
public DatabaseAllAssetsProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
{
}
public override void Update()
{
#if UNITY_EDITOR
if (IsDone)
return;
if (Status == EStatus.None)
{
// 检测资源文件是否存在
string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
if (string.IsNullOrEmpty(guid))
{
Status = EStatus.Failed;
LastError = $"Not found asset : {MainAssetInfo.AssetPath}";
YooLogger.Error(LastError);
InvokeCompletion();
return;
}
Status = EStatus.CheckBundle;
// 注意:模拟异步加载效果提前返回
if (IsWaitForAsyncComplete == false)
return;
}
// 1. 检测资源包
if (Status == EStatus.CheckBundle)
{
if (IsWaitForAsyncComplete)
{
OwnerBundle.WaitForAsyncComplete();
}
if (OwnerBundle.IsDone() == false)
return;
if (OwnerBundle.Status != BundleLoaderBase.EStatus.Succeed)
{
Status = EStatus.Failed;
LastError = OwnerBundle.LastError;
InvokeCompletion();
return;
}
Status = EStatus.Loading;
}
// 2. 加载资源对象
if (Status == EStatus.Loading)
{
if (MainAssetInfo.AssetType == null)
{
List<UnityEngine.Object> result = new List<Object>();
foreach (var assetPath in OwnerBundle.MainBundleInfo.IncludeAssets)
{
UnityEngine.Object mainAsset = UnityEditor.AssetDatabase.LoadMainAssetAtPath(assetPath);
if (mainAsset != null)
result.Add(mainAsset);
}
AllAssetObjects = result.ToArray();
}
else
{
List<UnityEngine.Object> result = new List<Object>();
foreach (var assetPath in OwnerBundle.MainBundleInfo.IncludeAssets)
{
UnityEngine.Object mainAsset = UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath, MainAssetInfo.AssetType);
if (mainAsset != null)
result.Add(mainAsset);
}
AllAssetObjects = result.ToArray();
}
Status = EStatus.Checking;
}
// 3. 检测加载结果
if (Status == EStatus.Checking)
{
Status = AllAssetObjects == null ? EStatus.Failed : EStatus.Succeed;
if (Status == EStatus.Failed)
{
if (MainAssetInfo.AssetType == null)
LastError = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : null";
else
LastError = $"Failed to load all assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
YooLogger.Error(LastError);
}
InvokeCompletion();
}
#endif
}
}
}

View File

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

View File

@ -6,14 +6,14 @@ namespace YooAsset
internal sealed class DatabaseSceneProvider : ProviderBase internal sealed class DatabaseSceneProvider : ProviderBase
{ {
public readonly LoadSceneMode SceneMode; public readonly LoadSceneMode SceneMode;
private readonly bool _activateOnLoad; private readonly bool _suspendLoad;
private readonly int _priority; private readonly int _priority;
private AsyncOperation _asyncOp; private AsyncOperation _asyncOperation;
public DatabaseSceneProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) : base(impl, providerGUID, assetInfo) public DatabaseSceneProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool suspendLoad, int priority) : base(impl, providerGUID, assetInfo)
{ {
SceneMode = sceneMode; SceneMode = sceneMode;
_activateOnLoad = activateOnLoad; _suspendLoad = suspendLoad;
_priority = priority; _priority = priority;
} }
public override void Update() public override void Update()
@ -54,11 +54,11 @@ namespace YooAsset
{ {
LoadSceneParameters loadSceneParameters = new LoadSceneParameters(); LoadSceneParameters loadSceneParameters = new LoadSceneParameters();
loadSceneParameters.loadSceneMode = SceneMode; loadSceneParameters.loadSceneMode = SceneMode;
_asyncOp = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneAsyncInPlayMode(MainAssetInfo.AssetPath, loadSceneParameters); _asyncOperation = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneAsyncInPlayMode(MainAssetInfo.AssetPath, loadSceneParameters);
if (_asyncOp != null) if (_asyncOperation != null)
{ {
_asyncOp.allowSceneActivation = true; _asyncOperation.allowSceneActivation = !_suspendLoad;
_asyncOp.priority = _priority; _asyncOperation.priority = _priority;
SceneObject = SceneManager.GetSceneAt(SceneManager.sceneCount - 1); SceneObject = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
Status = EStatus.Checking; Status = EStatus.Checking;
} }
@ -74,12 +74,9 @@ namespace YooAsset
// 3. 检测加载结果 // 3. 检测加载结果
if (Status == EStatus.Checking) if (Status == EStatus.Checking)
{ {
Progress = _asyncOp.progress; Progress = _asyncOperation.progress;
if (_asyncOp.isDone) if (_asyncOperation.isDone)
{ {
if (SceneObject.IsValid() && _activateOnLoad)
SceneManager.SetActiveScene(SceneObject);
Status = SceneObject.IsValid() ? EStatus.Succeed : EStatus.Failed; Status = SceneObject.IsValid() ? EStatus.Succeed : EStatus.Failed;
if (Status == EStatus.Failed) if (Status == EStatus.Failed)
{ {
@ -91,5 +88,17 @@ namespace YooAsset
} }
#endif #endif
} }
/// <summary>
/// 解除场景加载挂起操作
/// </summary>
public bool UnSuspendLoad()
{
if (_asyncOperation == null)
return false;
_asyncOperation.allowSceneActivation = true;
return true;
}
} }
} }

View File

@ -91,7 +91,7 @@ namespace YooAsset
protected BundleLoaderBase OwnerBundle { private set; get; } protected BundleLoaderBase OwnerBundle { private set; get; }
protected DependAssetBundleGroup DependBundleGroup { private set; get; } protected DependAssetBundles DependBundles { private set; get; }
protected bool IsWaitForAsyncComplete { private set; get; } = false; protected bool IsWaitForAsyncComplete { private set; get; } = false;
private readonly List<OperationHandleBase> _handles = new List<OperationHandleBase>(); private readonly List<OperationHandleBase> _handles = new List<OperationHandleBase>();
@ -109,9 +109,9 @@ namespace YooAsset
OwnerBundle.Reference(); OwnerBundle.Reference();
OwnerBundle.AddProvider(this); OwnerBundle.AddProvider(this);
var dependBundles = impl.CreateDependAssetBundleLoaders(assetInfo); var dependList = impl.CreateDependAssetBundleLoaders(assetInfo);
DependBundleGroup = new DependAssetBundleGroup(dependBundles); DependBundles = new DependAssetBundles(dependList);
DependBundleGroup.Reference(); DependBundles.Reference();
} }
} }
@ -133,10 +133,10 @@ namespace YooAsset
OwnerBundle.Release(); OwnerBundle.Release();
OwnerBundle = null; OwnerBundle = null;
} }
if (DependBundleGroup != null) if (DependBundles != null)
{ {
DependBundleGroup.Release(); DependBundles.Release();
DependBundleGroup = null; DependBundles = null;
} }
} }
@ -177,6 +177,8 @@ namespace YooAsset
handle = new SceneOperationHandle(this); handle = new SceneOperationHandle(this);
else if (typeof(T) == typeof(SubAssetsOperationHandle)) else if (typeof(T) == typeof(SubAssetsOperationHandle))
handle = new SubAssetsOperationHandle(this); handle = new SubAssetsOperationHandle(this);
else if (typeof(T) == typeof(AllAssetsOperationHandle))
handle = new AllAssetsOperationHandle(this);
else if (typeof(T) == typeof(RawFileOperationHandle)) else if (typeof(T) == typeof(RawFileOperationHandle))
handle = new RawFileOperationHandle(this); handle = new RawFileOperationHandle(this);
else else
@ -320,7 +322,7 @@ namespace YooAsset
DownloadReport result = new DownloadReport(); DownloadReport result = new DownloadReport();
result.TotalSize = (ulong)OwnerBundle.MainBundleInfo.Bundle.FileSize; result.TotalSize = (ulong)OwnerBundle.MainBundleInfo.Bundle.FileSize;
result.DownloadedBytes = OwnerBundle.DownloadedBytes; result.DownloadedBytes = OwnerBundle.DownloadedBytes;
foreach (var dependBundle in DependBundleGroup.DependBundles) foreach (var dependBundle in DependBundles.DependList)
{ {
result.TotalSize += (ulong)dependBundle.MainBundleInfo.Bundle.FileSize; result.TotalSize += (ulong)dependBundle.MainBundleInfo.Bundle.FileSize;
result.DownloadedBytes += dependBundle.DownloadedBytes; result.DownloadedBytes += dependBundle.DownloadedBytes;
@ -340,7 +342,7 @@ namespace YooAsset
bundleInfo.Status = OwnerBundle.Status.ToString(); bundleInfo.Status = OwnerBundle.Status.ToString();
output.Add(bundleInfo); output.Add(bundleInfo);
DependBundleGroup.GetBundleDebugInfos(output); DependBundles.GetBundleDebugInfos(output);
} }
#endregion #endregion
} }

View File

@ -12,7 +12,7 @@ namespace YooAsset
/// </summary> /// </summary>
public static void WriteInfoToFile(string filePath, string dataFileCRC, long dataFileSize) public static void WriteInfoToFile(string filePath, string dataFileCRC, long dataFileSize)
{ {
using (FileStream fs = new FileStream(filePath, FileMode.Create)) using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read))
{ {
SharedBuffer.Clear(); SharedBuffer.Clear();
SharedBuffer.WriteUTF8(dataFileCRC); SharedBuffer.WriteUTF8(dataFileCRC);

View File

@ -10,6 +10,11 @@ namespace YooAsset
{ {
private readonly static Dictionary<string, PackageCache> _cachedDic = new Dictionary<string, PackageCache>(1000); private readonly static Dictionary<string, PackageCache> _cachedDic = new Dictionary<string, PackageCache>(1000);
/// <summary>
/// 禁用Unity缓存系统在WebGL平台
/// </summary>
public static bool DisableUnityCacheOnWebGL = false;
/// <summary> /// <summary>
/// 初始化时的验证级别 /// 初始化时的验证级别
/// </summary> /// </summary>

View File

@ -45,7 +45,7 @@ namespace YooAsset
{ {
// BundleFiles // BundleFiles
{ {
string rootPath = PersistentTools.GetCachedBundleFileFolderPath(_packageName); string rootPath = PersistentTools.GetPersistent(_packageName).SandboxCacheBundleFilesRoot;
DirectoryInfo rootDirectory = new DirectoryInfo(rootPath); DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);
if (rootDirectory.Exists) if (rootDirectory.Exists)
{ {
@ -56,7 +56,7 @@ namespace YooAsset
// RawFiles // RawFiles
{ {
string rootPath = PersistentTools.GetCachedRawFileFolderPath(_packageName); string rootPath = PersistentTools.GetPersistent(_packageName).SandboxCacheRawFilesRoot;
DirectoryInfo rootDirectory = new DirectoryInfo(rootPath); DirectoryInfo rootDirectory = new DirectoryInfo(rootPath);
if (rootDirectory.Exists) if (rootDirectory.Exists)
{ {

View File

@ -0,0 +1,163 @@
using System.IO;
namespace YooAsset
{
internal class Persistent
{
private readonly string _packageName;
public string BuildinRoot { private set; get; }
public string BuildinPackageRoot { private set; get; }
public string SandboxRoot { private set; get; }
public string SandboxPackageRoot { private set; get; }
public string SandboxCacheBundleFilesRoot { private set; get; }
public string SandboxCacheRawFilesRoot { private set; get; }
public string SandboxManifestFilesRoot { private set; get; }
public string SandboxAppFootPrintFilePath { private set; get; }
public Persistent(string packageName)
{
_packageName = packageName;
}
/// <summary>
/// 重写根路径
/// </summary>
public void OverwriteRootDirectory(string buildinRoot, string sandboxRoot)
{
if (string.IsNullOrEmpty(buildinRoot))
BuildinRoot = CreateDefaultBuildinRoot();
else
BuildinRoot = buildinRoot;
if (string.IsNullOrEmpty(sandboxRoot))
SandboxRoot = CreateDefaultSandboxRoot();
else
SandboxRoot = sandboxRoot;
BuildinPackageRoot = PathUtility.Combine(BuildinRoot, _packageName);
SandboxPackageRoot = PathUtility.Combine(SandboxRoot, _packageName);
SandboxCacheBundleFilesRoot = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.CachedBundleFileFolder);
SandboxCacheRawFilesRoot = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.CachedRawFileFolder);
SandboxManifestFilesRoot = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.ManifestFolderName);
SandboxAppFootPrintFilePath = PathUtility.Combine(SandboxPackageRoot, YooAssetSettings.AppFootPrintFileName);
}
private static string CreateDefaultBuildinRoot()
{
return PathUtility.Combine(UnityEngine.Application.streamingAssetsPath, YooAssetSettings.DefaultYooFolderName);
}
private static string CreateDefaultSandboxRoot()
{
#if UNITY_EDITOR
// 注意:为了方便调试查看,编辑器下把存储目录放到项目里。
string projectPath = Path.GetDirectoryName(UnityEngine.Application.dataPath);
projectPath = PathUtility.RegularPath(projectPath);
return PathUtility.Combine(projectPath, YooAssetSettings.DefaultYooFolderName);
#elif UNITY_STANDALONE
return PathUtility.Combine(UnityEngine.Application.dataPath, YooAssetSettings.DefaultYooFolderName);
#else
return PathUtility.Combine(UnityEngine.Application.persistentDataPath, YooAssetSettings.DefaultYooFolderName);
#endif
}
/// <summary>
/// 删除沙盒里的包裹目录
/// </summary>
public void DeleteSandboxPackageFolder()
{
if (Directory.Exists(SandboxPackageRoot))
Directory.Delete(SandboxPackageRoot, true);
}
/// <summary>
/// 删除沙盒内的缓存文件夹
/// </summary>
public void DeleteSandboxCacheFilesFolder()
{
// CacheBundleFiles
if (Directory.Exists(SandboxCacheBundleFilesRoot))
Directory.Delete(SandboxCacheBundleFilesRoot, true);
// CacheRawFiles
if (Directory.Exists(SandboxCacheRawFilesRoot))
Directory.Delete(SandboxCacheRawFilesRoot, true);
}
/// <summary>
/// 删除沙盒内的清单文件夹
/// </summary>
public void DeleteSandboxManifestFilesFolder()
{
if (Directory.Exists(SandboxManifestFilesRoot))
Directory.Delete(SandboxManifestFilesRoot, true);
}
/// <summary>
/// 获取沙盒内包裹的清单文件的路径
/// </summary>
public string GetSandboxPackageManifestFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_packageName, packageVersion);
return PathUtility.Combine(SandboxManifestFilesRoot, fileName);
}
/// <summary>
/// 获取沙盒内包裹的哈希文件的路径
/// </summary>
public string GetSandboxPackageHashFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(_packageName, packageVersion);
return PathUtility.Combine(SandboxManifestFilesRoot, fileName);
}
/// <summary>
/// 获取沙盒内包裹的版本文件的路径
/// </summary>
public string GetSandboxPackageVersionFilePath()
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_packageName);
return PathUtility.Combine(SandboxManifestFilesRoot, fileName);
}
/// <summary>
/// 保存沙盒内默认的包裹版本
/// </summary>
public void SaveSandboxPackageVersionFile(string version)
{
string filePath = GetSandboxPackageVersionFilePath();
FileUtility.WriteAllText(filePath, version);
}
/// <summary>
/// 获取APP内包裹的清单文件的路径
/// </summary>
public string GetBuildinPackageManifestFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_packageName, packageVersion);
return PathUtility.Combine(BuildinPackageRoot, fileName);
}
/// <summary>
/// 获取APP内包裹的哈希文件的路径
/// </summary>
public string GetBuildinPackageHashFilePath(string packageVersion)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(_packageName, packageVersion);
return PathUtility.Combine(BuildinPackageRoot, fileName);
}
/// <summary>
/// 获取APP内包裹的版本文件的路径
/// </summary>
public string GetBuildinPackageVersionFilePath()
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_packageName);
return PathUtility.Combine(BuildinPackageRoot, fileName);
}
}
}

View File

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

View File

@ -3,84 +3,31 @@ using System.Collections.Generic;
namespace YooAsset namespace YooAsset
{ {
internal static class PersistentTools internal class PersistentTools
{ {
private const string SandboxFolderName = "Sandbox"; private static readonly Dictionary<string, Persistent> _persitentDic = new Dictionary<string, Persistent>(100);
private const string CacheFolderName = "CacheFiles";
private const string CachedBundleFileFolder = "BundleFiles";
private const string CachedRawFileFolder = "RawFiles";
private const string ManifestFolderName = "ManifestFiles";
private const string AppFootPrintFileName = "ApplicationFootPrint.bytes";
private static string _buildinPath;
private static string _sandboxPath;
/// <summary> /// <summary>
/// 重写沙盒跟路径 /// 获取包裹的持久化类
/// </summary> /// </summary>
public static void OverwriteSandboxPath(string sandboxPath) public static Persistent GetPersistent(string packageName)
{ {
_sandboxPath = sandboxPath; if (_persitentDic.ContainsKey(packageName) == false)
throw new System.Exception("Should never get here !");
return _persitentDic[packageName];
} }
/// <summary> /// <summary>
/// 获取沙盒文件夹路径 /// 获取或创建包裹的持久化类
/// </summary> /// </summary>
public static string GetPersistentRootPath() public static Persistent GetOrCreatePersistent(string packageName)
{ {
#if UNITY_EDITOR if (_persitentDic.ContainsKey(packageName) == false)
// 注意:为了方便调试查看,编辑器下把存储目录放到项目里
if (string.IsNullOrEmpty(_sandboxPath))
{ {
string projectPath = Path.GetDirectoryName(UnityEngine.Application.dataPath); Persistent persistent = new Persistent(packageName);
projectPath = PathUtility.RegularPath(projectPath); _persitentDic.Add(packageName, persistent);
_sandboxPath = PathUtility.Combine(projectPath, SandboxFolderName);
} }
#elif UNITY_STANDALONE return _persitentDic[packageName];
if (string.IsNullOrEmpty(_sandboxPath))
{
_sandboxPath = PathUtility.Combine(UnityEngine.Application.dataPath, SandboxFolderName);
}
#else
if (string.IsNullOrEmpty(_sandboxPath))
{
_sandboxPath = PathUtility.Combine(UnityEngine.Application.persistentDataPath, SandboxFolderName);
}
#endif
return _sandboxPath;
}
/// <summary>
/// 获取基于流文件夹的加载路径
/// </summary>
public static string MakeStreamingLoadPath(string path)
{
if (string.IsNullOrEmpty(_buildinPath))
{
_buildinPath = PathUtility.Combine(UnityEngine.Application.streamingAssetsPath, YooAssetSettings.StreamingAssetsBuildinFolder);
}
return PathUtility.Combine(_buildinPath, path);
}
/// <summary>
/// 获取基于沙盒文件夹的加载路径
/// </summary>
public static string MakePersistentLoadPath(string path)
{
string root = GetPersistentRootPath();
return PathUtility.Combine(root, path);
}
public static string MakePersistentLoadPath(string path1, string path2)
{
string root = GetPersistentRootPath();
return PathUtility.Combine(root, path1, path2);
}
public static string MakePersistentLoadPath(string path1, string path2, string path3)
{
string root = GetPersistentRootPath();
return PathUtility.Combine(root, path1, path2, path3);
} }
/// <summary> /// <summary>
@ -100,109 +47,5 @@ namespace YooAsset
return path; return path;
#endif #endif
} }
/// <summary>
/// 删除沙盒总目录
/// </summary>
public static void DeleteSandbox()
{
string directoryPath = GetPersistentRootPath();
if (Directory.Exists(directoryPath))
Directory.Delete(directoryPath, true);
}
/// <summary>
/// 删除沙盒内的缓存文件夹
/// </summary>
public static void DeleteCacheFolder()
{
string root = MakePersistentLoadPath(CacheFolderName);
if (Directory.Exists(root))
Directory.Delete(root, true);
}
/// <summary>
/// 删除沙盒内的清单文件夹
/// </summary>
public static void DeleteManifestFolder()
{
string root = MakePersistentLoadPath(ManifestFolderName);
if (Directory.Exists(root))
Directory.Delete(root, true);
}
/// <summary>
/// 获取缓存的BundleFile文件夹路径
/// </summary>
private readonly static Dictionary<string, string> _cachedBundleFileFolder = new Dictionary<string, string>(100);
public static string GetCachedBundleFileFolderPath(string packageName)
{
if (_cachedBundleFileFolder.TryGetValue(packageName, out string value) == false)
{
value = MakePersistentLoadPath(CacheFolderName, packageName, CachedBundleFileFolder);
_cachedBundleFileFolder.Add(packageName, value);
}
return value;
}
/// <summary>
/// 获取缓存的RawFile文件夹路径
/// </summary>
private readonly static Dictionary<string, string> _cachedRawFileFolder = new Dictionary<string, string>(100);
public static string GetCachedRawFileFolderPath(string packageName)
{
if (_cachedRawFileFolder.TryGetValue(packageName, out string value) == false)
{
value = MakePersistentLoadPath(CacheFolderName, packageName, CachedRawFileFolder);
_cachedRawFileFolder.Add(packageName, value);
}
return value;
}
/// <summary>
/// 获取应用程序的水印文件路径
/// </summary>
public static string GetAppFootPrintFilePath()
{
return MakePersistentLoadPath(AppFootPrintFileName);
}
/// <summary>
/// 获取沙盒内清单文件的路径
/// </summary>
public static string GetCacheManifestFilePath(string packageName, string packageVersion)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(packageName, packageVersion);
return MakePersistentLoadPath(ManifestFolderName, fileName);
}
/// <summary>
/// 获取沙盒内包裹的哈希文件的路径
/// </summary>
public static string GetCachePackageHashFilePath(string packageName, string packageVersion)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(packageName, packageVersion);
return MakePersistentLoadPath(ManifestFolderName, fileName);
}
/// <summary>
/// 获取沙盒内包裹的版本文件的路径
/// </summary>
public static string GetCachePackageVersionFilePath(string packageName)
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(packageName);
return MakePersistentLoadPath(ManifestFolderName, fileName);
}
/// <summary>
/// 保存默认的包裹版本
/// </summary>
public static void SaveCachePackageVersionFile(string packageName, string version)
{
string filePath = GetCachePackageVersionFilePath(packageName);
FileUtility.WriteAllText(filePath, version);
}
} }
} }

View File

@ -32,6 +32,11 @@ namespace YooAsset
/// </summary> /// </summary>
public static CertificateHandler CertificateHandlerInstance = null; public static CertificateHandler CertificateHandlerInstance = null;
/// <summary>
/// 网络重定向次数
/// </summary>
public static int RedirectLimit { set; get; } = -1;
/// <summary> /// <summary>
/// 启用断点续传功能文件的最小字节数 /// 启用断点续传功能文件的最小字节数
/// </summary> /// </summary>
@ -128,11 +133,29 @@ namespace YooAsset
/// </summary> /// </summary>
public static UnityWebRequest NewRequest(string requestURL) public static UnityWebRequest NewRequest(string requestURL)
{ {
UnityWebRequest webRequest;
if (RequestDelegate != null) if (RequestDelegate != null)
return RequestDelegate.Invoke(requestURL); webRequest = RequestDelegate.Invoke(requestURL);
else
webRequest = new UnityWebRequest(requestURL, UnityWebRequest.kHttpVerbGET);
var request = new UnityWebRequest(requestURL, UnityWebRequest.kHttpVerbGET); SetUnityWebRequest(webRequest);
return request; return webRequest;
}
/// <summary>
/// 设置网络请求的自定义参数
/// </summary>
public static void SetUnityWebRequest(UnityWebRequest webRequest)
{
if (RedirectLimit >= 0)
webRequest.redirectLimit = RedirectLimit;
if (CertificateHandlerInstance != null)
{
webRequest.certificateHandler = CertificateHandlerInstance;
webRequest.disposeCertificateHandlerOnDispose = false;
}
} }
/// <summary> /// <summary>

View File

@ -101,13 +101,6 @@ namespace YooAsset
handler.removeFileOnAbort = true; handler.removeFileOnAbort = true;
_webRequest.downloadHandler = handler; _webRequest.downloadHandler = handler;
_webRequest.disposeDownloadHandlerOnDispose = true; _webRequest.disposeDownloadHandlerOnDispose = true;
if (DownloadSystem.CertificateHandlerInstance != null)
{
_webRequest.certificateHandler = DownloadSystem.CertificateHandlerInstance;
_webRequest.disposeCertificateHandlerOnDispose = false;
}
_webRequest.SendWebRequest(); _webRequest.SendWebRequest();
_steps = ESteps.CheckDownload; _steps = ESteps.CheckDownload;
} }
@ -137,13 +130,6 @@ namespace YooAsset
_webRequest.disposeDownloadHandlerOnDispose = true; _webRequest.disposeDownloadHandlerOnDispose = true;
if (fileLength > 0) if (fileLength > 0)
_webRequest.SetRequestHeader("Range", $"bytes={fileLength}-"); _webRequest.SetRequestHeader("Range", $"bytes={fileLength}-");
if (DownloadSystem.CertificateHandlerInstance != null)
{
_webRequest.certificateHandler = DownloadSystem.CertificateHandlerInstance;
_webRequest.disposeCertificateHandlerOnDispose = false;
}
_webRequest.SendWebRequest(); _webRequest.SendWebRequest();
_steps = ESteps.CheckDownload; _steps = ESteps.CheckDownload;
} }

View File

@ -27,17 +27,23 @@ namespace YooAsset
/// </summary> /// </summary>
public abstract class InitializeParameters public abstract class InitializeParameters
{ {
/// <summary>
/// 资源定位地址大小写不敏感
/// 注意默认值为False
/// </summary>
public bool LocationToLower = false;
/// <summary> /// <summary>
/// 文件解密服务接口 /// 文件解密服务接口
/// </summary> /// </summary>
public IDecryptionServices DecryptionServices = null; public IDecryptionServices DecryptionServices = null;
/// <summary>
/// 内置文件的根路径
/// 注意:当参数为空的时候会使用默认的根目录。
/// </summary>
public string BuildinRootDirectory = string.Empty;
/// <summary>
/// 沙盒文件的根路径
/// 注意:当参数为空的时候会使用默认的根目录。
/// </summary>
public string SandboxRootDirectory = string.Empty;
/// <summary> /// <summary>
/// 资源加载每帧处理的最大时间片段 /// 资源加载每帧处理的最大时间片段
/// 注意默认值为MaxValue /// 注意默认值为MaxValue

View File

@ -26,9 +26,9 @@ namespace YooAsset
public string RemoteFallbackURL { private set; get; } public string RemoteFallbackURL { private set; get; }
/// <summary> /// <summary>
/// 编辑器资源路径 /// 注意:该字段只用于帮助编辑器下的模拟模式。
/// </summary> /// </summary>
public string EditorAssetPath { private set; get; } public string[] IncludeAssets;
private BundleInfo() private BundleInfo()
@ -40,15 +40,6 @@ namespace YooAsset
LoadMode = loadMode; LoadMode = loadMode;
RemoteMainURL = mainURL; RemoteMainURL = mainURL;
RemoteFallbackURL = fallbackURL; RemoteFallbackURL = fallbackURL;
EditorAssetPath = string.Empty;
}
public BundleInfo(PackageBundle bundle, ELoadMode loadMode, string editorAssetPath)
{
Bundle = bundle;
LoadMode = loadMode;
RemoteMainURL = string.Empty;
RemoteFallbackURL = string.Empty;
EditorAssetPath = editorAssetPath;
} }
public BundleInfo(PackageBundle bundle, ELoadMode loadMode) public BundleInfo(PackageBundle bundle, ELoadMode loadMode)
{ {
@ -56,10 +47,8 @@ namespace YooAsset
LoadMode = loadMode; LoadMode = loadMode;
RemoteMainURL = string.Empty; RemoteMainURL = string.Empty;
RemoteFallbackURL = string.Empty; RemoteFallbackURL = string.Empty;
EditorAssetPath = string.Empty;
} }
/// <summary> /// <summary>
/// 是否为JAR包内文件 /// 是否为JAR包内文件
/// </summary> /// </summary>

View File

@ -8,7 +8,6 @@ namespace YooAsset
{ {
internal static class ManifestTools internal static class ManifestTools
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
/// <summary> /// <summary>
/// 序列化JSON文件 /// 序列化JSON文件
@ -37,6 +36,8 @@ namespace YooAsset
// 写入文件头信息 // 写入文件头信息
buffer.WriteBool(manifest.EnableAddressable); buffer.WriteBool(manifest.EnableAddressable);
buffer.WriteBool(manifest.LocationToLower);
buffer.WriteBool(manifest.IncludeAssetGUID);
buffer.WriteInt32(manifest.OutputNameStyle); buffer.WriteInt32(manifest.OutputNameStyle);
buffer.WriteUTF8(manifest.PackageName); buffer.WriteUTF8(manifest.PackageName);
buffer.WriteUTF8(manifest.PackageVersion); buffer.WriteUTF8(manifest.PackageVersion);
@ -48,6 +49,7 @@ namespace YooAsset
var packageAsset = manifest.AssetList[i]; var packageAsset = manifest.AssetList[i];
buffer.WriteUTF8(packageAsset.Address); buffer.WriteUTF8(packageAsset.Address);
buffer.WriteUTF8(packageAsset.AssetPath); buffer.WriteUTF8(packageAsset.AssetPath);
buffer.WriteUTF8(packageAsset.AssetGUID);
buffer.WriteUTF8Array(packageAsset.AssetTags); buffer.WriteUTF8Array(packageAsset.AssetTags);
buffer.WriteInt32(packageAsset.BundleID); buffer.WriteInt32(packageAsset.BundleID);
buffer.WriteInt32Array(packageAsset.DependIDs); buffer.WriteInt32Array(packageAsset.DependIDs);
@ -105,10 +107,16 @@ namespace YooAsset
// 读取文件头信息 // 读取文件头信息
manifest.FileVersion = fileVersion; manifest.FileVersion = fileVersion;
manifest.EnableAddressable = buffer.ReadBool(); manifest.EnableAddressable = buffer.ReadBool();
manifest.LocationToLower = buffer.ReadBool();
manifest.IncludeAssetGUID = buffer.ReadBool();
manifest.OutputNameStyle = buffer.ReadInt32(); manifest.OutputNameStyle = buffer.ReadInt32();
manifest.PackageName = buffer.ReadUTF8(); manifest.PackageName = buffer.ReadUTF8();
manifest.PackageVersion = buffer.ReadUTF8(); manifest.PackageVersion = buffer.ReadUTF8();
// 检测配置
if (manifest.EnableAddressable && manifest.LocationToLower)
throw new Exception("Addressable not support location to lower !");
// 读取资源列表 // 读取资源列表
int packageAssetCount = buffer.ReadInt32(); int packageAssetCount = buffer.ReadInt32();
manifest.AssetList = new List<PackageAsset>(packageAssetCount); manifest.AssetList = new List<PackageAsset>(packageAssetCount);
@ -117,6 +125,7 @@ namespace YooAsset
var packageAsset = new PackageAsset(); var packageAsset = new PackageAsset();
packageAsset.Address = buffer.ReadUTF8(); packageAsset.Address = buffer.ReadUTF8();
packageAsset.AssetPath = buffer.ReadUTF8(); packageAsset.AssetPath = buffer.ReadUTF8();
packageAsset.AssetGUID = buffer.ReadUTF8();
packageAsset.AssetTags = buffer.ReadUTF8Array(); packageAsset.AssetTags = buffer.ReadUTF8Array();
packageAsset.BundleID = buffer.ReadInt32(); packageAsset.BundleID = buffer.ReadInt32();
packageAsset.DependIDs = buffer.ReadInt32Array(); packageAsset.DependIDs = buffer.ReadInt32Array();
@ -141,7 +150,7 @@ namespace YooAsset
} }
} }
// BundleDic // 填充BundleDic
manifest.BundleDic = new Dictionary<string, PackageBundle>(manifest.BundleList.Count); manifest.BundleDic = new Dictionary<string, PackageBundle>(manifest.BundleList.Count);
foreach (var packageBundle in manifest.BundleList) foreach (var packageBundle in manifest.BundleList)
{ {
@ -149,7 +158,7 @@ namespace YooAsset
manifest.BundleDic.Add(packageBundle.BundleName, packageBundle); manifest.BundleDic.Add(packageBundle.BundleName, packageBundle);
} }
// AssetDic // 填充AssetDic
manifest.AssetDic = new Dictionary<string, PackageAsset>(manifest.AssetList.Count); manifest.AssetDic = new Dictionary<string, PackageAsset>(manifest.AssetList.Count);
foreach (var packageAsset in manifest.AssetList) foreach (var packageAsset in manifest.AssetList)
{ {
@ -188,14 +197,28 @@ namespace YooAsset
} }
/// <summary> /// <summary>
/// 获取解压BundleInfo /// 转换为解压BundleInfo
/// </summary> /// </summary>
public static BundleInfo GetUnpackInfo(PackageBundle packageBundle) public static BundleInfo ConvertToUnpackInfo(PackageBundle packageBundle)
{ {
// 注意:我们把流加载路径指定为远端下载地址 // 注意:我们把流加载路径指定为远端下载地址
string streamingPath = PersistentTools.ConvertToWWWPath(packageBundle.StreamingFilePath); string streamingPath = PersistentTools.ConvertToWWWPath(packageBundle.StreamingFilePath);
BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromStreaming, streamingPath, streamingPath); BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromStreaming, streamingPath, streamingPath);
return bundleInfo; return bundleInfo;
} }
/// <summary>
/// 批量转换解压为BundleInfo
/// </summary>
public static List<BundleInfo> ConvertToUnpackInfos(List<PackageBundle> unpackList)
{
List<BundleInfo> result = new List<BundleInfo>(unpackList.Count);
foreach (var packageBundle in unpackList)
{
var bundleInfo = ConvertToUnpackInfo(packageBundle);
result.Add(bundleInfo);
}
return result;
}
} }
} }

View File

@ -217,13 +217,13 @@ namespace YooAsset
if (_steps == ESteps.CheckAppFootPrint) if (_steps == ESteps.CheckAppFootPrint)
{ {
var appFootPrint = new AppFootPrint(); var appFootPrint = new AppFootPrint();
appFootPrint.Load(); appFootPrint.Load(_packageName);
// 如果水印发生变化,则说明覆盖安装后首次打开游戏 // 如果水印发生变化,则说明覆盖安装后首次打开游戏
if (appFootPrint.IsDirty()) if (appFootPrint.IsDirty())
{ {
PersistentTools.DeleteManifestFolder(); PersistentTools.GetPersistent(_packageName).DeleteSandboxManifestFilesFolder();
appFootPrint.Coverage(); appFootPrint.Coverage(_packageName);
YooLogger.Log("Delete manifest files when application foot print dirty !"); YooLogger.Log("Delete manifest files when application foot print dirty !");
} }
_steps = ESteps.QueryCachePackageVersion; _steps = ESteps.QueryCachePackageVersion;
@ -374,16 +374,16 @@ namespace YooAsset
/// <summary> /// <summary>
/// 读取应用程序水印 /// 读取应用程序水印
/// </summary> /// </summary>
public void Load() public void Load(string packageName)
{ {
string footPrintFilePath = PersistentTools.GetAppFootPrintFilePath(); string footPrintFilePath = PersistentTools.GetPersistent(packageName).SandboxAppFootPrintFilePath;
if (File.Exists(footPrintFilePath)) if (File.Exists(footPrintFilePath))
{ {
_footPrint = FileUtility.ReadAllText(footPrintFilePath); _footPrint = FileUtility.ReadAllText(footPrintFilePath);
} }
else else
{ {
Coverage(); Coverage(packageName);
} }
} }
@ -402,14 +402,14 @@ namespace YooAsset
/// <summary> /// <summary>
/// 覆盖掉水印 /// 覆盖掉水印
/// </summary> /// </summary>
public void Coverage() public void Coverage(string packageName)
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
_footPrint = Application.version; _footPrint = Application.version;
#else #else
_footPrint = Application.buildGUID; _footPrint = Application.buildGUID;
#endif #endif
string footPrintFilePath = PersistentTools.GetAppFootPrintFilePath(); string footPrintFilePath = PersistentTools.GetPersistent(packageName).SandboxAppFootPrintFilePath;
FileUtility.WriteAllText(footPrintFilePath, _footPrint); FileUtility.WriteAllText(footPrintFilePath, _footPrint);
YooLogger.Log($"Save application foot print : {_footPrint}"); YooLogger.Log($"Save application foot print : {_footPrint}");
} }

View File

@ -16,7 +16,7 @@ namespace YooAsset
DeserializeBundleList, DeserializeBundleList,
Done, Done,
} }
private readonly BufferReader _buffer; private readonly BufferReader _buffer;
private int _packageAssetCount; private int _packageAssetCount;
private int _packageBundleCount; private int _packageBundleCount;
@ -77,10 +77,16 @@ namespace YooAsset
Manifest = new PackageManifest(); Manifest = new PackageManifest();
Manifest.FileVersion = fileVersion; Manifest.FileVersion = fileVersion;
Manifest.EnableAddressable = _buffer.ReadBool(); Manifest.EnableAddressable = _buffer.ReadBool();
Manifest.LocationToLower = _buffer.ReadBool();
Manifest.IncludeAssetGUID = _buffer.ReadBool();
Manifest.OutputNameStyle = _buffer.ReadInt32(); Manifest.OutputNameStyle = _buffer.ReadInt32();
Manifest.PackageName = _buffer.ReadUTF8(); Manifest.PackageName = _buffer.ReadUTF8();
Manifest.PackageVersion = _buffer.ReadUTF8(); Manifest.PackageVersion = _buffer.ReadUTF8();
// 检测配置
if (Manifest.EnableAddressable && Manifest.LocationToLower)
throw new System.Exception("Addressable not support location to lower !");
_steps = ESteps.PrepareAssetList; _steps = ESteps.PrepareAssetList;
} }
@ -89,6 +95,17 @@ namespace YooAsset
_packageAssetCount = _buffer.ReadInt32(); _packageAssetCount = _buffer.ReadInt32();
Manifest.AssetList = new List<PackageAsset>(_packageAssetCount); Manifest.AssetList = new List<PackageAsset>(_packageAssetCount);
Manifest.AssetDic = new Dictionary<string, PackageAsset>(_packageAssetCount); Manifest.AssetDic = new Dictionary<string, PackageAsset>(_packageAssetCount);
if (Manifest.EnableAddressable)
Manifest.AssetPathMapping1 = new Dictionary<string, string>(_packageAssetCount);
else
Manifest.AssetPathMapping1 = new Dictionary<string, string>(_packageAssetCount * 2);
if (Manifest.IncludeAssetGUID)
Manifest.AssetPathMapping2 = new Dictionary<string, string>(_packageAssetCount);
else
Manifest.AssetPathMapping2 = new Dictionary<string, string>();
_progressTotalValue = _packageAssetCount; _progressTotalValue = _packageAssetCount;
_steps = ESteps.DeserializeAssetList; _steps = ESteps.DeserializeAssetList;
} }
@ -99,6 +116,7 @@ namespace YooAsset
var packageAsset = new PackageAsset(); var packageAsset = new PackageAsset();
packageAsset.Address = _buffer.ReadUTF8(); packageAsset.Address = _buffer.ReadUTF8();
packageAsset.AssetPath = _buffer.ReadUTF8(); packageAsset.AssetPath = _buffer.ReadUTF8();
packageAsset.AssetGUID = _buffer.ReadUTF8();
packageAsset.AssetTags = _buffer.ReadUTF8Array(); packageAsset.AssetTags = _buffer.ReadUTF8Array();
packageAsset.BundleID = _buffer.ReadInt32(); packageAsset.BundleID = _buffer.ReadInt32();
packageAsset.DependIDs = _buffer.ReadInt32Array(); packageAsset.DependIDs = _buffer.ReadInt32Array();
@ -111,6 +129,47 @@ namespace YooAsset
else else
Manifest.AssetDic.Add(assetPath, packageAsset); Manifest.AssetDic.Add(assetPath, packageAsset);
// 填充AssetPathMapping1
if (Manifest.EnableAddressable)
{
string location = packageAsset.Address;
if (Manifest.AssetPathMapping1.ContainsKey(location))
throw new System.Exception($"Address have existed : {location}");
else
Manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
}
else
{
string location = packageAsset.AssetPath;
if (Manifest.LocationToLower)
location = location.ToLower();
// 添加原生路径的映射
if (Manifest.AssetPathMapping1.ContainsKey(location))
throw new System.Exception($"AssetPath have existed : {location}");
else
Manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
// 添加无后缀名路径的映射
if (Path.HasExtension(location))
{
string locationWithoutExtension = PathUtility.RemoveExtension(location);
if (Manifest.AssetPathMapping1.ContainsKey(locationWithoutExtension))
YooLogger.Warning($"AssetPath have existed : {locationWithoutExtension}");
else
Manifest.AssetPathMapping1.Add(locationWithoutExtension, packageAsset.AssetPath);
}
}
// 填充AssetPathMapping2
if (Manifest.IncludeAssetGUID)
{
if (Manifest.AssetPathMapping2.ContainsKey(packageAsset.AssetGUID))
throw new System.Exception($"AssetGUID have existed : {packageAsset.AssetGUID}");
else
Manifest.AssetPathMapping2.Add(packageAsset.AssetGUID, packageAsset.AssetPath);
}
_packageAssetCount--; _packageAssetCount--;
Progress = 1f - _packageAssetCount / _progressTotalValue; Progress = 1f - _packageAssetCount / _progressTotalValue;
if (OperationSystem.IsBusy) if (OperationSystem.IsBusy)

View File

@ -41,7 +41,7 @@ namespace YooAsset
{ {
if (_downloader1 == null) if (_downloader1 == null)
{ {
string savePath = PersistentTools.GetCachePackageHashFilePath(_packageName, _packageVersion); string savePath = PersistentTools.GetPersistent(_packageName).GetSandboxPackageHashFilePath(_packageVersion);
string fileName = YooAssetSettingsData.GetPackageHashFileName(_packageName, _packageVersion); string fileName = YooAssetSettingsData.GetPackageHashFileName(_packageName, _packageVersion);
string webURL = GetDownloadRequestURL(fileName); string webURL = GetDownloadRequestURL(fileName);
YooLogger.Log($"Beginning to download package hash file : {webURL}"); YooLogger.Log($"Beginning to download package hash file : {webURL}");
@ -71,7 +71,7 @@ namespace YooAsset
{ {
if (_downloader2 == null) if (_downloader2 == null)
{ {
string savePath = PersistentTools.GetCacheManifestFilePath(_packageName, _packageVersion); string savePath = PersistentTools.GetPersistent(_packageName).GetSandboxPackageManifestFilePath(_packageVersion);
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_packageName, _packageVersion); string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_packageName, _packageVersion);
string webURL = GetDownloadRequestURL(fileName); string webURL = GetDownloadRequestURL(fileName);
YooLogger.Log($"Beginning to download manifest file : {webURL}"); YooLogger.Log($"Beginning to download manifest file : {webURL}");

View File

@ -41,8 +41,7 @@ namespace YooAsset
{ {
if (_downloader == null) if (_downloader == null)
{ {
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_buildinPackageName, _buildinPackageVersion); string filePath = PersistentTools.GetPersistent(_buildinPackageName).GetBuildinPackageManifestFilePath(_buildinPackageVersion);
string filePath = PersistentTools.MakeStreamingLoadPath(fileName);
string url = PersistentTools.ConvertToWWWPath(filePath); string url = PersistentTools.ConvertToWWWPath(filePath);
_downloader = new UnityWebDataRequester(); _downloader = new UnityWebDataRequester();
_downloader.SendRequest(url); _downloader.SendRequest(url);

View File

@ -67,7 +67,7 @@ namespace YooAsset
if (_steps == ESteps.VerifyFileHash) if (_steps == ESteps.VerifyFileHash)
{ {
_manifestFilePath = PersistentTools.GetCacheManifestFilePath(_packageName, _packageVersion); _manifestFilePath = PersistentTools.GetPersistent(_packageName).GetSandboxPackageManifestFilePath(_packageVersion);
if (File.Exists(_manifestFilePath) == false) if (File.Exists(_manifestFilePath) == false)
{ {
_steps = ESteps.Done; _steps = ESteps.Done;
@ -131,7 +131,7 @@ namespace YooAsset
File.Delete(_manifestFilePath); File.Delete(_manifestFilePath);
} }
string hashFilePath = PersistentTools.GetCachePackageHashFilePath(_packageName, _packageVersion); string hashFilePath = PersistentTools.GetPersistent(_packageName).GetSandboxPackageHashFilePath(_packageVersion);
if (File.Exists(hashFilePath)) if (File.Exists(hashFilePath))
{ {
File.Delete(hashFilePath); File.Delete(hashFilePath);

View File

@ -37,8 +37,7 @@ namespace YooAsset
{ {
if (_downloader == null) if (_downloader == null)
{ {
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_packageName); string filePath = PersistentTools.GetPersistent(_packageName).GetBuildinPackageVersionFilePath();
string filePath = PersistentTools.MakeStreamingLoadPath(fileName);
string url = PersistentTools.ConvertToWWWPath(filePath); string url = PersistentTools.ConvertToWWWPath(filePath);
_downloader = new UnityWebDataRequester(); _downloader = new UnityWebDataRequester();
_downloader.SendRequest(url); _downloader.SendRequest(url);

View File

@ -37,7 +37,7 @@ namespace YooAsset
if (_steps == ESteps.LoadCachePackageHashFile) if (_steps == ESteps.LoadCachePackageHashFile)
{ {
string filePath = PersistentTools.GetCachePackageHashFilePath(_packageName, _packageVersion); string filePath = PersistentTools.GetPersistent(_packageName).GetSandboxPackageHashFilePath(_packageVersion);
if (File.Exists(filePath) == false) if (File.Exists(filePath) == false)
{ {
_steps = ESteps.Done; _steps = ESteps.Done;

View File

@ -35,7 +35,7 @@ namespace YooAsset
if (_steps == ESteps.LoadCachePackageVersionFile) if (_steps == ESteps.LoadCachePackageVersionFile)
{ {
string filePath = PersistentTools.GetCachePackageVersionFilePath(_packageName); string filePath = PersistentTools.GetPersistent(_packageName).GetSandboxPackageVersionFilePath();
if (File.Exists(filePath) == false) if (File.Exists(filePath) == false)
{ {
_steps = ESteps.Done; _steps = ESteps.Done;

View File

@ -31,13 +31,13 @@ namespace YooAsset
if (_steps == ESteps.None || _steps == ESteps.Done) if (_steps == ESteps.None || _steps == ESteps.Done)
return; return;
if(_steps == ESteps.UnpackManifestHashFile) if (_steps == ESteps.UnpackManifestHashFile)
{ {
if (_downloader1 == null) if (_downloader1 == null)
{ {
string savePath = PersistentTools.GetCachePackageHashFilePath(_buildinPackageName, _buildinPackageVersion); var persistent = PersistentTools.GetPersistent(_buildinPackageName);
string fileName = YooAssetSettingsData.GetPackageHashFileName(_buildinPackageName, _buildinPackageVersion); string savePath = persistent.GetSandboxPackageHashFilePath(_buildinPackageVersion);
string filePath = PersistentTools.MakeStreamingLoadPath(fileName); string filePath = persistent.GetBuildinPackageHashFilePath(_buildinPackageVersion);
string url = PersistentTools.ConvertToWWWPath(filePath); string url = PersistentTools.ConvertToWWWPath(filePath);
_downloader1 = new UnityWebFileRequester(); _downloader1 = new UnityWebFileRequester();
_downloader1.SendRequest(url, savePath); _downloader1.SendRequest(url, savePath);
@ -64,9 +64,9 @@ namespace YooAsset
{ {
if (_downloader2 == null) if (_downloader2 == null)
{ {
string savePath = PersistentTools.GetCacheManifestFilePath(_buildinPackageName, _buildinPackageVersion); var persistent = PersistentTools.GetPersistent(_buildinPackageName);
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_buildinPackageName, _buildinPackageVersion); string savePath = persistent.GetSandboxPackageManifestFilePath(_buildinPackageVersion);
string filePath = PersistentTools.MakeStreamingLoadPath(fileName); string filePath = persistent.GetBuildinPackageManifestFilePath(_buildinPackageVersion);
string url = PersistentTools.ConvertToWWWPath(filePath); string url = PersistentTools.ConvertToWWWPath(filePath);
_downloader2 = new UnityWebFileRequester(); _downloader2 = new UnityWebFileRequester();
_downloader2.SendRequest(url, savePath); _downloader2.SendRequest(url, savePath);

View File

@ -16,6 +16,11 @@ namespace YooAsset
/// </summary> /// </summary>
public string AssetPath; public string AssetPath;
/// <summary>
/// 资源GUID
/// </summary>
public string AssetGUID;
/// <summary> /// <summary>
/// 资源的分类标签 /// 资源的分类标签
/// </summary> /// </summary>

View File

@ -74,13 +74,13 @@ namespace YooAsset
string folderName = FileHash.Substring(0, 2); string folderName = FileHash.Substring(0, 2);
if (IsRawFile) if (IsRawFile)
{ {
string cacheRoot = PersistentTools.GetCachedRawFileFolderPath(PackageName); string cacheRoot = PersistentTools.GetPersistent(PackageName).SandboxCacheRawFilesRoot;
_cachedDataFilePath = PathUtility.Combine(cacheRoot, folderName, CacheGUID, YooAssetSettings.CacheBundleDataFileName); _cachedDataFilePath = PathUtility.Combine(cacheRoot, folderName, CacheGUID, YooAssetSettings.CacheBundleDataFileName);
_cachedDataFilePath += _fileExtension; _cachedDataFilePath += _fileExtension;
} }
else else
{ {
string cacheRoot = PersistentTools.GetCachedBundleFileFolderPath(PackageName); string cacheRoot = PersistentTools.GetPersistent(PackageName).SandboxCacheBundleFilesRoot;
_cachedDataFilePath = PathUtility.Combine(cacheRoot, folderName, CacheGUID, YooAssetSettings.CacheBundleDataFileName); _cachedDataFilePath = PathUtility.Combine(cacheRoot, folderName, CacheGUID, YooAssetSettings.CacheBundleDataFileName);
} }
return _cachedDataFilePath; return _cachedDataFilePath;
@ -101,12 +101,12 @@ namespace YooAsset
string folderName = FileHash.Substring(0, 2); string folderName = FileHash.Substring(0, 2);
if (IsRawFile) if (IsRawFile)
{ {
string cacheRoot = PersistentTools.GetCachedRawFileFolderPath(PackageName); string cacheRoot = PersistentTools.GetPersistent(PackageName).SandboxCacheRawFilesRoot;
_cachedInfoFilePath = PathUtility.Combine(cacheRoot, folderName, CacheGUID, YooAssetSettings.CacheBundleInfoFileName); _cachedInfoFilePath = PathUtility.Combine(cacheRoot, folderName, CacheGUID, YooAssetSettings.CacheBundleInfoFileName);
} }
else else
{ {
string cacheRoot = PersistentTools.GetCachedBundleFileFolderPath(PackageName); string cacheRoot = PersistentTools.GetPersistent(PackageName).SandboxCacheBundleFilesRoot;
_cachedInfoFilePath = PathUtility.Combine(cacheRoot, folderName, CacheGUID, YooAssetSettings.CacheBundleInfoFileName); _cachedInfoFilePath = PathUtility.Combine(cacheRoot, folderName, CacheGUID, YooAssetSettings.CacheBundleInfoFileName);
} }
return _cachedInfoFilePath; return _cachedInfoFilePath;
@ -140,7 +140,8 @@ namespace YooAsset
if (string.IsNullOrEmpty(_streamingFilePath) == false) if (string.IsNullOrEmpty(_streamingFilePath) == false)
return _streamingFilePath; return _streamingFilePath;
_streamingFilePath = PersistentTools.MakeStreamingLoadPath(FileName); string root = PersistentTools.GetPersistent(PackageName).BuildinPackageRoot;
_streamingFilePath = PathUtility.Combine(root, FileName);
return _streamingFilePath; return _streamingFilePath;
} }
} }

View File

@ -22,6 +22,16 @@ namespace YooAsset
/// </summary> /// </summary>
public bool EnableAddressable; public bool EnableAddressable;
/// <summary>
/// 资源定位地址大小写不敏感
/// </summary>
public bool LocationToLower;
/// <summary>
/// 包含资源GUID数据
/// </summary>
public bool IncludeAssetGUID;
/// <summary> /// <summary>
/// 文件名称样式 /// 文件名称样式
/// </summary> /// </summary>
@ -61,93 +71,17 @@ namespace YooAsset
public Dictionary<string, PackageAsset> AssetDic; public Dictionary<string, PackageAsset> AssetDic;
/// <summary> /// <summary>
/// 资源路径映射集合 /// 资源路径映射集合提供Location获取AssetPath
/// </summary> /// </summary>
[NonSerialized] [NonSerialized]
public Dictionary<string, string> AssetPathMapping; public Dictionary<string, string> AssetPathMapping1;
// 资源路径映射相关
private bool _isInitAssetPathMapping = false;
private bool _locationToLower = false;
/// <summary> /// <summary>
/// 初始化资源路径映射 /// 资源路径映射集合提供AssetGUID获取AssetPath
/// </summary> /// </summary>
public void InitAssetPathMapping(bool locationToLower) [NonSerialized]
{ public Dictionary<string, string> AssetPathMapping2;
if (_isInitAssetPathMapping)
return;
_isInitAssetPathMapping = true;
if (EnableAddressable)
{
if (locationToLower)
YooLogger.Error("Addressable not support location to lower !");
AssetPathMapping = new Dictionary<string, string>(AssetList.Count);
foreach (var packageAsset in AssetList)
{
string location = packageAsset.Address;
if (AssetPathMapping.ContainsKey(location))
throw new Exception($"Address have existed : {location}");
else
AssetPathMapping.Add(location, packageAsset.AssetPath);
}
}
else
{
_locationToLower = locationToLower;
AssetPathMapping = new Dictionary<string, string>(AssetList.Count * 2);
foreach (var packageAsset in AssetList)
{
string location = packageAsset.AssetPath;
if (locationToLower)
location = location.ToLower();
// 添加原生路径的映射
if (AssetPathMapping.ContainsKey(location))
throw new Exception($"AssetPath have existed : {location}");
else
AssetPathMapping.Add(location, packageAsset.AssetPath);
// 添加无后缀名路径的映射
if (Path.HasExtension(location))
{
string locationWithoutExtension = PathUtility.RemoveExtension(location);
if (AssetPathMapping.ContainsKey(locationWithoutExtension))
YooLogger.Warning($"AssetPath have existed : {locationWithoutExtension}");
else
AssetPathMapping.Add(locationWithoutExtension, packageAsset.AssetPath);
}
}
}
}
/// <summary>
/// 映射为资源路径
/// </summary>
public string MappingToAssetPath(string location)
{
if (string.IsNullOrEmpty(location))
{
YooLogger.Error("Failed to mapping location to asset path, The location is null or empty.");
return string.Empty;
}
if (_locationToLower)
location = location.ToLower();
if (AssetPathMapping.TryGetValue(location, out string assetPath))
{
return assetPath;
}
else
{
YooLogger.Warning($"Failed to mapping location to asset path : {location}");
return string.Empty;
}
}
/// <summary> /// <summary>
/// 尝试映射为资源路径 /// 尝试映射为资源路径
@ -157,10 +91,10 @@ namespace YooAsset
if (string.IsNullOrEmpty(location)) if (string.IsNullOrEmpty(location))
return string.Empty; return string.Empty;
if (_locationToLower) if (LocationToLower)
location = location.ToLower(); location = location.ToLower();
if (AssetPathMapping.TryGetValue(location, out string assetPath)) if (AssetPathMapping1.TryGetValue(location, out string assetPath))
return assetPath; return assetPath;
else else
return string.Empty; return string.Empty;
@ -283,14 +217,14 @@ namespace YooAsset
} }
/// <summary> /// <summary>
/// 资源定位地址转换为资源信息类,失败时内部会发出错误日志 /// 资源定位地址转换为资源信息
/// </summary> /// </summary>
/// <returns>如果转换失败会返回一个无效的资源信息类</returns> /// <returns>如果转换失败会返回一个无效的资源信息类</returns>
public AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType) public AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType)
{ {
DebugCheckLocation(location); DebugCheckLocation(location);
string assetPath = MappingToAssetPath(location); string assetPath = ConvertLocationToAssetInfoMapping(location);
if (TryGetPackageAsset(assetPath, out PackageAsset packageAsset)) if (TryGetPackageAsset(assetPath, out PackageAsset packageAsset))
{ {
AssetInfo assetInfo = new AssetInfo(packageAsset, assetType); AssetInfo assetInfo = new AssetInfo(packageAsset, assetType);
@ -307,6 +241,95 @@ namespace YooAsset
return assetInfo; return assetInfo;
} }
} }
private string ConvertLocationToAssetInfoMapping(string location)
{
if (string.IsNullOrEmpty(location))
{
YooLogger.Error("Failed to mapping location to asset path, The location is null or empty.");
return string.Empty;
}
if (LocationToLower)
location = location.ToLower();
if (AssetPathMapping1.TryGetValue(location, out string assetPath))
{
return assetPath;
}
else
{
YooLogger.Warning($"Failed to mapping location to asset path : {location}");
return string.Empty;
}
}
/// <summary>
/// 资源GUID转换为资源信息。
/// </summary>
/// <returns>如果转换失败会返回一个无效的资源信息类</returns>
public AssetInfo ConvertAssetGUIDToAssetInfo(string assetGUID, System.Type assetType)
{
if (IncludeAssetGUID == false)
{
YooLogger.Warning("Package manifest not include asset guid ! Please check asset bundle collector settings.");
AssetInfo assetInfo = new AssetInfo("AssetGUID data is empty !");
return assetInfo;
}
string assetPath = ConvertAssetGUIDToAssetInfoMapping(assetGUID);
if (TryGetPackageAsset(assetPath, out PackageAsset packageAsset))
{
AssetInfo assetInfo = new AssetInfo(packageAsset, assetType);
return assetInfo;
}
else
{
string error;
if (string.IsNullOrEmpty(assetGUID))
error = $"The assetGUID is null or empty !";
else
error = $"The assetGUID is invalid : {assetGUID}";
AssetInfo assetInfo = new AssetInfo(error);
return assetInfo;
}
}
private string ConvertAssetGUIDToAssetInfoMapping(string assetGUID)
{
if (string.IsNullOrEmpty(assetGUID))
{
YooLogger.Error("Failed to mapping assetGUID to asset path, The assetGUID is null or empty.");
return string.Empty;
}
if (AssetPathMapping2.TryGetValue(assetGUID, out string assetPath))
{
return assetPath;
}
else
{
YooLogger.Warning($"Failed to mapping assetGUID to asset path : {assetGUID}");
return string.Empty;
}
}
/// <summary>
/// 获取资源包内的主资源列表
/// </summary>
public string[] GetBundleIncludeAssets(string assetPath)
{
List<string> assetList = new List<string>();
if (TryGetPackageAsset(assetPath, out PackageAsset result))
{
foreach (var packageAsset in AssetList)
{
if (packageAsset.BundleID == result.BundleID)
{
assetList.Add(packageAsset.AssetPath);
}
}
}
return assetList.ToArray();
}
#region 调试方法 #region 调试方法
[Conditional("DEBUG")] [Conditional("DEBUG")]

View File

@ -7,14 +7,12 @@ namespace YooAsset
internal class EditorSimulateModeImpl : IPlayModeServices, IBundleServices internal class EditorSimulateModeImpl : IPlayModeServices, IBundleServices
{ {
private PackageManifest _activeManifest; private PackageManifest _activeManifest;
private bool _locationToLower;
/// <summary> /// <summary>
/// 异步初始化 /// 异步初始化
/// </summary> /// </summary>
public InitializationOperation InitializeAsync(bool locationToLower, string simulateManifestFilePath) public InitializationOperation InitializeAsync(string simulateManifestFilePath)
{ {
_locationToLower = locationToLower;
var operation = new EditorSimulateModeInitializationOperation(this, simulateManifestFilePath); var operation = new EditorSimulateModeInitializationOperation(this, simulateManifestFilePath);
OperationSystem.StartOperation(operation); OperationSystem.StartOperation(operation);
return operation; return operation;
@ -26,14 +24,13 @@ namespace YooAsset
set set
{ {
_activeManifest = value; _activeManifest = value;
_activeManifest.InitAssetPathMapping(_locationToLower);
} }
get get
{ {
return _activeManifest; return _activeManifest;
} }
} }
public void FlushManifestVersionFile() public void FlushManifestVersionFile()
{ {
} }
@ -55,7 +52,7 @@ namespace YooAsset
OperationSystem.StartOperation(operation); OperationSystem.StartOperation(operation);
return operation; return operation;
} }
ResourceDownloaderOperation IPlayModeServices.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout) ResourceDownloaderOperation IPlayModeServices.CreateResourceDownloaderByAll(int downloadingMaxNumber, int failedTryAgain, int timeout)
{ {
return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout); return ResourceDownloaderOperation.CreateEmptyDownloader(downloadingMaxNumber, failedTryAgain, timeout);
@ -85,7 +82,8 @@ namespace YooAsset
if (packageBundle == null) if (packageBundle == null)
throw new Exception("Should never get here !"); throw new Exception("Should never get here !");
BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromEditor, assetInfo.AssetPath); BundleInfo bundleInfo = new BundleInfo(packageBundle, BundleInfo.ELoadMode.LoadFromEditor);
bundleInfo.IncludeAssets = _activeManifest.GetBundleIncludeAssets(assetInfo.AssetPath);
return bundleInfo; return bundleInfo;
} }
BundleInfo IBundleServices.GetBundleInfo(AssetInfo assetInfo) BundleInfo IBundleServices.GetBundleInfo(AssetInfo assetInfo)

View File

@ -10,7 +10,6 @@ namespace YooAsset
// 参数相关 // 参数相关
private string _packageName; private string _packageName;
private bool _locationToLower;
private string _defaultHostServer; private string _defaultHostServer;
private string _fallbackHostServer; private string _fallbackHostServer;
private IQueryServices _queryServices; private IQueryServices _queryServices;
@ -18,10 +17,9 @@ namespace YooAsset
/// <summary> /// <summary>
/// 异步初始化 /// 异步初始化
/// </summary> /// </summary>
public InitializationOperation InitializeAsync(string packageName, bool locationToLower, string defaultHostServer, string fallbackHostServer, IQueryServices queryServices) public InitializationOperation InitializeAsync(string packageName, string defaultHostServer, string fallbackHostServer, IQueryServices queryServices)
{ {
_packageName = packageName; _packageName = packageName;
_locationToLower = locationToLower;
_defaultHostServer = defaultHostServer; _defaultHostServer = defaultHostServer;
_fallbackHostServer = fallbackHostServer; _fallbackHostServer = fallbackHostServer;
_queryServices = queryServices; _queryServices = queryServices;
@ -50,22 +48,6 @@ namespace YooAsset
return bundleInfo; return bundleInfo;
} }
// 解压相关
private List<BundleInfo> ConvertToUnpackList(List<PackageBundle> unpackList)
{
List<BundleInfo> result = new List<BundleInfo>(unpackList.Count);
foreach (var packageBundle in unpackList)
{
var bundleInfo = ConvertToUnpackInfo(packageBundle);
result.Add(bundleInfo);
}
return result;
}
private BundleInfo ConvertToUnpackInfo(PackageBundle packageBundle)
{
return ManifestTools.GetUnpackInfo(packageBundle);
}
#region IRemoteServices接口 #region IRemoteServices接口
public string GetRemoteMainURL(string fileName) public string GetRemoteMainURL(string fileName)
{ {
@ -83,7 +65,6 @@ namespace YooAsset
set set
{ {
_activeManifest = value; _activeManifest = value;
_activeManifest.InitAssetPathMapping(_locationToLower);
} }
get get
{ {
@ -93,12 +74,14 @@ namespace YooAsset
public void FlushManifestVersionFile() public void FlushManifestVersionFile()
{ {
if (_activeManifest != null) if (_activeManifest != null)
PersistentTools.SaveCachePackageVersionFile(_packageName, _activeManifest.PackageVersion); {
PersistentTools.GetPersistent(_packageName).SaveSandboxPackageVersionFile(_activeManifest.PackageVersion);
}
} }
private bool IsBuildinPackageBundle(PackageBundle packageBundle) private bool IsBuildinPackageBundle(PackageBundle packageBundle)
{ {
return _queryServices.QueryStreamingAssets(packageBundle.FileName); return _queryServices.QueryStreamingAssets(_packageName, packageBundle.FileName);
} }
private bool IsCachedPackageBundle(PackageBundle packageBundle) private bool IsCachedPackageBundle(PackageBundle packageBundle)
{ {
@ -256,7 +239,7 @@ namespace YooAsset
} }
} }
return ConvertToUnpackList(downloadList); return ManifestTools.ConvertToUnpackInfos(downloadList);
} }
ResourceUnpackerOperation IPlayModeServices.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) ResourceUnpackerOperation IPlayModeServices.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout)
@ -284,7 +267,7 @@ namespace YooAsset
} }
} }
return ConvertToUnpackList(downloadList); return ManifestTools.ConvertToUnpackInfos(downloadList);
} }
#endregion #endregion

View File

@ -7,14 +7,12 @@ namespace YooAsset
internal class OfflinePlayModeImpl : IPlayModeServices, IBundleServices internal class OfflinePlayModeImpl : IPlayModeServices, IBundleServices
{ {
private PackageManifest _activeManifest; private PackageManifest _activeManifest;
private bool _locationToLower;
/// <summary> /// <summary>
/// 异步初始化 /// 异步初始化
/// </summary> /// </summary>
public InitializationOperation InitializeAsync(string packageName, bool locationToLower) public InitializationOperation InitializeAsync(string packageName)
{ {
_locationToLower = locationToLower;
var operation = new OfflinePlayModeInitializationOperation(this, packageName); var operation = new OfflinePlayModeInitializationOperation(this, packageName);
OperationSystem.StartOperation(operation); OperationSystem.StartOperation(operation);
return operation; return operation;
@ -26,7 +24,6 @@ namespace YooAsset
set set
{ {
_activeManifest = value; _activeManifest = value;
_activeManifest.InitAssetPathMapping(_locationToLower);
} }
get get
{ {
@ -37,6 +34,11 @@ namespace YooAsset
{ {
} }
private bool IsCachedPackageBundle(PackageBundle packageBundle)
{
return CacheSystem.IsCached(packageBundle.PackageName, packageBundle.CacheGUID);
}
UpdatePackageVersionOperation IPlayModeServices.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout) UpdatePackageVersionOperation IPlayModeServices.UpdatePackageVersionAsync(bool appendTimeTicks, int timeout)
{ {
var operation = new OfflinePlayModeUpdatePackageVersionOperation(); var operation = new OfflinePlayModeUpdatePackageVersionOperation();
@ -71,11 +73,48 @@ namespace YooAsset
ResourceUnpackerOperation IPlayModeServices.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout) ResourceUnpackerOperation IPlayModeServices.CreateResourceUnpackerByAll(int upackingMaxNumber, int failedTryAgain, int timeout)
{ {
return ResourceUnpackerOperation.CreateEmptyUnpacker(upackingMaxNumber, failedTryAgain, timeout); List<BundleInfo> unpcakList = GetUnpackListByAll(_activeManifest);
var operation = new ResourceUnpackerOperation(unpcakList, upackingMaxNumber, failedTryAgain, timeout);
return operation;
} }
private List<BundleInfo> GetUnpackListByAll(PackageManifest manifest)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
downloadList.Add(packageBundle);
}
return ManifestTools.ConvertToUnpackInfos(downloadList);
}
ResourceUnpackerOperation IPlayModeServices.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout) ResourceUnpackerOperation IPlayModeServices.CreateResourceUnpackerByTags(string[] tags, int upackingMaxNumber, int failedTryAgain, int timeout)
{ {
return ResourceUnpackerOperation.CreateEmptyUnpacker(upackingMaxNumber, failedTryAgain, timeout); List<BundleInfo> unpcakList = GetUnpackListByTags(_activeManifest, tags);
var operation = new ResourceUnpackerOperation(unpcakList, upackingMaxNumber, failedTryAgain, timeout);
return operation;
}
private List<BundleInfo> GetUnpackListByTags(PackageManifest manifest, string[] tags)
{
List<PackageBundle> downloadList = new List<PackageBundle>(1000);
foreach (var packageBundle in manifest.BundleList)
{
// 忽略缓存文件
if (IsCachedPackageBundle(packageBundle))
continue;
// 查询DLC资源
if (packageBundle.HasTag(tags))
{
downloadList.Add(packageBundle);
}
}
return ManifestTools.ConvertToUnpackInfos(downloadList);
} }
#endregion #endregion

View File

@ -79,6 +79,10 @@ namespace YooAsset
// 检测初始化参数合法性 // 检测初始化参数合法性
CheckInitializeParameters(parameters); CheckInitializeParameters(parameters);
// 重写持久化根目录
var persistent = PersistentTools.GetOrCreatePersistent(PackageName);
persistent.OverwriteRootDirectory(parameters.BuildinRootDirectory, parameters.SandboxRootDirectory);
// 初始化资源系统 // 初始化资源系统
InitializationOperation initializeOperation; InitializationOperation initializeOperation;
_assetSystemImpl = new AssetSystemImpl(); _assetSystemImpl = new AssetSystemImpl();
@ -92,7 +96,7 @@ namespace YooAsset
parameters.DecryptionServices, _bundleServices); parameters.DecryptionServices, _bundleServices);
var initializeParameters = parameters as EditorSimulateModeParameters; var initializeParameters = parameters as EditorSimulateModeParameters;
initializeOperation = editorSimulateModeImpl.InitializeAsync(initializeParameters.LocationToLower, initializeParameters.SimulateManifestFilePath); initializeOperation = editorSimulateModeImpl.InitializeAsync(initializeParameters.SimulateManifestFilePath);
} }
else if (_playMode == EPlayMode.OfflinePlayMode) else if (_playMode == EPlayMode.OfflinePlayMode)
{ {
@ -104,7 +108,7 @@ namespace YooAsset
parameters.DecryptionServices, _bundleServices); parameters.DecryptionServices, _bundleServices);
var initializeParameters = parameters as OfflinePlayModeParameters; var initializeParameters = parameters as OfflinePlayModeParameters;
initializeOperation = offlinePlayModeImpl.InitializeAsync(PackageName, initializeParameters.LocationToLower); initializeOperation = offlinePlayModeImpl.InitializeAsync(PackageName);
} }
else if (_playMode == EPlayMode.HostPlayMode) else if (_playMode == EPlayMode.HostPlayMode)
{ {
@ -118,7 +122,6 @@ namespace YooAsset
var initializeParameters = parameters as HostPlayModeParameters; var initializeParameters = parameters as HostPlayModeParameters;
initializeOperation = hostPlayModeImpl.InitializeAsync( initializeOperation = hostPlayModeImpl.InitializeAsync(
PackageName, PackageName,
initializeParameters.LocationToLower,
initializeParameters.DefaultHostServer, initializeParameters.DefaultHostServer,
initializeParameters.FallbackHostServer, initializeParameters.FallbackHostServer,
initializeParameters.QueryServices initializeParameters.QueryServices
@ -292,6 +295,37 @@ namespace YooAsset
_assetSystemImpl.ForceUnloadAllAssets(); _assetSystemImpl.ForceUnloadAllAssets();
} }
#region 沙盒相关
/// <summary>
/// 获取包裹的内置文件根路径
/// </summary>
public string GetPackageBuildinRootDirectory()
{
DebugCheckInitialize();
var persistent = PersistentTools.GetPersistent(PackageName);
return persistent.BuildinRoot;
}
/// <summary>
/// 获取包裹的沙盒文件根路径
/// </summary>
public string GetPackageSandboxRootDirectory()
{
DebugCheckInitialize();
var persistent = PersistentTools.GetPersistent(PackageName);
return persistent.SandboxRoot;
}
/// <summary>
/// 清空包裹的沙盒目录
/// </summary>
public void ClearPackageSandbox()
{
DebugCheckInitialize();
var persistent = PersistentTools.GetPersistent(PackageName);
persistent.DeleteSandboxPackageFolder();
}
#endregion
#region 资源信息 #region 资源信息
/// <summary> /// <summary>
@ -363,8 +397,17 @@ namespace YooAsset
public AssetInfo GetAssetInfo(string location) public AssetInfo GetAssetInfo(string location)
{ {
DebugCheckInitialize(); DebugCheckInitialize();
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null); return ConvertLocationToAssetInfo(location, null);
return assetInfo; }
/// <summary>
/// 获取资源信息
/// </summary>
/// <param name="assetGUID">资源GUID</param>
public AssetInfo GetAssetInfoByGUID(string assetGUID)
{
DebugCheckInitialize();
return ConvertAssetGUIDToAssetInfo(assetGUID, null);
} }
/// <summary> /// <summary>
@ -447,13 +490,13 @@ namespace YooAsset
/// </summary> /// </summary>
/// <param name="location">场景的定位地址</param> /// <param name="location">场景的定位地址</param>
/// <param name="sceneMode">场景加载模式</param> /// <param name="sceneMode">场景加载模式</param>
/// <param name="activateOnLoad">加载完毕时是否主动激活</param> /// <param name="suspendLoad">场景加载到90%自动挂起</param>
/// <param name="priority">优先级</param> /// <param name="priority">优先级</param>
public SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100) public SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100)
{ {
DebugCheckInitialize(); DebugCheckInitialize();
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null); AssetInfo assetInfo = ConvertLocationToAssetInfo(location, null);
var handle = _assetSystemImpl.LoadSceneAsync(assetInfo, sceneMode, activateOnLoad, priority); var handle = _assetSystemImpl.LoadSceneAsync(assetInfo, sceneMode, suspendLoad, priority);
return handle; return handle;
} }
@ -462,12 +505,12 @@ namespace YooAsset
/// </summary> /// </summary>
/// <param name="assetInfo">场景的资源信息</param> /// <param name="assetInfo">场景的资源信息</param>
/// <param name="sceneMode">场景加载模式</param> /// <param name="sceneMode">场景加载模式</param>
/// <param name="activateOnLoad">加载完毕时是否主动激活</param> /// <param name="suspendLoad">场景加载到90%自动挂起</param>
/// <param name="priority">优先级</param> /// <param name="priority">优先级</param>
public SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100) public SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, bool suspendLoad = false, int priority = 100)
{ {
DebugCheckInitialize(); DebugCheckInitialize();
var handle = _assetSystemImpl.LoadSceneAsync(assetInfo, sceneMode, activateOnLoad, priority); var handle = _assetSystemImpl.LoadSceneAsync(assetInfo, sceneMode, suspendLoad, priority);
return handle; return handle;
} }
#endregion #endregion
@ -650,6 +693,95 @@ namespace YooAsset
} }
#endregion #endregion
#region 资源加载
/// <summary>
/// 同步加载资源包内所有资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public AllAssetsOperationHandle LoadAllAssetsSync(AssetInfo assetInfo)
{
DebugCheckInitialize();
return LoadAllAssetsInternal(assetInfo, true);
}
/// <summary>
/// 同步加载资源包内所有资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public AllAssetsOperationHandle LoadAllAssetsSync<TObject>(string location) where TObject : UnityEngine.Object
{
DebugCheckInitialize();
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
return LoadAllAssetsInternal(assetInfo, true);
}
/// <summary>
/// 同步加载资源包内所有资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">子对象类型</param>
public AllAssetsOperationHandle LoadAllAssetsSync(string location, System.Type type)
{
DebugCheckInitialize();
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
return LoadAllAssetsInternal(assetInfo, true);
}
/// <summary>
/// 异步加载资源包内所有资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public AllAssetsOperationHandle LoadAllAssetsAsync(AssetInfo assetInfo)
{
DebugCheckInitialize();
return LoadAllAssetsInternal(assetInfo, false);
}
/// <summary>
/// 异步加载资源包内所有资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public AllAssetsOperationHandle LoadAllAssetsAsync<TObject>(string location) where TObject : UnityEngine.Object
{
DebugCheckInitialize();
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, typeof(TObject));
return LoadAllAssetsInternal(assetInfo, false);
}
/// <summary>
/// 异步加载资源包内所有资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">子对象类型</param>
public AllAssetsOperationHandle LoadAllAssetsAsync(string location, System.Type type)
{
DebugCheckInitialize();
AssetInfo assetInfo = ConvertLocationToAssetInfo(location, type);
return LoadAllAssetsInternal(assetInfo, false);
}
private AllAssetsOperationHandle LoadAllAssetsInternal(AssetInfo assetInfo, bool waitForAsyncComplete)
{
#if UNITY_EDITOR
if (assetInfo.IsInvalid == false)
{
BundleInfo bundleInfo = _bundleServices.GetBundleInfo(assetInfo);
if (bundleInfo.Bundle.IsRawFile)
throw new Exception($"Cannot load raw file using {nameof(LoadAllAssetsAsync)} method !");
}
#endif
var handle = _assetSystemImpl.LoadAllAssetsAsync(assetInfo);
if (waitForAsyncComplete)
handle.WaitForAsyncComplete();
return handle;
}
#endregion
#region 资源下载 #region 资源下载
/// <summary> /// <summary>
/// 创建资源下载器,用于下载当前资源版本所有的资源包文件 /// 创建资源下载器,用于下载当前资源版本所有的资源包文件
@ -800,13 +932,14 @@ namespace YooAsset
return _playModeServices.ActiveManifest.IsIncludeBundleFile(cacheGUID); return _playModeServices.ActiveManifest.IsIncludeBundleFile(cacheGUID);
} }
/// <summary>
/// 资源定位地址转换为资源信息类
/// </summary>
private AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType) private AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType)
{ {
return _playModeServices.ActiveManifest.ConvertLocationToAssetInfo(location, assetType); return _playModeServices.ActiveManifest.ConvertLocationToAssetInfo(location, assetType);
} }
private AssetInfo ConvertAssetGUIDToAssetInfo(string assetGUID, System.Type assetType)
{
return _playModeServices.ActiveManifest.ConvertAssetGUIDToAssetInfo(assetGUID, assetType);
}
#endregion #endregion
#region 调试方法 #region 调试方法

View File

@ -6,6 +6,6 @@ namespace YooAsset
/// <summary> /// <summary>
/// 查询内置资源 /// 查询内置资源
/// </summary> /// </summary>
bool QueryStreamingAssets(string fileName); bool QueryStreamingAssets(string packageName, string fileName);
} }
} }

View File

@ -24,7 +24,7 @@ namespace YooAsset
/// <summary> /// <summary>
/// 清单文件格式版本 /// 清单文件格式版本
/// </summary> /// </summary>
public const string ManifestFileVersion = "1.4.6"; public const string ManifestFileVersion = "1.4.17";
/// <summary> /// <summary>
@ -37,6 +37,31 @@ namespace YooAsset
/// </summary> /// </summary>
public const string CacheBundleInfoFileName = "__info"; public const string CacheBundleInfoFileName = "__info";
/// <summary>
/// 默认的YooAsset文件夹名称
/// </summary>
public const string DefaultYooFolderName = "yoo";
/// <summary>
/// 缓存的资源文件的文件夹名称
/// </summary>
public const string CachedBundleFileFolder = "CacheBundleFiles";
/// <summary>
/// 缓存的原生文件的文件夹名称
/// </summary>
public const string CachedRawFileFolder = "CacheRawFiles";
/// <summary>
/// 缓存的清单文件的文件夹名称
/// </summary>
public const string ManifestFolderName = "ManifestFiles";
/// <summary>
/// 记录应用程序版本的文件名称
/// </summary>
public const string AppFootPrintFileName = "ApplicationFootPrint.bytes";
/// <summary> /// <summary>
/// 构建输出文件夹名称 /// 构建输出文件夹名称
@ -47,10 +72,5 @@ namespace YooAsset
/// 构建输出的报告文件 /// 构建输出的报告文件
/// </summary> /// </summary>
public const string ReportFileName = "BuildReport"; public const string ReportFileName = "BuildReport";
/// <summary>
/// 内置资源目录名称
/// </summary>
public const string StreamingAssetsBuildinFolder = "BuildinFiles";
} }
} }

View File

@ -217,6 +217,21 @@ namespace YooAsset
DownloadSystem.RequestDelegate = requestDelegate; DownloadSystem.RequestDelegate = requestDelegate;
} }
/// <summary>
/// 设置下载系统参数网络重定向次数Unity引擎默认值32
/// 注意:不支持设置为负值
/// </summary>
public static void SetDownloadSystemRedirectLimit(int redirectLimit)
{
if (redirectLimit < 0)
{
YooLogger.Warning($"Invalid param value : {redirectLimit}");
return;
}
DownloadSystem.RedirectLimit = redirectLimit;
}
/// <summary> /// <summary>
/// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒) /// 设置异步系统参数,每帧执行消耗的最大时间切片(单位:毫秒)
/// </summary> /// </summary>
@ -239,51 +254,11 @@ namespace YooAsset
} }
/// <summary> /// <summary>
/// 设置缓存系统参数,沙盒目录的存储路径 /// 设置缓存系统参数,禁用缓存在WebGL平台
/// </summary> /// </summary>
public static void SetCacheSystemSandboxPath(string sandboxPath) public static void SetCacheSystemDisableCacheOnWebGL()
{ {
if (string.IsNullOrEmpty(sandboxPath)) CacheSystem.DisableUnityCacheOnWebGL = true;
{
YooLogger.Error($"Sandbox path is null or empty !");
return;
}
// 注意:需要确保没有任何资源系统起效之前才可以设置沙盒目录!
if (_packages.Count > 0)
{
YooLogger.Error($"Please call this method {nameof(SetCacheSystemSandboxPath)} before the package is created !");
return;
}
PersistentTools.OverwriteSandboxPath(sandboxPath);
}
#endregion
#region 沙盒相关
/// <summary>
/// 获取内置文件夹名称
/// </summary>
public static string GetStreamingAssetBuildinFolderName()
{
return YooAssetSettings.StreamingAssetsBuildinFolder;
}
/// <summary>
/// 获取沙盒的根路径
/// </summary>
public static string GetSandboxRoot()
{
return PersistentTools.GetPersistentRootPath();
}
/// <summary>
/// 清空沙盒目录需要重启APP
/// </summary>
public static void ClearSandbox()
{
YooLogger.Warning("Clear sandbox folder files, Finally, restart the application !");
PersistentTools.DeleteSandbox();
} }
#endregion #endregion

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