Compare commits

..

34 Commits

Author SHA1 Message Date
hevinci
f07cbcbb81 Update CHANGELOG.md 2022-10-08 14:56:00 +08:00
hevinci
9df32816a1 Update package.json 2022-10-08 14:55:47 +08:00
何冠峰
f7fd589b13 Merge pull request #40 from youigame/main
change sample path name
2022-10-08 14:36:09 +08:00
hevinci
852d031254 Update samples 2022-10-08 12:10:34 +08:00
hevinci
38c0ca0ce1 Update runtime code 2022-10-08 12:09:34 +08:00
hevinci
4eca73303b Update runtime code 2022-10-08 11:23:16 +08:00
hevinci
d5292f3fc3 Update runtime code 2022-09-29 18:43:13 +08:00
hevinci
6549fbb552 Update editor code 2022-09-29 18:40:51 +08:00
hevinci
a71921cdd1 Update runtime code 2022-09-29 18:40:43 +08:00
hevinci
46c219505f Update editor code 2022-09-29 15:06:03 +08:00
lark
0a129f9250 change sample path name 2022-09-28 22:13:21 +08:00
hevinci
4ece14e921 Update runtime code 2022-09-28 14:39:58 +08:00
hevinci
a4c8fb6e1b Update runtime logic 2022-09-28 11:55:12 +08:00
hevinci
c8d3f6efed Update editor logic 2022-09-28 11:46:23 +08:00
hevinci
fe47de01d3 Update samples 2022-09-27 21:32:37 +08:00
hevinci
84045b13c6 Update samples 2022-09-27 21:26:00 +08:00
hevinci
af37bb6e54 Update runtime logic 2022-09-27 21:11:55 +08:00
hevinci
e1801a5fba Update editor logic 2022-09-27 21:04:08 +08:00
hevinci
50bfde6e8e Update AssetBundleBuilder 2022-09-27 10:40:29 +08:00
hevinci
f0ac319a73 Update AssetBundleCollector
编辑器支持分布式构建
2022-09-27 10:38:35 +08:00
hevinci
39c277b090 Update CHANGELOG.md 2022-09-22 15:07:39 +08:00
hevinci
81e6aab53d Update package.json 2022-09-22 15:07:09 +08:00
hevinci
7c1e1ab593 Update Basic Sample 2022-09-22 14:29:24 +08:00
hevinci
2381b67312 Update BasicSamples 2022-09-22 14:18:54 +08:00
hevinci
ca83a4450d Update Basic Samples 2022-09-22 11:42:13 +08:00
hevinci
8cec0abf0e Update AssetBundleCollector
增加配置表自我修复功能。
2022-09-22 11:40:30 +08:00
hevinci
a89127df1d Update YooAssetDriver
在游戏对象销毁的时候释放YooAssets
2022-09-21 11:36:28 +08:00
hevinci
95924868f7 Update AssetBundleCollector
移除对Gizmos资源的打包限制。
2022-09-21 11:21:13 +08:00
hevinci
778b097f7a Update TaskCreateReport.cs 2022-09-21 11:20:41 +08:00
hevinci
3a7f3bb68d Update AssetBundleBuilder
修复在可编程构建管线下模拟构建模式报错。
2022-09-21 11:20:32 +08:00
hevinci
02b9b689b7 Update AssetBundleBuilder
可编程构建管线强制使用增量构建模式。
2022-09-21 11:18:38 +08:00
hevinci
3882fe9f3f Update Samples.md 2022-09-16 11:16:22 +08:00
hevinci
af29cb738d Update AssetBundleBuilder
对内置管线构建结果做容错处理
2022-09-14 17:36:41 +08:00
hevinci
4975d3b1ba Update AssetBundleBuilder
修复加密文件下载验证失败问题。
2022-09-13 11:48:57 +08:00
139 changed files with 5186 additions and 3704 deletions

View File

@@ -2,6 +2,62 @@
All notable changes to this package will be documented in this file.
## [1.3.0-preview] - 2022-10-08
该预览版本提供了分布式构建的功能,用于解决分工程或分内容构建的问题。
### Added
- 新增方法设置异步系统的每帧允许运行的最大时间切片。
```c#
/// <summary>
/// 设置异步系统的每帧允许运行的最大时间切片(单位:毫秒)
/// </summary>
public static void SetOperationSystemMaxTimeSlice(long milliseconds)
```
- 新增方法设置缓存系统的已经缓存文件的校验等级。
```c#
/// <summary>
/// 设置缓存系统的已经缓存文件的校验等级
/// </summary>
public static void SetCacheSystemCachedFileVerifyLevel(EVerifyLevel verifyLevel)
```
- 新增方法设置下载系统的断点续传功能的文件大小。
````C#
/// <summary>
/// 启用下载系统的断点续传功能的文件大小
/// </summary>
public static void SetDownloadSystemBreakpointResumeFileSize(int fileBytes)
````
### Removed
- 移除了资源版本号相关概念的代码。
- 移除了TaskCopyBuildinFiles节点在构建流程里。
- 移除了YooAssets.ClearUnusedCacheFiles()方法。
- 移除了初始化参数 InitializeParameters.ClearCacheOnDirty
- 移除了初始化参数 InitializeParameters.OperationSystemMaxTimeSlice
- 移除了初始化参数 InitializeParameters.BreakpointResumeFileSize
- 移除了初始化参数 InitializeParameters.VerifyLevel
## [1.2.4] - 2022-09-22
### Fixed
- 修复了加密文件下载验证失败的问题。
- 修复了可编程构建管线下模拟构建模式报错的问题。
### Changed
- 可编程构建管线强制使用增量构建模式。
- 移除了对Gizmos资源的打包限制。
- AssetBundleCollector窗口增加配置表修复功能。
## [1.2.3] - 2022-09-09
### Fixed

View File

@@ -20,13 +20,19 @@ namespace YooAsset.Editor
// 检测构建参数是否为空
if (buildParameters == null)
{
throw new Exception($"{nameof(buildParameters)} is null !");
}
// 检测可编程构建管线参数
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 !");
}
// 构建参数
@@ -53,7 +59,6 @@ namespace YooAsset.Editor
new TaskCreatePatchManifest(), //创建清单文件
new TaskCreateReport(), //创建报告文件
new TaskCreatePatchPackage(), //制作补丁包
new TaskCopyBuildinFiles(), //拷贝内置文件
};
}
else if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
@@ -68,7 +73,6 @@ namespace YooAsset.Editor
new TaskCreatePatchManifest(), //创建清单文件
new TaskCreateReport(), //创建报告文件
new TaskCreatePatchPackage(), //制作补丁包
new TaskCopyBuildinFiles(), //拷贝内置文件
};
}
else
@@ -80,7 +84,8 @@ namespace YooAsset.Editor
var buildResult = BuildRunner.Run(pipeline, _buildContext);
if (buildResult.Success)
{
buildResult.OutputPackageDirectory = buildParametersContext.GetPackageDirectory();
buildResult.OutputPackageCRC = buildParametersContext.OutputPackageCRC;
buildResult.OutputPackageDirectory = buildParametersContext.GetPackageOutputDirectory();
Debug.Log($"{buildParameters.BuildMode} pipeline build succeed !");
}
else

View File

@@ -25,14 +25,6 @@ namespace YooAsset.Editor
return $"{Application.dataPath}/StreamingAssets/YooAssets/";
}
/// <summary>
/// 获取构建管线的输出目录
/// </summary>
public static string MakePipelineOutputDirectory(string outputRoot, BuildTarget buildTarget)
{
return $"{outputRoot}/{buildTarget}/{YooAssetSettings.OutputFolderName}";
}
/// <summary>
/// 清空流文件夹
/// </summary>
@@ -67,61 +59,25 @@ namespace YooAsset.Editor
}
}
/// <summary>
/// 获取所有补丁包版本列表
/// 注意:列表会按照版本号从小到大排序
/// 获取构建管线的输出目录
/// </summary>
private static List<int> GetPackageVersionList(BuildTarget buildTarget, string outputRoot)
public static string MakePipelineOutputDirectory(string outputRoot, string buildPackage, BuildTarget buildTarget, EBuildMode buildMode)
{
List<int> versionList = new List<int>();
string parentPath = $"{outputRoot}/{buildTarget}";
if (Directory.Exists(parentPath) == false)
return versionList;
// 获取所有补丁包文件夹
string[] allFolders = Directory.GetDirectories(parentPath);
for (int i = 0; i < allFolders.Length; i++)
{
string folderName = Path.GetFileNameWithoutExtension(allFolders[i]);
if (int.TryParse(folderName, out int version))
versionList.Add(version);
}
// 从小到大排序
versionList.Sort();
return versionList;
string result = $"{outputRoot}/{buildPackage}/{buildTarget}/{YooAssetSettings.OutputFolderName}";
if (buildMode == EBuildMode.DryRunBuild)
result += $"_{EBuildMode.DryRunBuild}";
else if (buildMode == EBuildMode.SimulateBuild)
result += $"_{EBuildMode.SimulateBuild}";
return result;
}
/// <summary>
/// 获取当前最大的补丁包版本号
/// </summary>
/// <returns>如果没有任何补丁版本,那么返回-1</returns>
public static int GetMaxPackageVersion(BuildTarget buildTarget, string outputRoot)
{
List<int> versionList = GetPackageVersionList(buildTarget, outputRoot);
if (versionList.Count == 0)
return -1;
return versionList[versionList.Count - 1];
}
/// <summary>
/// 是否存在任何补丁包版本
/// </summary>
public static bool HasAnyPackageVersion(BuildTarget buildTarget, string outputRoot)
{
List<int> versionList = GetPackageVersionList(buildTarget, outputRoot);
return versionList.Count > 0;
}
/// <summary>
/// 加载补丁清单文件
/// </summary>
internal static PatchManifest LoadPatchManifestFile(string fileDirectory, int resourceVersion)
internal static PatchManifest LoadPatchManifestFile(string fileDirectory, string packageName, string packageCRC)
{
string filePath = $"{fileDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(resourceVersion)}";
string filePath = $"{fileDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(packageName, packageCRC)}";
if (File.Exists(filePath) == false)
{
throw new System.Exception($"Not found patch manifest file : {filePath}");
@@ -130,16 +86,5 @@ namespace YooAsset.Editor
string jsonData = FileUtility.ReadFile(filePath);
return PatchManifest.Deserialize(jsonData);
}
/// <summary>
/// 获取旧的补丁清单
/// </summary>
internal static PatchManifest GetOldPatchManifest(string pipelineOutputDirectory)
{
string staticVersionFilePath = $"{pipelineOutputDirectory}/{YooAssetSettings.VersionFileName}";
string staticVersionContent = FileUtility.ReadFile(staticVersionFilePath);
int staticVersion = int.Parse(staticVersionContent);
return LoadPatchManifestFile(pipelineOutputDirectory, staticVersion);
}
}
}

View File

@@ -5,11 +5,6 @@ namespace YooAsset.Editor
{
public class AssetBundleBuilderSetting : ScriptableObject
{
/// <summary>
/// 构建版本号
/// </summary>
public int BuildVersion = 0;
/// <summary>
/// 构建管线
/// </summary>
@@ -21,9 +16,9 @@ namespace YooAsset.Editor
public EBuildMode BuildMode = EBuildMode.ForceRebuild;
/// <summary>
/// 内置资源标签(首包资源标签)
/// 构建的包裹名称
/// </summary>
public string BuildTags = string.Empty;
public string BuildPackage = string.Empty;
/// <summary>
/// 压缩方式

View File

@@ -21,13 +21,13 @@ namespace YooAsset.Editor
private BuildTarget _buildTarget;
private List<Type> _encryptionServicesClassTypes;
private List<string> _encryptionServicesClassNames;
private List<string> _buildPackageNames;
private Button _saveButton;
private TextField _buildOutputField;
private IntegerField _buildVersionField;
private EnumField _buildPipelineField;
private EnumField _buildModeField;
private TextField _buildinTagsField;
private PopupField<string> _buildPackageField;
private PopupField<string> _encryptionField;
private EnumField _compressionField;
private EnumField _outputNameStyleField;
@@ -52,26 +52,19 @@ namespace YooAsset.Editor
// 构建平台
_buildTarget = EditorUserBuildSettings.activeBuildTarget;
// 包裹名称列表
_buildPackageNames = GetBuildPackageNames();
// 加密服务类
_encryptionServicesClassTypes = GetEncryptionServicesClassTypes();
_encryptionServicesClassNames = _encryptionServicesClassTypes.Select(t => t.FullName).ToList();
// 输出目录
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot();
string pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(defaultOutputRoot, _buildTarget);
_buildOutputField = root.Q<TextField>("BuildOutput");
_buildOutputField.SetValueWithoutNotify(pipelineOutputDirectory);
_buildOutputField.SetValueWithoutNotify(defaultOutputRoot);
_buildOutputField.SetEnabled(false);
// 构建版本
_buildVersionField = root.Q<IntegerField>("BuildVersion");
_buildVersionField.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.BuildVersion);
_buildVersionField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSettingData.IsDirty = true;
AssetBundleBuilderSettingData.Setting.BuildVersion = _buildVersionField.value;
});
// 构建管线
_buildPipelineField = root.Q<EnumField>("BuildPipeline");
_buildPipelineField.Init(AssetBundleBuilderSettingData.Setting.BuildPipeline);
@@ -96,20 +89,34 @@ namespace YooAsset.Editor
RefreshWindow();
});
// 内置资源标签
_buildinTagsField = root.Q<TextField>("BuildinTags");
_buildinTagsField.SetValueWithoutNotify(AssetBundleBuilderSettingData.Setting.BuildTags);
_buildinTagsField.RegisterValueChangedCallback(evt =>
// 构建包裹
var buildPackageContainer = root.Q("BuildPackageContainer");
if (_buildPackageNames.Count > 0)
{
AssetBundleBuilderSettingData.IsDirty = true;
AssetBundleBuilderSettingData.Setting.BuildTags = _buildinTagsField.value;
});
int defaultIndex = GetDefaultPackageIndex(AssetBundleBuilderSettingData.Setting.BuildPackage);
_buildPackageField = new PopupField<string>(_buildPackageNames, defaultIndex);
_buildPackageField.label = "Build Package";
_buildPackageField.style.width = 350;
_buildPackageField.RegisterValueChangedCallback(evt =>
{
AssetBundleBuilderSettingData.IsDirty = true;
AssetBundleBuilderSettingData.Setting.BuildPackage = _buildPackageField.value;
});
buildPackageContainer.Add(_buildPackageField);
}
else
{
_buildPackageField = new PopupField<string>();
_buildPackageField.label = "Build Package";
_buildPackageField.style.width = 350;
buildPackageContainer.Add(_buildPackageField);
}
// 加密方法
var encryptionContainer = root.Q("EncryptionContainer");
if (_encryptionServicesClassNames.Count > 0)
{
int defaultIndex = GetEncryptionDefaultIndex(AssetBundleBuilderSettingData.Setting.EncyptionClassName);
int defaultIndex = GetDefaultEncryptionIndex(AssetBundleBuilderSettingData.Setting.EncyptionClassName);
_encryptionField = new PopupField<string>(_encryptionServicesClassNames, defaultIndex);
_encryptionField.label = "Encryption";
_encryptionField.style.width = 350;
@@ -163,21 +170,21 @@ namespace YooAsset.Editor
}
public void OnDestroy()
{
if(AssetBundleBuilderSettingData.IsDirty)
if (AssetBundleBuilderSettingData.IsDirty)
AssetBundleBuilderSettingData.SaveFile();
}
public void Update()
{
if(_saveButton != null)
if (_saveButton != null)
{
if(AssetBundleBuilderSettingData.IsDirty)
if (AssetBundleBuilderSettingData.IsDirty)
{
if (_saveButton.enabledSelf == false)
_saveButton.SetEnabled(true);
}
else
{
if(_saveButton.enabledSelf)
if (_saveButton.enabledSelf)
_saveButton.SetEnabled(false);
}
}
@@ -187,7 +194,6 @@ namespace YooAsset.Editor
{
var buildMode = AssetBundleBuilderSettingData.Setting.BuildMode;
bool enableElement = buildMode == EBuildMode.ForceRebuild;
_buildinTagsField.SetEnabled(enableElement);
_encryptionField.SetEnabled(enableElement);
_compressionField.SetEnabled(enableElement);
_outputNameStyleField.SetEnabled(enableElement);
@@ -221,11 +227,9 @@ namespace YooAsset.Editor
buildParameters.BuildTarget = _buildTarget;
buildParameters.BuildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline;
buildParameters.BuildMode = AssetBundleBuilderSettingData.Setting.BuildMode;
buildParameters.BuildVersion = AssetBundleBuilderSettingData.Setting.BuildVersion;
buildParameters.BuildinTags = AssetBundleBuilderSettingData.Setting.BuildTags;
buildParameters.BuildPackage = AssetBundleBuilderSettingData.Setting.BuildPackage;
buildParameters.VerifyBuildingResult = true;
buildParameters.EnableAddressable = AssetBundleCollectorSettingData.Setting.EnableAddressable;
buildParameters.CopyBuildinTagFiles = AssetBundleBuilderSettingData.Setting.BuildMode == EBuildMode.ForceRebuild;
buildParameters.EncryptionServices = CreateEncryptionServicesInstance();
buildParameters.CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption;
buildParameters.OutputNameStyle = AssetBundleBuilderSettingData.Setting.OutputNameStyle;
@@ -235,17 +239,42 @@ namespace YooAsset.Editor
buildParameters.SBPParameters = new BuildParameters.SBPBuildParameters();
buildParameters.SBPParameters.WriteLinkXML = true;
}
var builder = new AssetBundleBuilder();
var buildResult = builder.Run(buildParameters);
if (buildResult.Success)
{
EditorUtility.RevealInFinder($"{buildParameters.OutputRoot}/{buildParameters.BuildTarget}/{buildParameters.BuildVersion}");
EditorUtility.RevealInFinder(buildResult.OutputPackageDirectory);
}
}
// 构建包裹相关
private int GetDefaultPackageIndex(string packageName)
{
for (int index = 0; index < _buildPackageNames.Count; index++)
{
if (_buildPackageNames[index] == packageName)
{
return index;
}
}
AssetBundleBuilderSettingData.IsDirty = true;
AssetBundleBuilderSettingData.Setting.BuildPackage = _buildPackageNames[0];
return 0;
}
private List<string> GetBuildPackageNames()
{
List<string> result = new List<string>();
foreach (var package in AssetBundleCollectorSettingData.Setting.Packages)
{
result.Add(package.PackageName);
}
return result;
}
// 加密类相关
private int GetEncryptionDefaultIndex(string className)
private int GetDefaultEncryptionIndex(string className)
{
for (int index = 0; index < _encryptionServicesClassNames.Count; index++)
{
@@ -254,6 +283,9 @@ namespace YooAsset.Editor
return index;
}
}
AssetBundleBuilderSettingData.IsDirty = true;
AssetBundleBuilderSettingData.Setting.EncyptionClassName = _encryptionServicesClassNames[0];
return 0;
}
private List<Type> GetEncryptionServicesClassTypes()

View File

@@ -4,13 +4,12 @@
</uie:Toolbar>
<ui:VisualElement name="BuildContainer">
<ui:TextField picking-mode="Ignore" label="Build Output" name="BuildOutput" />
<uie:IntegerField label="Build Version" value="0" name="BuildVersion" />
<uie:EnumField label="Build Pipeline" name="BuildPipeline" />
<uie:EnumField label="Build Mode" name="BuildMode" />
<ui:VisualElement name="BuildPackageContainer" style="height: 24px;" />
<ui:VisualElement name="EncryptionContainer" style="height: 24px;" />
<uie:EnumField label="Compression" value="Center" name="Compression" />
<uie:EnumField label="Output Name Style" value="Center" name="OutputNameStyle" />
<ui:TextField picking-mode="Ignore" label="Buildin Tags" name="BuildinTags" />
<ui:Button text="构建" display-tooltip-when-elided="true" name="Build" style="height: 50px; background-color: rgb(40, 106, 42); margin-top: 10px;" />
</ui:VisualElement>
</ui:UXML>

View File

@@ -4,40 +4,32 @@ namespace YooAsset.Editor
{
public static class AssetBundleSimulateBuilder
{
private static string _manifestFilePath = string.Empty;
/// <summary>
/// 模拟构建
/// </summary>
public static void SimulateBuild()
public static string SimulateBuild(string packageName, bool enableAddressable)
{
string defaultOutputRoot = AssetBundleBuilderHelper.GetDefaultOutputRoot();
BuildParameters buildParameters = new BuildParameters();
buildParameters.OutputRoot = defaultOutputRoot;
buildParameters.BuildTarget = EditorUserBuildSettings.activeBuildTarget;
buildParameters.BuildMode = EBuildMode.SimulateBuild;
buildParameters.BuildVersion = 999;
buildParameters.EnableAddressable = AssetBundleCollectorSettingData.Setting.EnableAddressable;
buildParameters.BuildPackage = packageName;
buildParameters.EnableAddressable = enableAddressable;
AssetBundleBuilder builder = new AssetBundleBuilder();
var buildResult = builder.Run(buildParameters);
if (buildResult.Success)
{
string pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(buildParameters.OutputRoot, buildParameters.BuildTarget);
_manifestFilePath = $"{pipelineOutputDirectory}_{EBuildMode.SimulateBuild}/{YooAssetSettingsData.GetPatchManifestFileName(buildParameters.BuildVersion)}";
string pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(buildParameters.OutputRoot, buildParameters.BuildPackage, buildParameters.BuildTarget, buildParameters.BuildMode);
string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.BuildPackage, buildResult.OutputPackageCRC);
string manifestFilePath = $"{pipelineOutputDirectory}/{manifestFileName}";
return manifestFilePath;
}
else
{
_manifestFilePath = null;
return null;
}
}
/// <summary>
/// 获取构建的补丁清单路径
/// </summary>
public static string GetPatchManifestPath()
{
return _manifestFilePath;
}
}
}

View File

@@ -40,21 +40,6 @@ namespace YooAsset.Editor
/// </summary>
public string ContentHash { set; get; } = "00000000000000000000000000000000"; //32位
/// <summary>
/// 文件哈希值
/// </summary>
public string FileHash { set; get; } = "00000000000000000000000000000000"; //32位
/// <summary>
/// 文件CRC32
/// </summary>
public string FileCRC { set; get; } = "00000000"; //8位
/// <summary>
/// 文件大小
/// </summary>
public long FileSize { set; get; } = 0;
public BuildBundleInfo(string bundleName)
{

View File

@@ -10,7 +10,7 @@ namespace YooAsset.Editor
/// <summary>
/// 执行资源构建上下文
/// </summary>
public static BuildMapContext CreateBuildMap(EBuildMode buildMode)
public static BuildMapContext CreateBuildMap(EBuildMode buildMode, string packageName)
{
BuildMapContext context = new BuildMapContext();
Dictionary<string, BuildAssetInfo> buildAssetDic = new Dictionary<string, BuildAssetInfo>(1000);
@@ -19,7 +19,7 @@ namespace YooAsset.Editor
AssetBundleCollectorSettingData.Setting.CheckConfigError();
// 2. 获取所有收集器收集的资源
List<CollectAssetInfo> allCollectAssets = AssetBundleCollectorSettingData.Setting.GetAllCollectAssets(buildMode);
List<CollectAssetInfo> allCollectAssets = AssetBundleCollectorSettingData.Setting.GetPackageAssets(buildMode, packageName);
// 3. 剔除未被引用的依赖资源
List<CollectAssetInfo> removeDependList = new List<CollectAssetInfo>();

View File

@@ -57,15 +57,9 @@ namespace YooAsset.Editor
public EBuildMode BuildMode;
/// <summary>
/// 构建的版本(资源版本号)
/// 构建的Package名称
/// </summary>
public int BuildVersion;
/// <summary>
/// 内置资源标签集合(首包资源标签)
/// 注意:分号为分隔符
/// </summary>
public string BuildinTags;
public string BuildPackage;
/// <summary>
@@ -77,12 +71,6 @@ namespace YooAsset.Editor
/// 启用可寻址资源定位
/// </summary>
public bool EnableAddressable = false;
/// <summary>
/// 拷贝内置资源文件到StreamingAssets目录首包资源文件
/// </summary>
public bool CopyBuildinTagFiles = false;
/// <summary>
/// 加密类
@@ -108,14 +96,5 @@ namespace YooAsset.Editor
/// 忽略类型树变化
/// </summary>
public bool IgnoreTypeTreeChanges = true;
/// <summary>
/// 获取内置资源标签列表(首包资源标签)
/// </summary>
public List<string> GetBuildinTags()
{
return StringUtility.StringToStringList(BuildinTags, ';');
}
}
}

View File

@@ -9,34 +9,61 @@ namespace YooAsset.Editor
{
private readonly System.Diagnostics.Stopwatch _buildWatch = new System.Diagnostics.Stopwatch();
private string _pipelineOutputDirectory = string.Empty;
private string _packageOutputDirectory = string.Empty;
private string _outputPackageCRC = string.Empty;
/// <summary>
/// 构建参数
/// </summary>
public BuildParameters Parameters { private set; get; }
/// <summary>
/// 构建管线的输出目录
/// 构建输出的包裹清单哈希值
/// </summary>
public string PipelineOutputDirectory { private set; get; }
public string OutputPackageCRC
{
get
{
if (string.IsNullOrEmpty(_outputPackageCRC))
throw new Exception("Output package file CRC32 is empty !");
return _outputPackageCRC;
}
set
{
_outputPackageCRC = value;
}
}
public BuildParametersContext(BuildParameters parameters)
{
Parameters = parameters;
}
PipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(parameters.OutputRoot, parameters.BuildTarget);
if (parameters.BuildMode == EBuildMode.DryRunBuild)
PipelineOutputDirectory += $"_{EBuildMode.DryRunBuild}";
else if (parameters.BuildMode == EBuildMode.SimulateBuild)
PipelineOutputDirectory += $"_{EBuildMode.SimulateBuild}";
/// <summary>
/// 获取构建管线的输出目录
/// </summary>
/// <returns></returns>
public string GetPipelineOutputDirectory()
{
if (string.IsNullOrEmpty(_pipelineOutputDirectory))
{
_pipelineOutputDirectory = AssetBundleBuilderHelper.MakePipelineOutputDirectory(Parameters.OutputRoot, Parameters.BuildPackage, Parameters.BuildTarget, Parameters.BuildMode);
}
return _pipelineOutputDirectory;
}
/// <summary>
/// 获取本次构建的补丁目录
/// </summary>
public string GetPackageDirectory()
public string GetPackageOutputDirectory()
{
return $"{Parameters.OutputRoot}/{Parameters.BuildTarget}/{Parameters.BuildVersion}";
if (string.IsNullOrEmpty(_packageOutputDirectory))
{
_packageOutputDirectory = $"{Parameters.OutputRoot}/{Parameters.BuildPackage}/{Parameters.BuildTarget}/{OutputPackageCRC}";
}
return _packageOutputDirectory;
}
/// <summary>
@@ -85,11 +112,9 @@ namespace YooAsset.Editor
if (Parameters.BuildMode == EBuildMode.SimulateBuild)
throw new Exception("Should never get here !");
if (Parameters.BuildMode == EBuildMode.DryRunBuild)
throw new Exception($"SBP not support {nameof(EBuildMode.DryRunBuild)} build mode !");
var targetGroup = BuildPipeline.GetBuildTargetGroup(Parameters.BuildTarget);
var buildParams = new UnityEditor.Build.Pipeline.BundleBuildParameters(Parameters.BuildTarget, targetGroup, PipelineOutputDirectory);
var pipelineOutputDirectory = GetPipelineOutputDirectory();
var buildParams = new UnityEditor.Build.Pipeline.BundleBuildParameters(Parameters.BuildTarget, targetGroup, pipelineOutputDirectory);
if (Parameters.CompressOption == ECompressOption.Uncompressed)
buildParams.BundleCompression = UnityEngine.BuildCompression.Uncompressed;
@@ -103,16 +128,9 @@ namespace YooAsset.Editor
if (Parameters.DisableWriteTypeTree)
buildParams.ContentBuildFlags |= UnityEditor.Build.Content.ContentBuildFlags.DisableWriteTypeTree;
if(Parameters.BuildMode == EBuildMode.ForceRebuild)
{
buildParams.UseCache = false;
}
else
{
buildParams.UseCache = true;
buildParams.CacheServerHost = Parameters.SBPParameters.CacheServerHost;
buildParams.CacheServerPort = Parameters.SBPParameters.CacheServerPort;
}
buildParams.UseCache = true;
buildParams.CacheServerHost = Parameters.SBPParameters.CacheServerHost;
buildParams.CacheServerPort = Parameters.SBPParameters.CacheServerPort;
buildParams.WriteLinkXML = Parameters.SBPParameters.WriteLinkXML;
return buildParams;

View File

@@ -44,25 +44,15 @@ namespace YooAsset.Editor
public EBuildMode BuildMode;
/// <summary>
/// 构建版本
/// 构建包裹
/// </summary>
public int BuildVersion;
/// <summary>
/// 内置资源标签
/// </summary>
public string BuildinTags;
public string BuildPackage;
/// <summary>
/// 启用可寻址资源定位
/// </summary>
public bool EnableAddressable;
/// <summary>
/// 拷贝内置资源文件
/// </summary>
public bool CopyBuildinTagFiles;
/// <summary>
/// 加密服务类名称
/// </summary>
@@ -79,8 +69,6 @@ namespace YooAsset.Editor
public int MainAssetTotalCount;
public int AllBundleTotalCount;
public long AllBundleTotalSize;
public int BuildinBundleTotalCount;
public long BuildinBundleTotalSize;
public int EncryptedBundleTotalCount;
public long EncryptedBundleTotalSize;
public int RawBundleTotalCount;

View File

@@ -25,5 +25,10 @@ namespace YooAsset.Editor
/// 输出的补丁包目录
/// </summary>
public string OutputPackageDirectory;
/// <summary>
/// 输出的包裹清单哈希值
/// </summary>
public string OutputPackageCRC;
}
}

View File

@@ -25,11 +25,19 @@ namespace YooAsset.Editor
if (buildMode == EBuildMode.SimulateBuild)
return;
BuildAssetBundleOptions opt = buildParametersContext.GetPipelineBuildOptions();
AssetBundleManifest buildResults = BuildPipeline.BuildAssetBundles(buildParametersContext.PipelineOutputDirectory, buildMapContext.GetPipelineBuilds(), opt, buildParametersContext.Parameters.BuildTarget);
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
BuildAssetBundleOptions buildOptions = buildParametersContext.GetPipelineBuildOptions();
AssetBundleManifest buildResults = BuildPipeline.BuildAssetBundles(pipelineOutputDirectory, buildMapContext.GetPipelineBuilds(), buildOptions, buildParametersContext.Parameters.BuildTarget);
if (buildResults == null)
throw new Exception("构建过程中发生错误!");
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{
string unityOutputManifestFilePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{YooAssetSettings.OutputFolderName}";
if(System.IO.File.Exists(unityOutputManifestFilePath) == false)
throw new Exception("构建过程中发生严重错误!请查阅上下文日志!");
}
BuildRunner.Log("Unity引擎打包成功");
BuildResultContext buildResultContext = new BuildResultContext();
buildResultContext.UnityManifest = buildResults;
@@ -47,11 +55,12 @@ namespace YooAsset.Editor
/// </summary>
private void CopyRawBundle(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext)
{
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
if (bundleInfo.IsRawFile)
{
string dest = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
string dest = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
foreach (var buildAsset in bundleInfo.BuildinAssets)
{
if (buildAsset.IsRawAsset)
@@ -66,15 +75,13 @@ namespace YooAsset.Editor
/// </summary>
private void UpdateBuildBundleInfo(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext, BuildResultContext buildResult)
{
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
string filePath = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
bundleInfo.FileHash = HashUtility.FileMD5(filePath);
bundleInfo.FileCRC = HashUtility.FileCRC32(filePath);
bundleInfo.FileSize = FileUtility.GetFileSize(filePath);
if (bundleInfo.IsRawFile)
{
bundleInfo.ContentHash = bundleInfo.FileHash;
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
bundleInfo.ContentHash = HashUtility.FileMD5(filePath);
}
else
{

View File

@@ -58,11 +58,12 @@ namespace YooAsset.Editor
/// </summary>
private void CopyRawBundle(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext)
{
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
if (bundleInfo.IsRawFile)
{
string dest = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
string dest = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
foreach (var buildAsset in bundleInfo.BuildinAssets)
{
if (buildAsset.IsRawAsset)
@@ -77,15 +78,13 @@ namespace YooAsset.Editor
/// </summary>
private void UpdateBuildBundleInfo(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext, BuildResultContext buildResult)
{
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
string filePath = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
bundleInfo.FileHash = HashUtility.FileMD5(filePath);
bundleInfo.FileCRC = HashUtility.FileCRC32(filePath);
bundleInfo.FileSize = FileUtility.GetFileSize(filePath);
if (bundleInfo.IsRawFile)
{
bundleInfo.ContentHash = bundleInfo.FileHash;
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
bundleInfo.ContentHash = HashUtility.FileMD5(filePath);
}
else
{

View File

@@ -1,68 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace YooAsset.Editor
{
[TaskAttribute("拷贝内置文件到流目录")]
public class TaskCopyBuildinFiles : IBuildTask
{
void IBuildTask.Run(BuildContext context)
{
// 注意:我们只有在强制重建的时候才会拷贝
var buildParameters = context.GetContextObject<BuildParametersContext>();
if (buildParameters.Parameters.CopyBuildinTagFiles)
{
// 清空流目录
AssetBundleBuilderHelper.ClearStreamingAssetsFolder();
// 拷贝内置文件
CopyBuildinFilesToStreaming(buildParameters.PipelineOutputDirectory, buildParameters.Parameters.BuildVersion);
}
}
private void CopyBuildinFilesToStreaming(string pipelineOutputDirectory, int buildVersion)
{
// 加载补丁清单
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(pipelineOutputDirectory, buildVersion);
// 拷贝文件列表
foreach (var patchBundle in patchManifest.BundleList)
{
if (patchBundle.IsBuildin == false)
continue;
string sourcePath = $"{pipelineOutputDirectory}/{patchBundle.BundleName}";
string destPath = $"{AssetBundleBuilderHelper.GetStreamingAssetsFolderPath()}/{patchBundle.FileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝清单文件
{
string sourcePath = $"{pipelineOutputDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(buildVersion)}";
string destPath = $"{AssetBundleBuilderHelper.GetStreamingAssetsFolderPath()}/{YooAssetSettingsData.GetPatchManifestFileName(buildVersion)}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝清单哈希文件
{
string sourcePath = $"{pipelineOutputDirectory}/{YooAssetSettingsData.GetPatchManifestHashFileName(buildVersion)}";
string destPath = $"{AssetBundleBuilderHelper.GetStreamingAssetsFolderPath()}/{YooAssetSettingsData.GetPatchManifestHashFileName(buildVersion)}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝静态版本文件
{
string sourcePath = $"{pipelineOutputDirectory}/{YooAssetSettings.VersionFileName}";
string destPath = $"{AssetBundleBuilderHelper.GetStreamingAssetsFolderPath()}/{YooAssetSettings.VersionFileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 刷新目录
AssetDatabase.Refresh();
BuildRunner.Log($"内置文件拷贝完成:{AssetBundleBuilderHelper.GetStreamingAssetsFolderPath()}");
}
}
}

View File

@@ -21,42 +21,48 @@ namespace YooAsset.Editor
/// </summary>
private void CreatePatchManifestFile(BuildContext context)
{
var buildParameters = context.GetContextObject<BuildParametersContext>();
int resourceVersion = buildParameters.Parameters.BuildVersion;
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildParameters = buildParametersContext.Parameters;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
// 创建新补丁清单
PatchManifest patchManifest = new PatchManifest();
patchManifest.FileVersion = YooAssetSettings.PatchManifestFileVersion;
patchManifest.ResourceVersion = buildParameters.Parameters.BuildVersion;
patchManifest.EnableAddressable = buildParameters.Parameters.EnableAddressable;
patchManifest.OutputNameStyle = (int)buildParameters.Parameters.OutputNameStyle;
patchManifest.BuildinTags = buildParameters.Parameters.BuildinTags;
patchManifest.EnableAddressable = buildParameters.EnableAddressable;
patchManifest.OutputNameStyle = (int)buildParameters.OutputNameStyle;
patchManifest.PackageName = buildParameters.BuildPackage;
patchManifest.BundleList = GetAllPatchBundle(context);
patchManifest.AssetList = GetAllPatchAsset(context, patchManifest);
// 更新Unity内置资源包的引用关系
if (buildParameters.Parameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
UpdateBuiltInBundleReference(patchManifest, buildResultContext.Results);
if(buildParameters.BuildMode == EBuildMode.IncrementalBuild)
{
var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
UpdateBuiltInBundleReference(patchManifest, buildResultContext.Results);
}
}
// 创建补丁清单文件
string manifestFilePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(resourceVersion)}";
BuildRunner.Log($"创建补丁清单文件:{manifestFilePath}");
PatchManifest.Serialize(manifestFilePath, patchManifest);
string manifestFileTempName = YooAssetSettingsData.GetPatchManifestTempFileName(buildParameters.BuildPackage);
string manifestFileTempPath = $"{pipelineOutputDirectory}/{manifestFileTempName}";
BuildRunner.Log($"创建补丁清单文件:{manifestFileTempPath}");
PatchManifest.Serialize(manifestFileTempPath, patchManifest);
// 创建补丁清单哈希文件
string manifestHashFilePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.GetPatchManifestHashFileName(resourceVersion)}";
string manifestHash = HashUtility.FileMD5(manifestFilePath);
BuildRunner.Log($"创建补丁清单哈希文件:{manifestHashFilePath}");
FileUtility.CreateFile(manifestHashFilePath, manifestHash);
// 计算补丁清单文件的CRC32
buildParametersContext.OutputPackageCRC = HashUtility.FileCRC32(manifestFileTempPath);
// 补丁清单文件重命名
string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.BuildPackage, buildParametersContext.OutputPackageCRC);
string manifestFilePath = $"{pipelineOutputDirectory}/{manifestFileName}";
EditorTools.FileMoveTo(manifestFileTempPath, manifestFilePath);
// 创建静态版本文件
string staticVersionFilePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettings.VersionFileName}";
string staticVersion = resourceVersion.ToString();
string staticVersionFileName = YooAssetSettingsData.GetStaticVersionFileName(buildParameters.BuildPackage);
string staticVersionFilePath = $"{pipelineOutputDirectory}/{staticVersionFileName}";
BuildRunner.Log($"创建静态版本文件:{staticVersionFilePath}");
FileUtility.CreateFile(staticVersionFilePath, staticVersion);
FileUtility.CreateFile(staticVersionFilePath, buildParametersContext.OutputPackageCRC);
}
/// <summary>
@@ -69,38 +75,48 @@ namespace YooAsset.Editor
var encryptionContext = context.GetContextObject<TaskEncryption.EncryptionContext>();
List<PatchBundle> result = new List<PatchBundle>(1000);
List<string> buildinTags = buildParameters.Parameters.GetBuildinTags();
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
var bundleName = bundleInfo.BundleName;
string fileHash = bundleInfo.FileHash;
string fileCRC = bundleInfo.FileCRC;
long fileSize = bundleInfo.FileSize;
string fileHash = GetBundleFileHash(bundleInfo, buildParameters);
string fileCRC = GetBundleFileCRC(bundleInfo, buildParameters);
long fileSize = GetBundleFileSize(bundleInfo, buildParameters);
string[] tags = buildMapContext.GetBundleTags(bundleName);
bool isEncrypted = encryptionContext.IsEncryptFile(bundleName);
bool isBuildin = IsBuildinBundle(tags, buildinTags);
bool isRawFile = bundleInfo.IsRawFile;
PatchBundle patchBundle = new PatchBundle(bundleName, fileHash, fileCRC, fileSize, tags);
patchBundle.SetFlagsValue(isEncrypted, isBuildin, isRawFile);
patchBundle.SetFlagsValue(isRawFile, isEncrypted);
result.Add(patchBundle);
}
return result;
}
private bool IsBuildinBundle(string[] bundleTags, List<string> buildinTags)
private string GetBundleFileHash(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
{
// 注意没有任何分类标签的Bundle文件默认为内置文件
if (bundleTags.Length == 0)
return true;
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return "00000000000000000000000000000000"; //32位
foreach (var tag in bundleTags)
{
if (buildinTags.Contains(tag))
return true;
}
return false;
string filePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{bundleInfo.BundleName}";
return HashUtility.FileMD5(filePath);
}
private string GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
{
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return "00000000"; //8位
string filePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{bundleInfo.BundleName}";
return HashUtility.FileCRC32(filePath);
}
private long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
{
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
return 0;
string filePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{bundleInfo.BundleName}";
return FileUtility.GetFileSize(filePath);
}
/// <summary>

View File

@@ -19,55 +19,51 @@ namespace YooAsset.Editor
/// <summary>
/// 拷贝补丁文件到补丁包目录
/// </summary>
private void CopyPatchFiles(BuildParametersContext buildParameters)
private void CopyPatchFiles(BuildParametersContext buildParametersContext)
{
int resourceVersion = buildParameters.Parameters.BuildVersion;
string packageDirectory = buildParameters.GetPackageDirectory();
BuildRunner.Log($"开始拷贝补丁文件到补丁包目录:{packageDirectory}");
var buildParameters = buildParametersContext.Parameters;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
string packageOutputDirectory = buildParametersContext.GetPackageOutputDirectory();
BuildRunner.Log($"开始拷贝补丁文件到补丁包目录:{packageOutputDirectory}");
// 拷贝Report文件
{
string reportFileName = YooAssetSettingsData.GetReportFileName(buildParameters.Parameters.BuildVersion);
string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{reportFileName}";
string destPath = $"{packageDirectory}/{reportFileName}";
string reportFileName = YooAssetSettingsData.GetReportFileName(buildParameters.BuildPackage, buildParametersContext.OutputPackageCRC);
string sourcePath = $"{pipelineOutputDirectory}/{reportFileName}";
string destPath = $"{packageOutputDirectory}/{reportFileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝补丁清单文件
{
string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(resourceVersion)}";
string destPath = $"{packageDirectory}/{YooAssetSettingsData.GetPatchManifestFileName(resourceVersion)}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝补丁清单哈希文件
{
string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.GetPatchManifestHashFileName(resourceVersion)}";
string destPath = $"{packageDirectory}/{YooAssetSettingsData.GetPatchManifestHashFileName(resourceVersion)}";
string manifestFileName = YooAssetSettingsData.GetPatchManifestFileName(buildParameters.BuildPackage, buildParametersContext.OutputPackageCRC);
string sourcePath = $"{pipelineOutputDirectory}/{manifestFileName}";
string destPath = $"{packageOutputDirectory}/{manifestFileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝静态版本文件
{
string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettings.VersionFileName}";
string destPath = $"{packageDirectory}/{YooAssetSettings.VersionFileName}";
string versionFileName = YooAssetSettingsData.GetStaticVersionFileName(buildParameters.BuildPackage);
string sourcePath = $"{pipelineOutputDirectory}/{versionFileName}";
string destPath = $"{packageOutputDirectory}/{versionFileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
if (buildParameters.Parameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
{
// 拷贝构建日志
{
string sourcePath = $"{buildParameters.PipelineOutputDirectory}/buildlogtep.json";
string destPath = $"{packageDirectory}/buildlogtep.json";
string sourcePath = $"{pipelineOutputDirectory}/buildlogtep.json";
string destPath = $"{packageOutputDirectory}/buildlogtep.json";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝代码防裁剪配置
if (buildParameters.Parameters.SBPParameters.WriteLinkXML)
if (buildParameters.SBPParameters.WriteLinkXML)
{
string sourcePath = $"{buildParameters.PipelineOutputDirectory}/link.xml";
string destPath = $"{packageDirectory}/link.xml";
string sourcePath = $"{pipelineOutputDirectory}/link.xml";
string destPath = $"{packageOutputDirectory}/link.xml";
EditorTools.CopyFile(sourcePath, destPath, true);
}
}
@@ -75,27 +71,27 @@ namespace YooAsset.Editor
{
// 拷贝UnityManifest序列化文件
{
string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}";
string destPath = $"{packageDirectory}/{YooAssetSettings.OutputFolderName}";
string sourcePath = $"{pipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}";
string destPath = $"{packageOutputDirectory}/{YooAssetSettings.OutputFolderName}";
EditorTools.CopyFile(sourcePath, destPath, true);
}
// 拷贝UnityManifest文本文件
{
string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}.manifest";
string destPath = $"{packageDirectory}/{YooAssetSettings.OutputFolderName}.manifest";
string sourcePath = $"{pipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}.manifest";
string destPath = $"{packageOutputDirectory}/{YooAssetSettings.OutputFolderName}.manifest";
EditorTools.CopyFile(sourcePath, destPath, true);
}
}
// 拷贝所有补丁文件
int progressValue = 0;
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(buildParameters.PipelineOutputDirectory, buildParameters.Parameters.BuildVersion);
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(pipelineOutputDirectory, buildParameters.BuildPackage, buildParametersContext.OutputPackageCRC);
int patchFileTotalCount = patchManifest.BundleList.Count;
foreach (var patchBundle in patchManifest.BundleList)
{
string sourcePath = $"{buildParameters.PipelineOutputDirectory}/{patchBundle.BundleName}";
string destPath = $"{packageDirectory}/{patchBundle.FileName}";
string sourcePath = $"{pipelineOutputDirectory}/{patchBundle.BundleName}";
string destPath = $"{packageOutputDirectory}/{patchBundle.FileName}";
EditorTools.CopyFile(sourcePath, destPath, true);
EditorTools.DisplayProgressBar("拷贝补丁文件", ++progressValue, patchFileTotalCount);
}

View File

@@ -19,16 +19,17 @@ namespace YooAsset.Editor
{
CreateReportFile(buildParameters, buildMapContext);
}
else
{
float buildSeconds = buildParameters.GetBuildingSeconds();
BuildRunner.Info($"Build time consuming {buildSeconds} seconds.");
}
float buildSeconds = buildParameters.GetBuildingSeconds();
BuildRunner.Info($"Build time consuming {buildSeconds} seconds.");
}
private void CreateReportFile(BuildParametersContext buildParameters, BuildMapContext buildMapContext)
private void CreateReportFile(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext)
{
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(buildParameters.PipelineOutputDirectory, buildParameters.Parameters.BuildVersion);
var buildParameters = buildParametersContext.Parameters;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(pipelineOutputDirectory, buildParameters.BuildPackage, buildParametersContext.OutputPackageCRC);
BuildReport buildReport = new BuildReport();
// 概述信息
@@ -40,30 +41,26 @@ namespace YooAsset.Editor
#endif
buildReport.Summary.UnityVersion = UnityEngine.Application.unityVersion;
buildReport.Summary.BuildDate = DateTime.Now.ToString();
buildReport.Summary.BuildSeconds = (int)buildParameters.GetBuildingSeconds();
buildReport.Summary.BuildTarget = buildParameters.Parameters.BuildTarget;
buildReport.Summary.BuildPipeline = buildParameters.Parameters.BuildPipeline;
buildReport.Summary.BuildMode = buildParameters.Parameters.BuildMode;
buildReport.Summary.BuildVersion = buildParameters.Parameters.BuildVersion;
buildReport.Summary.BuildinTags = buildParameters.Parameters.BuildinTags;
buildReport.Summary.EnableAddressable = buildParameters.Parameters.EnableAddressable;
buildReport.Summary.CopyBuildinTagFiles = buildParameters.Parameters.CopyBuildinTagFiles;
buildReport.Summary.EncryptionServicesClassName = buildParameters.Parameters.EncryptionServices == null ?
"null" : buildParameters.Parameters.EncryptionServices.GetType().FullName;
buildReport.Summary.BuildSeconds = (int)buildParametersContext.GetBuildingSeconds();
buildReport.Summary.BuildTarget = buildParameters.BuildTarget;
buildReport.Summary.BuildPipeline = buildParameters.BuildPipeline;
buildReport.Summary.BuildMode = buildParameters.BuildMode;
buildReport.Summary.BuildPackage = buildParameters.BuildPackage;
buildReport.Summary.EnableAddressable = buildParameters.EnableAddressable;
buildReport.Summary.EncryptionServicesClassName = buildParameters.EncryptionServices == null ?
"null" : buildParameters.EncryptionServices.GetType().FullName;
// 构建参数
buildReport.Summary.OutputNameStyle = buildParameters.Parameters.OutputNameStyle;
buildReport.Summary.CompressOption = buildParameters.Parameters.CompressOption;
buildReport.Summary.DisableWriteTypeTree = buildParameters.Parameters.DisableWriteTypeTree;
buildReport.Summary.IgnoreTypeTreeChanges = buildParameters.Parameters.IgnoreTypeTreeChanges;
buildReport.Summary.OutputNameStyle = buildParameters.OutputNameStyle;
buildReport.Summary.CompressOption = buildParameters.CompressOption;
buildReport.Summary.DisableWriteTypeTree = buildParameters.DisableWriteTypeTree;
buildReport.Summary.IgnoreTypeTreeChanges = buildParameters.IgnoreTypeTreeChanges;
// 构建结果
buildReport.Summary.AssetFileTotalCount = buildMapContext.AssetFileCount;
buildReport.Summary.MainAssetTotalCount = GetMainAssetCount(patchManifest);
buildReport.Summary.AllBundleTotalCount = GetAllBundleCount(patchManifest);
buildReport.Summary.AllBundleTotalSize = GetAllBundleSize(patchManifest);
buildReport.Summary.BuildinBundleTotalCount = GetBuildinBundleCount(patchManifest);
buildReport.Summary.BuildinBundleTotalSize = GetBuildinBundleSize(patchManifest);
buildReport.Summary.EncryptedBundleTotalCount = GetEncryptedBundleCount(patchManifest);
buildReport.Summary.EncryptedBundleTotalSize = GetEncryptedBundleSize(patchManifest);
buildReport.Summary.RawBundleTotalCount = GetRawBundleCount(patchManifest);
@@ -103,7 +100,8 @@ namespace YooAsset.Editor
}
// 删除旧文件
string filePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettingsData.GetReportFileName(buildParameters.Parameters.BuildVersion)}";
string fileName = YooAssetSettingsData.GetReportFileName(buildParameters.BuildPackage, buildParametersContext.OutputPackageCRC);
string filePath = $"{pipelineOutputDirectory}/{fileName}";
if (File.Exists(filePath))
File.Delete(filePath);
@@ -176,26 +174,6 @@ namespace YooAsset.Editor
}
return fileBytes;
}
private int GetBuildinBundleCount(PatchManifest patchManifest)
{
int fileCount = 0;
foreach (var patchBundle in patchManifest.BundleList)
{
if (patchBundle.IsBuildin)
fileCount++;
}
return fileCount;
}
private long GetBuildinBundleSize(PatchManifest patchManifest)
{
long fileBytes = 0;
foreach (var patchBundle in patchManifest.BundleList)
{
if (patchBundle.IsBuildin)
fileBytes += patchBundle.FileSize;
}
return fileBytes;
}
private int GetEncryptedBundleCount(PatchManifest patchManifest)
{
int fileCount = 0;

View File

@@ -45,9 +45,9 @@ namespace YooAsset.Editor
/// <summary>
/// 加密文件
/// </summary>
private List<string> EncryptFiles(BuildParametersContext buildParameters, BuildMapContext buildMapContext)
private List<string> EncryptFiles(BuildParametersContext buildParametersContext, BuildMapContext buildMapContext)
{
var encryptionServices = buildParameters.Parameters.EncryptionServices;
var encryptionServices = buildParametersContext.Parameters.EncryptionServices;
// 加密资源列表
List<string> encryptList = new List<string>();
@@ -57,6 +57,7 @@ namespace YooAsset.Editor
return encryptList;
int progressValue = 0;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
if (encryptionServices.Check(bundleInfo.BundleName))
@@ -70,7 +71,7 @@ namespace YooAsset.Editor
encryptList.Add(bundleInfo.BundleName);
// 注意:通过判断文件合法性,规避重复加密一个文件
string filePath = $"{buildParameters.PipelineOutputDirectory}/{bundleInfo.BundleName}";
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
byte[] fileData = File.ReadAllBytes(filePath);
if (EditorTools.CheckBundleFileValid(fileData))
{

View File

@@ -13,7 +13,7 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildMapContext = BuildMapCreater.CreateBuildMap(buildParametersContext.Parameters.BuildMode);
var buildMapContext = BuildMapCreater.CreateBuildMap(buildParametersContext.Parameters.BuildMode, buildParametersContext.Parameters.BuildPackage);
context.SetContextObject(buildMapContext);
BuildRunner.Log("构建内容准备完毕!");

View File

@@ -11,24 +11,18 @@ namespace YooAsset.Editor
{
void IBuildTask.Run(BuildContext context)
{
var buildParameters = context.GetContextObject<BuildParametersContext>();
buildParameters.BeginWatch();
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
buildParametersContext.BeginWatch();
var buildMode = buildParameters.Parameters.BuildMode;
var buildParameters = buildParametersContext.Parameters;
// 检测构建平台是否合法
if (buildParameters.Parameters.BuildTarget == BuildTarget.NoTarget)
// 检测构建参数合法
if (buildParameters.BuildTarget == BuildTarget.NoTarget)
throw new Exception("请选择目标平台");
if (string.IsNullOrEmpty(buildParameters.BuildPackage))
throw new Exception("包裹名称不能为空");
// 检测构建版本是否合法
if (buildParameters.Parameters.BuildVersion <= 0)
throw new Exception("请先设置版本号");
// 检测输出目录是否为空
if (string.IsNullOrEmpty(buildParameters.PipelineOutputDirectory))
throw new Exception("输出目录不能为空");
if (buildMode != EBuildMode.SimulateBuild)
if (buildParameters.BuildMode != EBuildMode.SimulateBuild)
{
// 检测当前是否正在构建资源包
if (BuildPipeline.isBuildingPlayer)
@@ -41,35 +35,10 @@ namespace YooAsset.Editor
// 保存改动的资源
AssetDatabase.SaveAssets();
}
// 增量更新时候的必要检测
if (buildMode == EBuildMode.IncrementalBuild)
{
// 检测历史版本是否存在
if (AssetBundleBuilderHelper.HasAnyPackageVersion(buildParameters.Parameters.BuildTarget, buildParameters.Parameters.OutputRoot))
{
// 检测构建版本是否合法
int maxPackageVersion = AssetBundleBuilderHelper.GetMaxPackageVersion(buildParameters.Parameters.BuildTarget, buildParameters.Parameters.OutputRoot);
if (buildParameters.Parameters.BuildVersion <= maxPackageVersion)
throw new Exception("构建版本不能小于历史版本");
// 检测补丁包是否已经存在
string packageDirectory = buildParameters.GetPackageDirectory();
if (Directory.Exists(packageDirectory))
throw new Exception($"补丁包已经存在:{packageDirectory}");
// 检测内置资源分类标签是否一致
var oldPatchManifest = AssetBundleBuilderHelper.GetOldPatchManifest(buildParameters.PipelineOutputDirectory);
if (buildParameters.Parameters.BuildinTags != oldPatchManifest.BuildinTags)
throw new Exception($"增量更新时内置资源标签必须一致:{buildParameters.Parameters.BuildinTags} != {oldPatchManifest.BuildinTags}");
}
}
// 如果是强制重建
if (buildMode == EBuildMode.ForceRebuild)
if (buildParameters.BuildMode == EBuildMode.ForceRebuild)
{
// 删除平台总目录
string platformDirectory = $"{buildParameters.Parameters.OutputRoot}/{buildParameters.Parameters.BuildTarget}";
string platformDirectory = $"{buildParameters.OutputRoot}/{buildParameters.BuildPackage}/{buildParameters.BuildTarget}";
if (EditorTools.DeleteDirectory(platformDirectory))
{
BuildRunner.Log($"删除平台总目录:{platformDirectory}");
@@ -77,9 +46,10 @@ namespace YooAsset.Editor
}
// 如果输出目录不存在
if (EditorTools.CreateDirectory(buildParameters.PipelineOutputDirectory))
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
if (EditorTools.CreateDirectory(pipelineOutputDirectory))
{
BuildRunner.Log($"创建输出目录:{buildParameters.PipelineOutputDirectory}");
BuildRunner.Log($"创建输出目录:{pipelineOutputDirectory}");
}
}
}

View File

@@ -32,7 +32,7 @@ namespace YooAsset.Editor
/// </summary>
private void VerifyingBuildingResult(BuildContext context, AssetBundleManifest unityManifest)
{
var buildParameters = context.GetContextObject<BuildParametersContext>();
var buildParametersContext = context.GetContextObject<BuildParametersContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
string[] buildedBundles = unityManifest.GetAllAssetBundles();
@@ -63,13 +63,14 @@ namespace YooAsset.Editor
// 4. 验证Asset
bool isPass = true;
var buildMode = buildParameters.Parameters.BuildMode;
var buildMode = buildParametersContext.Parameters.BuildMode;
if (buildMode == EBuildMode.ForceRebuild || buildMode == EBuildMode.IncrementalBuild)
{
int progressValue = 0;
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
foreach (var buildedBundle in buildedBundles)
{
string filePath = $"{buildParameters.PipelineOutputDirectory}/{buildedBundle}";
string filePath = $"{pipelineOutputDirectory}/{buildedBundle}";
string[] buildedAssetPaths = GetAssetBundleAllAssets(filePath);
string[] mapAssetPaths = buildMapContext.GetBuildinAssetPaths(buildedBundle);
if (mapAssetPaths.Length != buildedAssetPaths.Length)

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace YooAsset.Editor
{
@@ -14,6 +15,11 @@ namespace YooAsset.Editor
/// </summary>
public string CollectPath = string.Empty;
/// <summary>
/// 收集器的GUID
/// </summary>
public string CollectorGUID = string.Empty;
/// <summary>
/// 收集器类型
/// </summary>
@@ -68,7 +74,8 @@ namespace YooAsset.Editor
/// </summary>
public void CheckConfigError()
{
if (AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(CollectPath) == null)
string assetGUID = AssetDatabase.AssetPathToGUID(CollectPath);
if (string.IsNullOrEmpty(assetGUID))
throw new Exception($"Invalid collect path : {CollectPath}");
if (CollectorType == ECollectorType.None)
@@ -84,10 +91,48 @@ namespace YooAsset.Editor
throw new Exception($"Invalid {nameof(IAddressRule)} class type : {AddressRuleName} in collector : {CollectPath}");
}
/// <summary>
/// 修复配置错误
/// </summary>
public bool FixConfigError()
{
bool isFixed = false;
if (string.IsNullOrEmpty(CollectorGUID) == false)
{
string convertAssetPath = AssetDatabase.GUIDToAssetPath(CollectorGUID);
if (string.IsNullOrEmpty(convertAssetPath))
{
Debug.LogWarning($"Collector GUID {CollectorGUID} is invalid and has been auto removed !");
CollectorGUID = string.Empty;
isFixed = true;
}
else
{
if (CollectPath != convertAssetPath)
{
CollectPath = convertAssetPath;
isFixed = true;
Debug.LogWarning($"Fix collect path : {CollectPath} -> {convertAssetPath}");
}
}
}
/*
string convertGUID = AssetDatabase.AssetPathToGUID(CollectPath);
if(string.IsNullOrEmpty(convertGUID) == false)
{
CollectorGUID = convertGUID;
}
*/
return isFixed;
}
/// <summary>
/// 获取打包收集的资源文件
/// </summary>
public List<CollectAssetInfo> GetAllCollectAssets(EBuildMode buildMode, AssetBundleCollectorGroup group)
public List<CollectAssetInfo> GetAllCollectAssets(EBuildMode buildMode, bool enableAddressable, AssetBundleCollectorGroup group)
{
// 注意:模拟构建模式下只收集主资源
if (buildMode == EBuildMode.SimulateBuild)
@@ -142,7 +187,7 @@ namespace YooAsset.Editor
}
// 检测可寻址地址是否重复
if (AssetBundleCollectorSettingData.Setting.EnableAddressable)
if (enableAddressable)
{
HashSet<string> adressTemper = new HashSet<string>();
foreach (var collectInfoPair in result)
@@ -184,11 +229,6 @@ namespace YooAsset.Editor
UnityEngine.Debug.LogError($"Invalid asset path : {assetPath}");
return false;
}
if (assetPath.Contains("/Gizmos/"))
{
UnityEngine.Debug.LogWarning($"Cannot pack gizmos asset : {assetPath}");
return false;
}
// 忽略文件夹
if (AssetDatabase.IsValidFolder(assetPath))

View File

@@ -10,22 +10,30 @@ namespace YooAsset.Editor
{
public class AssetBundleCollectorConfig
{
public const string ConfigVersion = "1.0";
public const string ConfigVersion = "2.0";
public const string XmlVersion = "Version";
public const string XmlCommon = "Common";
public const string XmlEnableAddressable = "AutoAddressable";
public const string XmlShowPackageView = "ShowPackageView";
public const string XmlPackage = "Package";
public const string XmlPackageName = "PackageName";
public const string XmlPackageDesc = "PackageDesc";
public const string XmlGroup = "Group";
public const string XmlGroupName = "GroupName";
public const string XmlGroupDesc = "GroupDesc";
public const string XmlCollector = "Collector";
public const string XmlCollectPath = "CollectPath";
public const string XmlCollectorGUID = "CollectGUID";
public const string XmlCollectorType = "CollectType";
public const string XmlAddressRule = "AddressRule";
public const string XmlPackRule = "PackRule";
public const string XmlFilterRule = "FilterRule";
public const string XmlAssetTags = "AssetTags";
/// <summary>
/// 导入XML配置表
/// </summary>
@@ -38,80 +46,108 @@ namespace YooAsset.Editor
throw new Exception($"Only support xml : {filePath}");
// 加载配置文件
XmlDocument xml = new XmlDocument();
xml.Load(filePath);
XmlElement root = xml.DocumentElement;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filePath);
XmlElement root = xmlDoc.DocumentElement;
// 读取配置版本
string configVersion = root.GetAttribute(XmlVersion);
if(configVersion != ConfigVersion)
if (configVersion != ConfigVersion)
{
throw new Exception($"The config version is invalid : {configVersion}");
if (UpdateXmlConfig(xmlDoc) == false)
throw new Exception($"The config version update failed : {configVersion} -> {ConfigVersion}");
else
Debug.Log($"The config version update succeed : {configVersion} -> {ConfigVersion}");
}
// 读取公共配置
bool enableAddressable = false;
bool showPackageView = false;
var commonNodeList = root.GetElementsByTagName(XmlCommon);
if (commonNodeList.Count > 0)
{
XmlElement commonElement = commonNodeList[0] as XmlElement;
if (commonElement.HasAttribute(XmlEnableAddressable) == false)
throw new Exception($"Not found attribute {XmlEnableAddressable} in {XmlCommon}");
if (commonElement.HasAttribute(XmlShowPackageView) == false)
throw new Exception($"Not found attribute {XmlShowPackageView} in {XmlCommon}");
enableAddressable = commonElement.GetAttribute(XmlEnableAddressable) == "True" ? true : false;
showPackageView = commonElement.GetAttribute(XmlShowPackageView) == "True" ? true : false;
}
// 读取分组配置
List<AssetBundleCollectorGroup> groupTemper = new List<AssetBundleCollectorGroup>();
var groupNodeList = root.GetElementsByTagName(XmlGroup);
foreach (var groupNode in groupNodeList)
// 读取包裹配置
List<AssetBundleCollectorPackage> packages = new List<AssetBundleCollectorPackage>();
var packageNodeList = root.GetElementsByTagName(XmlPackage);
foreach (var packageNode in packageNodeList)
{
XmlElement groupElement = groupNode as XmlElement;
if (groupElement.HasAttribute(XmlGroupName) == false)
throw new Exception($"Not found attribute {XmlGroupName} in {XmlGroup}");
if (groupElement.HasAttribute(XmlGroupDesc) == false)
throw new Exception($"Not found attribute {XmlGroupDesc} in {XmlGroup}");
if (groupElement.HasAttribute(XmlAssetTags) == false)
throw new Exception($"Not found attribute {XmlAssetTags} in {XmlGroup}");
XmlElement packageElement = packageNode as XmlElement;
if (packageElement.HasAttribute(XmlPackageName) == false)
throw new Exception($"Not found attribute {XmlPackageName} in {XmlPackage}");
if (packageElement.HasAttribute(XmlPackageDesc) == false)
throw new Exception($"Not found attribute {XmlPackageDesc} in {XmlPackage}");
AssetBundleCollectorGroup group = new AssetBundleCollectorGroup();
group.GroupName = groupElement.GetAttribute(XmlGroupName);
group.GroupDesc = groupElement.GetAttribute(XmlGroupDesc);
group.AssetTags = groupElement.GetAttribute(XmlAssetTags);
groupTemper.Add(group);
AssetBundleCollectorPackage package = new AssetBundleCollectorPackage();
package.PackageName = packageElement.GetAttribute(XmlPackageName);
package.PackageDesc = packageElement.GetAttribute(XmlPackageDesc);
packages.Add(package);
// 读取收集器配置
var collectorNodeList = groupElement.GetElementsByTagName(XmlCollector);
foreach (var collectorNode in collectorNodeList)
// 读取分组配置
var groupNodeList = packageElement.GetElementsByTagName(XmlGroup);
foreach (var groupNode in groupNodeList)
{
XmlElement collectorElement = collectorNode as XmlElement;
if (collectorElement.HasAttribute(XmlCollectPath) == false)
throw new Exception($"Not found attribute {XmlCollectPath} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlCollectorType) == false)
throw new Exception($"Not found attribute {XmlCollectorType} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlAddressRule) == false)
throw new Exception($"Not found attribute {XmlAddressRule} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlPackRule) == false)
throw new Exception($"Not found attribute {XmlPackRule} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlFilterRule) == false)
throw new Exception($"Not found attribute {XmlFilterRule} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlAssetTags) == false)
throw new Exception($"Not found attribute {XmlAssetTags} in {XmlCollector}");
XmlElement groupElement = groupNode as XmlElement;
if (groupElement.HasAttribute(XmlGroupName) == false)
throw new Exception($"Not found attribute {XmlGroupName} in {XmlGroup}");
if (groupElement.HasAttribute(XmlGroupDesc) == false)
throw new Exception($"Not found attribute {XmlGroupDesc} in {XmlGroup}");
if (groupElement.HasAttribute(XmlAssetTags) == false)
throw new Exception($"Not found attribute {XmlAssetTags} in {XmlGroup}");
AssetBundleCollector collector = new AssetBundleCollector();
collector.CollectPath = collectorElement.GetAttribute(XmlCollectPath);
collector.CollectorType = StringUtility.NameToEnum<ECollectorType>(collectorElement.GetAttribute(XmlCollectorType));
collector.AddressRuleName = collectorElement.GetAttribute(XmlAddressRule);
collector.PackRuleName = collectorElement.GetAttribute(XmlPackRule);
collector.FilterRuleName = collectorElement.GetAttribute(XmlFilterRule);
collector.AssetTags = collectorElement.GetAttribute(XmlAssetTags); ;
group.Collectors.Add(collector);
AssetBundleCollectorGroup group = new AssetBundleCollectorGroup();
group.GroupName = groupElement.GetAttribute(XmlGroupName);
group.GroupDesc = groupElement.GetAttribute(XmlGroupDesc);
group.AssetTags = groupElement.GetAttribute(XmlAssetTags);
package.Groups.Add(group);
// 读取收集器配置
var collectorNodeList = groupElement.GetElementsByTagName(XmlCollector);
foreach (var collectorNode in collectorNodeList)
{
XmlElement collectorElement = collectorNode as XmlElement;
if (collectorElement.HasAttribute(XmlCollectPath) == false)
throw new Exception($"Not found attribute {XmlCollectPath} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlCollectorGUID) == false)
throw new Exception($"Not found attribute {XmlCollectorGUID} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlCollectorType) == false)
throw new Exception($"Not found attribute {XmlCollectorType} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlAddressRule) == false)
throw new Exception($"Not found attribute {XmlAddressRule} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlPackRule) == false)
throw new Exception($"Not found attribute {XmlPackRule} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlFilterRule) == false)
throw new Exception($"Not found attribute {XmlFilterRule} in {XmlCollector}");
if (collectorElement.HasAttribute(XmlAssetTags) == false)
throw new Exception($"Not found attribute {XmlAssetTags} in {XmlCollector}");
AssetBundleCollector collector = new AssetBundleCollector();
collector.CollectPath = collectorElement.GetAttribute(XmlCollectPath);
collector.CollectorGUID = collectorElement.GetAttribute(XmlCollectorGUID);
collector.CollectorType = StringUtility.NameToEnum<ECollectorType>(collectorElement.GetAttribute(XmlCollectorType));
collector.AddressRuleName = collectorElement.GetAttribute(XmlAddressRule);
collector.PackRuleName = collectorElement.GetAttribute(XmlPackRule);
collector.FilterRuleName = collectorElement.GetAttribute(XmlFilterRule);
collector.AssetTags = collectorElement.GetAttribute(XmlAssetTags);
group.Collectors.Add(collector);
}
}
}
// 保存配置数据
AssetBundleCollectorSettingData.ClearAll();
AssetBundleCollectorSettingData.Setting.EnableAddressable = enableAddressable;
AssetBundleCollectorSettingData.Setting.Groups.AddRange(groupTemper);
AssetBundleCollectorSettingData.Setting.ShowPackageView = showPackageView;
AssetBundleCollectorSettingData.Setting.Packages.AddRange(packages);
AssetBundleCollectorSettingData.SaveFile();
Debug.Log($"导入配置完毕!");
}
@@ -139,28 +175,39 @@ namespace YooAsset.Editor
// 设置公共配置
var commonElement = xmlDoc.CreateElement(XmlCommon);
commonElement.SetAttribute(XmlEnableAddressable, AssetBundleCollectorSettingData.Setting.EnableAddressable.ToString());
commonElement.SetAttribute(XmlShowPackageView, AssetBundleCollectorSettingData.Setting.ShowPackageView.ToString());
root.AppendChild(commonElement);
// 设置分组配置
foreach (var group in AssetBundleCollectorSettingData.Setting.Groups)
// 设置Package配置
foreach (var package in AssetBundleCollectorSettingData.Setting.Packages)
{
var groupElement = xmlDoc.CreateElement(XmlGroup);
groupElement.SetAttribute(XmlGroupName, group.GroupName);
groupElement.SetAttribute(XmlGroupDesc, group.GroupDesc);
groupElement.SetAttribute(XmlAssetTags, group.AssetTags);
root.AppendChild(groupElement);
var packageElement = xmlDoc.CreateElement(XmlPackage);
packageElement.SetAttribute(XmlPackageName, package.PackageName);
packageElement.SetAttribute(XmlPackageDesc, package.PackageDesc);
root.AppendChild(packageElement);
// 设置收集器配置
foreach (var collector in group.Collectors)
// 设置分组配置
foreach (var group in package.Groups)
{
var collectorElement = xmlDoc.CreateElement(XmlCollector);
collectorElement.SetAttribute(XmlCollectPath, collector.CollectPath);
collectorElement.SetAttribute(XmlCollectorType, collector.CollectorType.ToString());
collectorElement.SetAttribute(XmlAddressRule, collector.AddressRuleName);
collectorElement.SetAttribute(XmlPackRule, collector.PackRuleName);
collectorElement.SetAttribute(XmlFilterRule, collector.FilterRuleName);
collectorElement.SetAttribute(XmlAssetTags, collector.AssetTags);
groupElement.AppendChild(collectorElement);
var groupElement = xmlDoc.CreateElement(XmlGroup);
groupElement.SetAttribute(XmlGroupName, group.GroupName);
groupElement.SetAttribute(XmlGroupDesc, group.GroupDesc);
groupElement.SetAttribute(XmlAssetTags, group.AssetTags);
packageElement.AppendChild(groupElement);
// 设置收集器配置
foreach (var collector in group.Collectors)
{
var collectorElement = xmlDoc.CreateElement(XmlCollector);
collectorElement.SetAttribute(XmlCollectPath, collector.CollectPath);
collectorElement.SetAttribute(XmlCollectorGUID, collector.CollectorGUID);
collectorElement.SetAttribute(XmlCollectorType, collector.CollectorType.ToString());
collectorElement.SetAttribute(XmlAddressRule, collector.AddressRuleName);
collectorElement.SetAttribute(XmlPackRule, collector.PackRuleName);
collectorElement.SetAttribute(XmlFilterRule, collector.FilterRuleName);
collectorElement.SetAttribute(XmlAssetTags, collector.AssetTags);
groupElement.AppendChild(collectorElement);
}
}
}
@@ -168,5 +215,65 @@ namespace YooAsset.Editor
xmlDoc.Save(savePath);
Debug.Log($"导出配置完毕!");
}
/// <summary>
/// 升级XML配置表
/// </summary>
private static bool UpdateXmlConfig(XmlDocument xmlDoc)
{
XmlElement root = xmlDoc.DocumentElement;
string configVersion = root.GetAttribute(XmlVersion);
if (configVersion == ConfigVersion)
return true;
// 1.0 -> 2.0
if (configVersion == "1.0")
{
// 添加公共元素属性
var commonNodeList = root.GetElementsByTagName(XmlCommon);
if (commonNodeList.Count > 0)
{
XmlElement commonElement = commonNodeList[0] as XmlElement;
if (commonElement.HasAttribute(XmlShowPackageView) == false)
commonElement.SetAttribute(XmlShowPackageView, "False");
}
// 添加包裹元素
var packageElement = xmlDoc.CreateElement(XmlPackage);
packageElement.SetAttribute(XmlPackageName, "DefaultPackage");
packageElement.SetAttribute(XmlPackageDesc, string.Empty);
root.AppendChild(packageElement);
// 获取所有分组元素
var groupNodeList = root.GetElementsByTagName(XmlGroup);
List<XmlElement> temper = new List<XmlElement>(groupNodeList.Count);
foreach (var groupNode in groupNodeList)
{
XmlElement groupElement = groupNode as XmlElement;
var collectorNodeList = groupElement.GetElementsByTagName(XmlCollector);
foreach (var collectorNode in collectorNodeList)
{
XmlElement collectorElement = collectorNode as XmlElement;
if (collectorElement.HasAttribute(XmlCollectorGUID) == false)
collectorElement.SetAttribute(XmlCollectorGUID, string.Empty);
}
temper.Add(groupElement);
}
// 将分组元素转移至包裹元素下
foreach (var groupElement in temper)
{
root.RemoveChild(groupElement);
packageElement.AppendChild(groupElement);
}
// 更新版本
root.SetAttribute(XmlVersion, "2.0");
return UpdateXmlConfig(xmlDoc);
}
return false;
}
}
}

View File

@@ -50,10 +50,26 @@ namespace YooAsset.Editor
}
}
/// <summary>
/// 修复配置错误
/// </summary>
public bool FixConfigError()
{
bool isFixed = false;
foreach (var collector in Collectors)
{
if (collector.FixConfigError())
{
isFixed = true;
}
}
return isFixed;
}
/// <summary>
/// 获取打包收集的资源文件
/// </summary>
public List<CollectAssetInfo> GetAllCollectAssets(EBuildMode buildMode)
public List<CollectAssetInfo> GetAllCollectAssets(EBuildMode buildMode, bool enableAddressable)
{
Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(10000);
@@ -67,7 +83,7 @@ namespace YooAsset.Editor
// 收集打包资源
foreach (var collector in Collectors)
{
var temper = collector.GetAllCollectAssets(buildMode, this);
var temper = collector.GetAllCollectAssets(buildMode, enableAddressable, this);
foreach (var assetInfo in temper)
{
if (result.ContainsKey(assetInfo.AssetPath) == false)
@@ -78,7 +94,7 @@ namespace YooAsset.Editor
}
// 检测可寻址地址是否重复
if (AssetBundleCollectorSettingData.Setting.EnableAddressable)
if (enableAddressable)
{
HashSet<string> adressTemper = new HashSet<string>();
foreach (var collectInfoPair in result)

View File

@@ -0,0 +1,125 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEditor;
namespace YooAsset.Editor
{
[Serializable]
public class AssetBundleCollectorPackage
{
/// <summary>
/// 包裹名称
/// </summary>
public string PackageName = string.Empty;
/// <summary>
/// 包裹描述
/// </summary>
public string PackageDesc = string.Empty;
/// <summary>
/// 分组列表
/// </summary>
public List<AssetBundleCollectorGroup> Groups = new List<AssetBundleCollectorGroup>();
/// <summary>
/// 检测配置错误
/// </summary>
public void CheckConfigError()
{
foreach (var group in Groups)
{
group.CheckConfigError();
}
}
/// <summary>
/// 修复配置错误
/// </summary>
public bool FixConfigError()
{
bool isFixed = false;
foreach (var group in Groups)
{
if (group.FixConfigError())
{
isFixed = true;
}
}
return isFixed;
}
/// <summary>
/// 获取打包收集的资源文件
/// </summary>
public List<CollectAssetInfo> GetAllCollectAssets(EBuildMode buildMode, bool enableAddressable)
{
Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(10000);
// 收集打包资源
foreach (var group in Groups)
{
var temper = group.GetAllCollectAssets(buildMode, enableAddressable);
foreach (var assetInfo in temper)
{
if (result.ContainsKey(assetInfo.AssetPath) == false)
result.Add(assetInfo.AssetPath, assetInfo);
else
throw new Exception($"The collecting asset file is existed : {assetInfo.AssetPath}");
}
}
// 检测可寻址地址是否重复
if (enableAddressable)
{
HashSet<string> adressTemper = new HashSet<string>();
foreach (var collectInfoPair in result)
{
if (collectInfoPair.Value.CollectorType == ECollectorType.MainAssetCollector)
{
string address = collectInfoPair.Value.Address;
if (adressTemper.Contains(address) == false)
adressTemper.Add(address);
else
throw new Exception($"The address is existed : {address}");
}
}
}
// 返回列表
return result.Values.ToList();
}
/// <summary>
/// 获取所有的资源标签
/// </summary>
public List<string> GetAllTags()
{
HashSet<string> result = new HashSet<string>();
foreach (var group in Groups)
{
List<string> groupTags = StringUtility.StringToStringList(group.AssetTags, ';');
foreach (var tag in groupTags)
{
if (result.Contains(tag) == false)
result.Add(tag);
}
foreach (var collector in group.Collectors)
{
List<string> collectorTags = StringUtility.StringToStringList(collector.AssetTags, ';');
foreach (var tag in collectorTags)
{
if (result.Contains(tag) == false)
result.Add(tag);
}
}
}
return result.ToList();
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 5d188c50fd00bf941b2eeebb374dc0d1
guid: 154d1124b6089254895b0f2b672394d5
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -8,95 +8,105 @@ namespace YooAsset.Editor
{
public class AssetBundleCollectorSetting : ScriptableObject
{
/// <summary>
/// 是否显示包裹视图
/// </summary>
public bool ShowPackageView = false;
/// <summary>
/// 是否启用可寻址资源定位
/// </summary>
public bool EnableAddressable = false;
/// <summary>
/// 分组列表
/// 包裹列表
/// </summary>
public List<AssetBundleCollectorGroup> Groups = new List<AssetBundleCollectorGroup>();
public List<AssetBundleCollectorPackage> Packages = new List<AssetBundleCollectorPackage>();
/// <summary>
/// 清空所有数据
/// </summary>
public void ClearAll()
{
EnableAddressable = false;
Packages.Clear();
}
/// <summary>
/// 检测配置错误
/// </summary>
public void CheckConfigError()
{
foreach (var group in Groups)
foreach (var package in Packages)
{
group.CheckConfigError();
package.CheckConfigError();
}
}
/// <summary>
/// 修复配置错误
/// </summary>
public bool FixConfigError()
{
bool isFixed = false;
foreach (var package in Packages)
{
if (package.FixConfigError())
{
isFixed = true;
}
}
return isFixed;
}
/// <summary>
/// 获取所有的资源标签
/// </summary>
public List<string> GetAllTags()
public List<string> GetPackageAllTags(string packageName)
{
HashSet<string> result = new HashSet<string>();
foreach (var group in Groups)
foreach (var package in Packages)
{
List<string> groupTags = StringUtility.StringToStringList(group.AssetTags, ';');
foreach (var tag in groupTags)
if (package.PackageName == packageName)
{
if (result.Contains(tag) == false)
result.Add(tag);
}
foreach (var collector in group.Collectors)
{
List<string> collectorTags = StringUtility.StringToStringList(collector.AssetTags, ';');
foreach (var tag in collectorTags)
{
if (result.Contains(tag) == false)
result.Add(tag);
}
return package.GetAllTags();
}
}
return result.ToList();
Debug.LogWarning($"Not found package : {packageName}");
return new List<string>();
}
/// <summary>
/// 获取包裹收集的资源文件
/// </summary>
public List<CollectAssetInfo> GetPackageAssets(EBuildMode buildMode, string packageName)
{
if (string.IsNullOrEmpty(packageName))
throw new Exception("Build Package name is null or mepty !");
foreach (var package in Packages)
{
if (package.PackageName == packageName)
{
return package.GetAllCollectAssets(buildMode, EnableAddressable);
}
}
throw new Exception($"Not found collector pacakge : {packageName}");
}
/// <summary>
/// 获取打包收集的资源文件
/// 获取所有包裹收集的资源文件
/// </summary>
public List<CollectAssetInfo> GetAllCollectAssets(EBuildMode buildMode)
public List<CollectAssetInfo> GetAllPackageAssets(EBuildMode buildMode)
{
Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(10000);
// 收集打包资源
foreach (var group in Groups)
List<CollectAssetInfo> result = new List<CollectAssetInfo>(1000);
foreach (var package in Packages)
{
var temper = group.GetAllCollectAssets(buildMode);
foreach (var assetInfo in temper)
{
if (result.ContainsKey(assetInfo.AssetPath) == false)
result.Add(assetInfo.AssetPath, assetInfo);
else
throw new Exception($"The collecting asset file is existed : {assetInfo.AssetPath}");
}
var temper = package.GetAllCollectAssets(buildMode, EnableAddressable);
result.AddRange(temper);
}
// 检测可寻址地址是否重复
if (EnableAddressable)
{
HashSet<string> adressTemper = new HashSet<string>();
foreach (var collectInfoPair in result)
{
if (collectInfoPair.Value.CollectorType == ECollectorType.MainAssetCollector)
{
string address = collectInfoPair.Value.Address;
if (adressTemper.Contains(address) == false)
adressTemper.Add(address);
else
throw new Exception($"The address is existed : {address}");
}
}
}
// 返回列表
return result.Values.ToList();
return result;
}
}
}

View File

@@ -232,7 +232,7 @@ namespace YooAsset.Editor
}
/// <summary>
/// 存储文件
/// 存储配置文件
/// </summary>
public static void SaveFile()
{
@@ -245,13 +245,24 @@ namespace YooAsset.Editor
}
}
/// <summary>
/// 修复配置文件
/// </summary>
public static void FixFile()
{
bool isFixed = Setting.FixConfigError();
if (isFixed)
{
IsDirty = true;
}
}
/// <summary>
/// 清空所有数据
/// </summary>
public static void ClearAll()
{
Setting.EnableAddressable = false;
Setting.Groups.Clear();
Setting.ClearAll();
SaveFile();
}
@@ -325,24 +336,56 @@ namespace YooAsset.Editor
}
}
// 可寻址编辑相关
// 公共参数编辑相关
public static void ModifyPackageView(bool showPackageView)
{
Setting.ShowPackageView = showPackageView;
IsDirty = true;
}
public static void ModifyAddressable(bool enableAddressable)
{
Setting.EnableAddressable = enableAddressable;
IsDirty = true;
}
// 资源包裹编辑相关
public static void CreatePackage(string packageName)
{
AssetBundleCollectorPackage package = new AssetBundleCollectorPackage();
package.PackageName = packageName;
Setting.Packages.Add(package);
IsDirty = true;
}
public static void RemovePackage(AssetBundleCollectorPackage package)
{
if (Setting.Packages.Remove(package))
{
IsDirty = true;
}
else
{
Debug.LogWarning($"Failed remove package : {package.PackageName}");
}
}
public static void ModifyPackage(AssetBundleCollectorPackage package)
{
if (package != null)
{
IsDirty = true;
}
}
// 资源分组编辑相关
public static void CreateGroup(string groupName)
public static void CreateGroup(AssetBundleCollectorPackage package, string groupName)
{
AssetBundleCollectorGroup group = new AssetBundleCollectorGroup();
group.GroupName = groupName;
Setting.Groups.Add(group);
package.Groups.Add(group);
IsDirty = true;
}
public static void RemoveGroup(AssetBundleCollectorGroup group)
public static void RemoveGroup(AssetBundleCollectorPackage package, AssetBundleCollectorGroup group)
{
if (Setting.Groups.Remove(group))
if (package.Groups.Remove(group))
{
IsDirty = true;
}
@@ -351,19 +394,17 @@ namespace YooAsset.Editor
Debug.LogWarning($"Failed remove group : {group.GroupName}");
}
}
public static void ModifyGroup(AssetBundleCollectorGroup group)
public static void ModifyGroup(AssetBundleCollectorPackage package, AssetBundleCollectorGroup group)
{
if (group != null)
if (package != null && group != null)
{
IsDirty = true;
}
}
// 资源收集器编辑相关
public static void CreateCollector(AssetBundleCollectorGroup group, string collectPath)
public static void CreateCollector(AssetBundleCollectorGroup group, AssetBundleCollector collector)
{
AssetBundleCollector collector = new AssetBundleCollector();
collector.CollectPath = collectPath;
group.Collectors.Add(collector);
IsDirty = true;
}
@@ -389,9 +430,9 @@ namespace YooAsset.Editor
/// <summary>
/// 获取所有的资源标签
/// </summary>
public static string GetAllTags()
public static string GetPackageAllTags(string packageName)
{
var allTags = Setting.GetAllTags();
var allTags = Setting.GetPackageAllTags(packageName);
return string.Join(";", allTags);
}
}

View File

@@ -24,15 +24,27 @@ namespace YooAsset.Editor
private List<string> _addressRuleList;
private List<string> _packRuleList;
private List<string> _filterRuleList;
private ListView _groupListView;
private ScrollView _collectorScrollView;
private PopupField<string> _activeRulePopupField;
private Toggle _showPackageToogle;
private Toggle _enableAddressableToogle;
private VisualElement _packageContainer;
private ListView _packageListView;
private TextField _packageNameTxt;
private TextField _packageDescTxt;
private VisualElement _groupContainer;
private ListView _groupListView;
private TextField _groupNameTxt;
private TextField _groupDescTxt;
private TextField _groupAssetTagsTxt;
private VisualElement _groupContainer;
private string _lastModifyGroup = string.Empty;
private VisualElement _collectorContainer;
private ScrollView _collectorScrollView;
private PopupField<string> _activeRulePopupField;
private int _lastModifyPackageIndex = 0;
private int _lastModifyGroupIndex = 0;
public void CreateGUI()
@@ -62,6 +74,24 @@ namespace YooAsset.Editor
visualAsset.CloneTree(root);
// 公共设置相关
_showPackageToogle = root.Q<Toggle>("ShowPackages");
_showPackageToogle.RegisterValueChangedCallback(evt =>
{
AssetBundleCollectorSettingData.ModifyPackageView(evt.newValue);
RefreshWindow();
});
_enableAddressableToogle = root.Q<Toggle>("EnableAddressable");
_enableAddressableToogle.RegisterValueChangedCallback(evt =>
{
AssetBundleCollectorSettingData.ModifyAddressable(evt.newValue);
RefreshWindow();
});
// 配置修复按钮
var fixBtn = root.Q<Button>("FixButton");
fixBtn.clicked += FixBtn_clicked;
// 导入导出按钮
var exportBtn = root.Q<Button>("ExportButton");
exportBtn.clicked += ExportBtn_clicked;
@@ -72,12 +102,50 @@ namespace YooAsset.Editor
_saveButton = root.Q<Button>("SaveButton");
_saveButton.clicked += SaveBtn_clicked;
// 公共设置相关
_enableAddressableToogle = root.Q<Toggle>("EnableAddressable");
_enableAddressableToogle.RegisterValueChangedCallback(evt =>
// 包裹容器
_packageContainer = root.Q("PackageContainer");
// 包裹列表相关
_packageListView = root.Q<ListView>("PackageListView");
_packageListView.makeItem = MakePackageListViewItem;
_packageListView.bindItem = BindPackageListViewItem;
#if UNITY_2020_1_OR_NEWER
_packageListView.onSelectionChange += PackageListView_onSelectionChange;
#else
_packageListView.onSelectionChanged += PackageListView_onSelectionChange;
#endif
// 包裹添加删除按钮
var packageAddContainer = root.Q("PackageAddContainer");
{
AssetBundleCollectorSettingData.ModifyAddressable(evt.newValue);
RefreshWindow();
var addBtn = packageAddContainer.Q<Button>("AddBtn");
addBtn.clicked += AddPackageBtn_clicked;
var removeBtn = packageAddContainer.Q<Button>("RemoveBtn");
removeBtn.clicked += RemovePackageBtn_clicked;
}
// 包裹名称
_packageNameTxt = root.Q<TextField>("PackageName");
_packageNameTxt.RegisterValueChangedCallback(evt =>
{
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
if (selectPackage != null)
{
selectPackage.PackageName = evt.newValue;
AssetBundleCollectorSettingData.ModifyPackage(selectPackage);
}
});
// 包裹备注
_packageDescTxt = root.Q<TextField>("PackageDesc");
_packageDescTxt.RegisterValueChangedCallback(evt =>
{
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
if (selectPackage != null)
{
selectPackage.PackageDesc = evt.newValue;
AssetBundleCollectorSettingData.ModifyPackage(selectPackage);
}
});
// 分组列表相关
@@ -106,11 +174,12 @@ namespace YooAsset.Editor
_groupNameTxt = root.Q<TextField>("GroupName");
_groupNameTxt.RegisterValueChangedCallback(evt =>
{
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
if (selectGroup != null)
if (selectPackage != null && selectGroup != null)
{
selectGroup.GroupName = evt.newValue;
AssetBundleCollectorSettingData.ModifyGroup(selectGroup);
AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup);
}
});
@@ -118,11 +187,12 @@ namespace YooAsset.Editor
_groupDescTxt = root.Q<TextField>("GroupDesc");
_groupDescTxt.RegisterValueChangedCallback(evt =>
{
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
if (selectGroup != null)
if (selectPackage != null && selectGroup != null)
{
selectGroup.GroupDesc = evt.newValue;
AssetBundleCollectorSettingData.ModifyGroup(selectGroup);
AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup);
}
});
@@ -130,14 +200,18 @@ namespace YooAsset.Editor
_groupAssetTagsTxt = root.Q<TextField>("GroupAssetTags");
_groupAssetTagsTxt.RegisterValueChangedCallback(evt =>
{
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
if (selectGroup != null)
if (selectPackage != null && selectGroup != null)
{
selectGroup.AssetTags = evt.newValue;
AssetBundleCollectorSettingData.ModifyGroup(selectGroup);
AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup);
}
});
// 收集列表容器
_collectorContainer = root.Q("CollectorContainer");
// 收集列表相关
_collectorScrollView = root.Q<ScrollView>("CollectorScrollView");
_collectorScrollView.style.height = new Length(100, LengthUnit.Percent);
@@ -159,11 +233,12 @@ namespace YooAsset.Editor
activeRuleContainer.Add(_activeRulePopupField);
_activeRulePopupField.RegisterValueChangedCallback(evt =>
{
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
if (selectGroup != null)
if (selectPackage != null && selectGroup != null)
{
selectGroup.ActiveRuleName = evt.newValue;
AssetBundleCollectorSettingData.ModifyGroup(selectGroup);
AssetBundleCollectorSettingData.ModifyGroup(selectPackage, selectGroup);
FillGroupViewData();
}
});
@@ -204,10 +279,16 @@ namespace YooAsset.Editor
private void RefreshWindow()
{
_showPackageToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.ShowPackageView);
_enableAddressableToogle.SetValueWithoutNotify(AssetBundleCollectorSettingData.Setting.EnableAddressable);
_groupContainer.visible = false;
_collectorContainer.visible = false;
FillGroupViewData();
FillPackageViewData();
}
private void FixBtn_clicked()
{
AssetBundleCollectorSettingData.FixFile();
}
private void ExportBtn_clicked()
{
@@ -231,22 +312,97 @@ namespace YooAsset.Editor
AssetBundleCollectorSettingData.SaveFile();
}
// 包裹列表相关
private void FillPackageViewData()
{
_packageListView.Clear();
_packageListView.ClearSelection();
_packageListView.itemsSource = AssetBundleCollectorSettingData.Setting.Packages;
_packageListView.Rebuild();
if (_lastModifyPackageIndex >= 0 && _lastModifyPackageIndex < _packageListView.itemsSource.Count)
{
_packageListView.selectedIndex = _lastModifyPackageIndex;
}
if (_showPackageToogle.value)
_packageContainer.style.display = DisplayStyle.Flex;
else
_packageContainer.style.display = DisplayStyle.None;
}
private VisualElement MakePackageListViewItem()
{
VisualElement element = new VisualElement();
{
var label = new Label();
label.name = "Label1";
label.style.unityTextAlign = TextAnchor.MiddleLeft;
label.style.flexGrow = 1f;
label.style.height = 20f;
element.Add(label);
}
return element;
}
private void BindPackageListViewItem(VisualElement element, int index)
{
var package = AssetBundleCollectorSettingData.Setting.Packages[index];
var textField1 = element.Q<Label>("Label1");
if (string.IsNullOrEmpty(package.PackageDesc))
textField1.text = package.PackageName;
else
textField1.text = $"{package.PackageName} ({package.PackageDesc})";
}
private void PackageListView_onSelectionChange(IEnumerable<object> objs)
{
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
if (selectPackage == null)
{
_groupContainer.visible = false;
_collectorContainer.visible = false;
return;
}
_groupContainer.visible = true;
_lastModifyPackageIndex = _packageListView.selectedIndex;
_packageNameTxt.SetValueWithoutNotify(selectPackage.PackageName);
_packageDescTxt.SetValueWithoutNotify(selectPackage.PackageDesc);
FillGroupViewData();
}
private void AddPackageBtn_clicked()
{
Undo.RecordObject(AssetBundleCollectorSettingData.Setting, "YooAsset.AssetBundleCollectorWindow AddPackage");
AssetBundleCollectorSettingData.CreatePackage("DefaultPackage");
FillPackageViewData();
}
private void RemovePackageBtn_clicked()
{
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
if (selectPackage == null)
return;
Undo.RecordObject(AssetBundleCollectorSettingData.Setting, "YooAsset.AssetBundleCollectorWindow RemovePackage");
AssetBundleCollectorSettingData.RemovePackage(selectPackage);
FillPackageViewData();
}
// 分组列表相关
private void FillGroupViewData()
{
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
if (selectPackage == null)
return;
_groupListView.Clear();
_groupListView.ClearSelection();
_groupListView.itemsSource = AssetBundleCollectorSettingData.Setting.Groups;
_groupListView.itemsSource = selectPackage.Groups;
_groupListView.Rebuild();
for (int index = 0; index < AssetBundleCollectorSettingData.Setting.Groups.Count; index++)
if(_lastModifyGroupIndex >=0 && _lastModifyGroupIndex < _groupListView.itemsSource.Count)
{
var group = AssetBundleCollectorSettingData.Setting.Groups[index];
if (group.GroupName == _lastModifyGroup)
{
_groupListView.selectedIndex = index;
break;
}
_groupListView.selectedIndex = _lastModifyGroupIndex;
}
}
private VisualElement MakeGroupListViewItem()
@@ -266,9 +422,12 @@ namespace YooAsset.Editor
}
private void BindGroupListViewItem(VisualElement element, int index)
{
var group = AssetBundleCollectorSettingData.Setting.Groups[index];
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
if (selectPackage == null)
return;
var group = selectPackage.Groups[index];
// Group Name
var textField1 = element.Q<Label>("Label1");
if (string.IsNullOrEmpty(group.GroupDesc))
textField1.text = group.GroupName;
@@ -282,22 +441,44 @@ namespace YooAsset.Editor
}
private void GroupListView_onSelectionChange(IEnumerable<object> objs)
{
var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
if (selectGroup == null)
{
_collectorContainer.visible = false;
return;
}
_collectorContainer.visible = true;
_lastModifyGroupIndex = _groupListView.selectedIndex;
_activeRulePopupField.SetValueWithoutNotify(selectGroup.ActiveRuleName);
_groupNameTxt.SetValueWithoutNotify(selectGroup.GroupName);
_groupDescTxt.SetValueWithoutNotify(selectGroup.GroupDesc);
_groupAssetTagsTxt.SetValueWithoutNotify(selectGroup.AssetTags);
FillCollectorViewData();
}
private void AddGroupBtn_clicked()
{
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
if (selectPackage == null)
return;
Undo.RecordObject(AssetBundleCollectorSettingData.Setting, "YooAsset.AssetBundleCollectorWindow AddGroup");
AssetBundleCollectorSettingData.CreateGroup("Default Group");
AssetBundleCollectorSettingData.CreateGroup(selectPackage, "Default Group");
FillGroupViewData();
}
private void RemoveGroupBtn_clicked()
{
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
if (selectPackage == null)
return;
var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
if (selectGroup == null)
return;
Undo.RecordObject(AssetBundleCollectorSettingData.Setting, "YooAsset.AssetBundleCollectorWindow RemoveGroup");
AssetBundleCollectorSettingData.RemoveGroup(selectGroup);
AssetBundleCollectorSettingData.RemoveGroup(selectPackage, selectGroup);
FillGroupViewData();
}
@@ -306,17 +487,7 @@ namespace YooAsset.Editor
{
var selectGroup = _groupListView.selectedItem as AssetBundleCollectorGroup;
if (selectGroup == null)
{
_groupContainer.visible = false;
return;
}
_lastModifyGroup = selectGroup.GroupName;
_groupContainer.visible = true;
_activeRulePopupField.SetValueWithoutNotify(selectGroup.ActiveRuleName);
_groupNameTxt.SetValueWithoutNotify(selectGroup.GroupName);
_groupDescTxt.SetValueWithoutNotify(selectGroup.GroupDesc);
_groupAssetTagsTxt.SetValueWithoutNotify(selectGroup.AssetTags);
// 填充数据
_collectorScrollView.Clear();
@@ -472,6 +643,7 @@ namespace YooAsset.Editor
objectField1.RegisterValueChangedCallback(evt =>
{
collector.CollectPath = AssetDatabase.GetAssetPath(evt.newValue);
collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath);
objectField1.value.name = collector.CollectPath;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value)
@@ -561,7 +733,8 @@ namespace YooAsset.Editor
try
{
collectAssetInfos = collector.GetAllCollectAssets(EBuildMode.DryRunBuild, group);
bool enableAdressable = AssetBundleCollectorSettingData.Setting.EnableAddressable;
collectAssetInfos = collector.GetAllCollectAssets(EBuildMode.DryRunBuild, enableAdressable, group);
}
catch (System.Exception e)
{
@@ -602,7 +775,8 @@ namespace YooAsset.Editor
return;
Undo.RecordObject(AssetBundleCollectorSettingData.Setting, "YooAsset.AssetBundleCollectorWindow AddCollector");
AssetBundleCollectorSettingData.CreateCollector(selectGroup, string.Empty);
AssetBundleCollector collector = new AssetBundleCollector();
AssetBundleCollectorSettingData.CreateCollector(selectGroup, collector);
FillCollectorViewData();
}
private void RemoveCollectorBtn_clicked(AssetBundleCollector selectCollector)

View File

@@ -3,29 +3,41 @@
<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="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);" />
</uie:Toolbar>
<ui:VisualElement name="PublicContainer" style="height: 30px; background-color: rgb(67, 67, 67); flex-direction: row; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
<ui:Toggle label="Show Packages" name="ShowPackages" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Enable Addressable" name="EnableAddressable" style="width: 196px; -unity-text-align: middle-left;" />
</ui:VisualElement>
<ui:VisualElement name="ContentContainer" style="flex-grow: 1; flex-direction: row;">
<ui:VisualElement name="LeftContainer" 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;">
<ui:Label text="Packages" display-tooltip-when-elided="true" name="PackageTitle" style="background-color: rgb(89, 89, 89); -unity-text-align: upper-center; -unity-font-style: bold; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px; font-size: 12px;" />
<ui:ListView focusable="true" name="PackageListView" item-height="20" virtualization-method="DynamicHeight" style="flex-grow: 1;" />
<ui:VisualElement name="PackageAddContainer" style="height: 20px; flex-direction: row; justify-content: center;">
<ui:Button text=" - " display-tooltip-when-elided="true" name="RemoveBtn" />
<ui:Button text=" + " display-tooltip-when-elided="true" name="AddBtn" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="GroupContainer" style="width: 200px; flex-grow: 0; background-color: rgb(67, 67, 67); border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
<ui:Label text="Groups" display-tooltip-when-elided="true" name="GroupTitle" style="background-color: rgb(89, 89, 89); -unity-text-align: upper-center; -unity-font-style: bold; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px; font-size: 12px;" />
<ui:TextField picking-mode="Ignore" label="Package Name" value="filler text" name="PackageName" style="flex-direction: column;" />
<ui:TextField picking-mode="Ignore" label="Package Desc" value="filler text" name="PackageDesc" style="flex-direction: column;" />
<ui:ListView focusable="true" name="GroupListView" item-height="20" virtualization-method="DynamicHeight" style="flex-grow: 1;" />
<ui:VisualElement name="GroupAddContainer" style="height: 20px; flex-direction: row; justify-content: center;">
<ui:Button text=" - " display-tooltip-when-elided="true" name="RemoveBtn" />
<ui:Button text=" + " display-tooltip-when-elided="true" name="AddBtn" />
</ui:VisualElement>
</ui:VisualElement>
<ui:VisualElement name="RightContainer" style="flex-direction: column; flex-grow: 1;">
<ui:VisualElement name="PublicContainer" style="height: 30px; background-color: rgb(67, 67, 67); flex-direction: row; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
<ui:Toggle label="Enable Addressable" name="EnableAddressable" style="width: 196px; -unity-text-align: middle-left;" />
</ui:VisualElement>
<ui:VisualElement name="GroupContainer" style="flex-grow: 1; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
<ui:VisualElement name="ActiveRuleContainer" style="height: 20px;" />
<ui:TextField picking-mode="Ignore" label="Group Name" name="GroupName" />
<ui:TextField picking-mode="Ignore" label="Group Desc" name="GroupDesc" />
<ui:TextField picking-mode="Ignore" label="Group Asset Tags" name="GroupAssetTags" />
<ui:VisualElement name="CollectorAddContainer" style="height: 20px; flex-direction: row-reverse;">
<ui:Button text="[ + ]" display-tooltip-when-elided="true" name="AddBtn" />
</ui:VisualElement>
<ui:ScrollView name="CollectorScrollView" style="flex-grow: 1;" />
<ui:VisualElement name="CollectorContainer" style="flex-grow: 1; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px;">
<ui:Label text="Collectors" display-tooltip-when-elided="true" name="CollectorTitle" style="background-color: rgb(89, 89, 89); -unity-text-align: upper-center; -unity-font-style: bold; border-left-width: 5px; border-right-width: 5px; border-top-width: 5px; border-bottom-width: 5px; font-size: 12px;" />
<ui:VisualElement name="ActiveRuleContainer" style="height: 20px;" />
<ui:TextField picking-mode="Ignore" label="Group Name" name="GroupName" />
<ui:TextField picking-mode="Ignore" label="Group Desc" name="GroupDesc" />
<ui:TextField picking-mode="Ignore" label="Group Asset Tags" name="GroupAssetTags" />
<ui:VisualElement name="CollectorAddContainer" style="height: 20px; flex-direction: row-reverse;">
<ui:Button text="[ + ]" display-tooltip-when-elided="true" name="AddBtn" />
</ui:VisualElement>
<ui:ScrollView name="CollectorScrollView" style="flex-grow: 1;" />
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>

View File

@@ -259,7 +259,7 @@ namespace YooAsset.Editor
{
_dependListView.Clear();
_dependListView.ClearSelection();
_dependListView.itemsSource = providerInfo.BundleInfos;
_dependListView.itemsSource = providerInfo.DependBundleInfos;
_dependListView.Rebuild();
}
}

View File

@@ -75,7 +75,7 @@ namespace YooAsset.Editor
Dictionary<string, DebugBundleInfo> result = new Dictionary<string, DebugBundleInfo>(debugReport.ProviderInfos.Count);
foreach (var providerInfo in debugReport.ProviderInfos)
{
foreach (var bundleInfo in providerInfo.BundleInfos)
foreach (var bundleInfo in providerInfo.DependBundleInfos)
{
if (string.IsNullOrEmpty(searchKeyWord) == false)
{
@@ -264,7 +264,7 @@ namespace YooAsset.Editor
List<DebugProviderInfo> source = new List<DebugProviderInfo>();
foreach (var providerInfo in _debugReport.ProviderInfos)
{
foreach (var bundleInfo in providerInfo.BundleInfos)
foreach (var bundleInfo in providerInfo.DependBundleInfos)
{
if (bundleInfo.BundleName == bundleName)
{

View File

@@ -66,11 +66,9 @@ namespace YooAsset.Editor
_items.Add(new ItemWrapper("构建平台", $"{buildReport.Summary.BuildTarget}"));
_items.Add(new ItemWrapper("构建管线", $"{buildReport.Summary.BuildPipeline}"));
_items.Add(new ItemWrapper("构建模式", $"{buildReport.Summary.BuildMode}"));
_items.Add(new ItemWrapper("构建版本", $"{buildReport.Summary.BuildVersion}"));
_items.Add(new ItemWrapper("内置资源标签", $"{buildReport.Summary.BuildinTags}"));
_items.Add(new ItemWrapper("构建包裹", $"{buildReport.Summary.BuildPackage}"));
_items.Add(new ItemWrapper("启用可寻址资源定位", $"{buildReport.Summary.EnableAddressable}"));
_items.Add(new ItemWrapper("拷贝内置资源文件", $"{buildReport.Summary.CopyBuildinTagFiles}"));
_items.Add(new ItemWrapper("加密服务类名称", $"{buildReport.Summary.EncryptionServicesClassName}"));
_items.Add(new ItemWrapper(string.Empty, string.Empty));
@@ -86,8 +84,6 @@ namespace YooAsset.Editor
_items.Add(new ItemWrapper("主资源总数", $"{buildReport.Summary.MainAssetTotalCount}"));
_items.Add(new ItemWrapper("资源包总数", $"{buildReport.Summary.AllBundleTotalCount}"));
_items.Add(new ItemWrapper("资源包总大小", ConvertSize(buildReport.Summary.AllBundleTotalSize)));
_items.Add(new ItemWrapper("内置资源包总数", $"{buildReport.Summary.BuildinBundleTotalCount}"));
_items.Add(new ItemWrapper("内置资源包总大小", ConvertSize(buildReport.Summary.BuildinBundleTotalSize)));
_items.Add(new ItemWrapper("加密资源包总数", $"{buildReport.Summary.EncryptedBundleTotalCount}"));
_items.Add(new ItemWrapper("加密资源包总大小", ConvertSize(buildReport.Summary.EncryptedBundleTotalSize)));
_items.Add(new ItemWrapper("原生资源包总数", $"{buildReport.Summary.RawBundleTotalCount}"));

View File

@@ -353,6 +353,9 @@ namespace YooAsset.Editor
/// </summary>
public static void FileMoveTo(string filePath, string destPath)
{
if (File.Exists(destPath))
File.Delete(destPath);
FileInfo fileInfo = new FileInfo(filePath);
fileInfo.MoveTo(destPath);
}

View File

@@ -87,7 +87,7 @@ namespace YooAsset.Editor
List<string> allAssets = new List<string>(1000);
// 获取所有打包的资源
List<CollectAssetInfo> allCollectInfos = AssetBundleCollectorSettingData.Setting.GetAllCollectAssets(EBuildMode.DryRunBuild);
List<CollectAssetInfo> allCollectInfos = AssetBundleCollectorSettingData.Setting.GetAllPackageAssets(EBuildMode.DryRunBuild);
List<string> collectAssets = allCollectInfos.Select(t => t.AssetPath).ToList();
foreach (var assetPath in collectAssets)
{

View File

@@ -6,24 +6,26 @@ using UnityEngine.SceneManagement;
namespace YooAsset
{
internal static class AssetSystem
internal class AssetSystemImpl
{
private static readonly List<AssetBundleLoaderBase> _loaders = new List<AssetBundleLoaderBase>(1000);
private static readonly List<ProviderBase> _providers = new List<ProviderBase>(1000);
private static readonly Dictionary<string, SceneOperationHandle> _sceneHandles = new Dictionary<string, SceneOperationHandle>(100);
private static long _sceneCreateCount = 0;
private static string SceneRunningPackage = string.Empty;
private static bool _simulationOnEditor;
private static int _loadingMaxNumber;
public static IDecryptionServices DecryptionServices { private set; get; }
public static IBundleServices BundleServices { private set; get; }
private readonly List<AssetBundleLoaderBase> _loaders = new List<AssetBundleLoaderBase>(1000);
private readonly List<ProviderBase> _providers = new List<ProviderBase>(1000);
private readonly Dictionary<string, SceneOperationHandle> _sceneHandles = new Dictionary<string, SceneOperationHandle>(100);
private long _sceneCreateCount = 0;
private bool _simulationOnEditor;
private int _loadingMaxNumber;
public IDecryptionServices DecryptionServices { private set; get; }
public IBundleServices BundleServices { private set; get; }
/// <summary>
/// 初始化
/// 注意在使用AssetSystem之前需要初始化
/// </summary>
public static void Initialize(bool simulationOnEditor, int loadingMaxNumber, IDecryptionServices decryptionServices, IBundleServices bundleServices)
public void Initialize(bool simulationOnEditor, int loadingMaxNumber, IDecryptionServices decryptionServices, IBundleServices bundleServices)
{
_simulationOnEditor = simulationOnEditor;
_loadingMaxNumber = loadingMaxNumber;
@@ -34,7 +36,7 @@ namespace YooAsset
/// <summary>
/// 更新
/// </summary>
public static void Update()
public void Update()
{
// 更新加载器
foreach (var loader in _loaders)
@@ -67,7 +69,7 @@ namespace YooAsset
/// <summary>
/// 销毁
/// </summary>
public static void DestroyAll()
public void DestroyAll()
{
_loaders.Clear();
_providers.Clear();
@@ -80,7 +82,7 @@ namespace YooAsset
/// <summary>
/// 资源回收(卸载引用计数为零的资源)
/// </summary>
public static void UnloadUnusedAssets()
public void UnloadUnusedAssets()
{
if (_simulationOnEditor)
{
@@ -115,7 +117,7 @@ namespace YooAsset
/// <summary>
/// 强制回收所有资源
/// </summary>
public static void ForceUnloadAllAssets()
public void ForceUnloadAllAssets()
{
foreach (var provider in _providers)
{
@@ -136,7 +138,7 @@ namespace YooAsset
/// <summary>
/// 加载场景
/// </summary>
public static SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority)
public SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority)
{
if (assetInfo.IsInvalid)
{
@@ -145,6 +147,19 @@ namespace YooAsset
return completedProvider.CreateHandle<SceneOperationHandle>();
}
// 注意:场景只允许运行在一个资源包内
if (string.IsNullOrEmpty(SceneRunningPackage))
{
SceneRunningPackage = BundleServices.GetPackageName();
}
if (BundleServices.GetPackageName() != SceneRunningPackage)
{
CompletedProvider completedProvider = new CompletedProvider(assetInfo);
string error = $"Scene are allowed to running within only {SceneRunningPackage}";
completedProvider.SetCompleted(error);
return completedProvider.CreateHandle<SceneOperationHandle>();
}
// 如果加载的是主场景,则卸载所有缓存的场景
if (sceneMode == LoadSceneMode.Single)
{
@@ -156,9 +171,9 @@ namespace YooAsset
ProviderBase provider;
{
if (_simulationOnEditor)
provider = new DatabaseSceneProvider(providerGUID, assetInfo, sceneMode, activateOnLoad, priority);
provider = new DatabaseSceneProvider(this, providerGUID, assetInfo, sceneMode, activateOnLoad, priority);
else
provider = new BundledSceneProvider(providerGUID, assetInfo, sceneMode, activateOnLoad, priority);
provider = new BundledSceneProvider(this, providerGUID, assetInfo, sceneMode, activateOnLoad, priority);
provider.InitSpawnDebugInfo();
_providers.Add(provider);
}
@@ -171,7 +186,7 @@ namespace YooAsset
/// <summary>
/// 加载资源对象
/// </summary>
public static AssetOperationHandle LoadAssetAsync(AssetInfo assetInfo)
public AssetOperationHandle LoadAssetAsync(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
{
@@ -185,9 +200,9 @@ namespace YooAsset
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseAssetProvider(providerGUID, assetInfo);
provider = new DatabaseAssetProvider(this, providerGUID, assetInfo);
else
provider = new BundledAssetProvider(providerGUID, assetInfo);
provider = new BundledAssetProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providers.Add(provider);
}
@@ -197,7 +212,7 @@ namespace YooAsset
/// <summary>
/// 加载子资源对象
/// </summary>
public static SubAssetsOperationHandle LoadSubAssetsAsync(AssetInfo assetInfo)
public SubAssetsOperationHandle LoadSubAssetsAsync(AssetInfo assetInfo)
{
if (assetInfo.IsInvalid)
{
@@ -211,16 +226,16 @@ namespace YooAsset
if (provider == null)
{
if (_simulationOnEditor)
provider = new DatabaseSubAssetsProvider(providerGUID, assetInfo);
provider = new DatabaseSubAssetsProvider(this, providerGUID, assetInfo);
else
provider = new BundledSubAssetsProvider(providerGUID, assetInfo);
provider = new BundledSubAssetsProvider(this, providerGUID, assetInfo);
provider.InitSpawnDebugInfo();
_providers.Add(provider);
}
return provider.CreateHandle<SubAssetsOperationHandle>();
}
internal static void UnloadSubScene(ProviderBase provider)
internal void UnloadSubScene(ProviderBase provider)
{
string providerGUID = provider.ProviderGUID;
if (_sceneHandles.ContainsKey(providerGUID) == false)
@@ -231,9 +246,9 @@ namespace YooAsset
_sceneHandles.Remove(providerGUID);
// 卸载未被使用的资源(包括场景)
AssetSystem.UnloadUnusedAssets();
UnloadUnusedAssets();
}
internal static void UnloadAllScene()
internal void UnloadAllScene()
{
// 释放所有场景句柄
foreach (var valuePair in _sceneHandles)
@@ -243,15 +258,15 @@ namespace YooAsset
_sceneHandles.Clear();
// 卸载未被使用的资源(包括场景)
AssetSystem.UnloadUnusedAssets();
UnloadUnusedAssets();
}
internal static AssetBundleLoaderBase CreateOwnerAssetBundleLoader(AssetInfo assetInfo)
internal AssetBundleLoaderBase CreateOwnerAssetBundleLoader(AssetInfo assetInfo)
{
BundleInfo bundleInfo = BundleServices.GetBundleInfo(assetInfo);
return CreateAssetBundleLoaderInternal(bundleInfo);
}
internal static List<AssetBundleLoaderBase> CreateDependAssetBundleLoaders(AssetInfo assetInfo)
internal List<AssetBundleLoaderBase> CreateDependAssetBundleLoaders(AssetInfo assetInfo)
{
BundleInfo[] depends = BundleServices.GetAllDependBundleInfos(assetInfo);
List<AssetBundleLoaderBase> result = new List<AssetBundleLoaderBase>(depends.Length);
@@ -262,7 +277,7 @@ namespace YooAsset
}
return result;
}
internal static void RemoveBundleProviders(List<ProviderBase> providers)
internal void RemoveBundleProviders(List<ProviderBase> providers)
{
foreach (var provider in providers)
{
@@ -270,7 +285,7 @@ namespace YooAsset
}
}
private static AssetBundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo)
private AssetBundleLoaderBase CreateAssetBundleLoaderInternal(BundleInfo bundleInfo)
{
// 如果加载器已经存在
AssetBundleLoaderBase loader = TryGetAssetBundleLoader(bundleInfo.Bundle.BundleName);
@@ -279,15 +294,15 @@ namespace YooAsset
// 新增下载需求
#if UNITY_WEBGL
loader = new AssetBundleWebLoader(bundleInfo);
loader = new AssetBundleWebLoader(this, bundleInfo);
#else
loader = new AssetBundleFileLoader(bundleInfo);
loader = new AssetBundleFileLoader(this, bundleInfo);
#endif
_loaders.Add(loader);
return loader;
}
private static AssetBundleLoaderBase TryGetAssetBundleLoader(string bundleName)
private AssetBundleLoaderBase TryGetAssetBundleLoader(string bundleName)
{
AssetBundleLoaderBase loader = null;
for (int i = 0; i < _loaders.Count; i++)
@@ -301,7 +316,7 @@ namespace YooAsset
}
return loader;
}
private static ProviderBase TryGetProvider(string providerGUID)
private ProviderBase TryGetProvider(string providerGUID)
{
ProviderBase provider = null;
for (int i = 0; i < _providers.Count; i++)
@@ -316,37 +331,31 @@ namespace YooAsset
return provider;
}
#region
internal static DebugReport GetDebugReport()
#region
internal List<DebugProviderInfo> GetDebugReportInfos()
{
DebugReport report = new DebugReport();
report.FrameCount = Time.frameCount;
report.BundleCount = _loaders.Count;
report.AssetCount = _providers.Count;
List<DebugProviderInfo> result = new List<DebugProviderInfo>(_providers.Count);
foreach (var provider in _providers)
{
DebugProviderInfo providerInfo = new DebugProviderInfo();
providerInfo.PackageName = BundleServices.GetPackageName();
providerInfo.AssetPath = provider.MainAssetInfo.AssetPath;
providerInfo.SpawnScene = provider.SpawnScene;
providerInfo.SpawnTime = provider.SpawnTime;
providerInfo.RefCount = provider.RefCount;
providerInfo.Status = (int)provider.Status;
providerInfo.BundleInfos = new List<DebugBundleInfo>();
report.ProviderInfos.Add(providerInfo);
providerInfo.DependBundleInfos = new List<DebugBundleInfo>();
result.Add(providerInfo);
if (provider is BundledProvider)
{
BundledProvider temp = provider as BundledProvider;
temp.GetBundleDebugInfos(providerInfo.BundleInfos);
temp.GetBundleDebugInfos(providerInfo.DependBundleInfos);
}
}
// 重新排序
report.ProviderInfos.Sort();
return report;
return result;
}
internal static List<BundleInfo> GetLoadedBundleInfos()
internal List<BundleInfo> GetLoadedBundleInfos()
{
List<BundleInfo> result = new List<BundleInfo>(100);
foreach (var bundleLoader in _loaders)

View File

@@ -118,7 +118,7 @@ namespace YooAsset
// 卸载子场景
Scene sceneObject = SceneObject;
AssetSystem.UnloadSubScene(Provider);
Provider.Impl.UnloadSubScene(Provider);
{
var operation = new UnloadSceneOperation(sceneObject);
OperationSystem.StartOperation(operation);

View File

@@ -26,7 +26,7 @@ namespace YooAsset
private AssetBundleCreateRequest _createRequest;
public AssetBundleFileLoader(BundleInfo bundleInfo) : base(bundleInfo)
public AssetBundleFileLoader(AssetSystemImpl impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
@@ -105,13 +105,13 @@ namespace YooAsset
// Load assetBundle file
if (MainBundleInfo.Bundle.IsEncrypted)
{
if (AssetSystem.DecryptionServices == null)
if (Impl.DecryptionServices == null)
throw new Exception($"{nameof(AssetBundleFileLoader)} need {nameof(IDecryptionServices)} : {MainBundleInfo.Bundle.BundleName}");
DecryptionFileInfo fileInfo = new DecryptionFileInfo();
fileInfo.BundleName = MainBundleInfo.Bundle.BundleName;
fileInfo.FileHash = MainBundleInfo.Bundle.FileHash;
ulong offset = AssetSystem.DecryptionServices.GetFileOffset(fileInfo);
ulong offset = Impl.DecryptionServices.GetFileOffset(fileInfo);
if (_isWaitForAsyncComplete)
CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath, 0, offset);
else

View File

@@ -14,6 +14,11 @@ namespace YooAsset
Failed
}
/// <summary>
/// 所属资源系统
/// </summary>
public AssetSystemImpl Impl { private set; get; }
/// <summary>
/// 资源包文件信息
/// </summary>
@@ -43,8 +48,9 @@ namespace YooAsset
internal AssetBundle CacheBundle { set; get; }
public AssetBundleLoaderBase(BundleInfo bundleInfo)
public AssetBundleLoaderBase(AssetSystemImpl impl, BundleInfo bundleInfo)
{
Impl = impl;
MainBundleInfo = bundleInfo;
RefCount = 0;
Status = EStatus.None;
@@ -79,7 +85,7 @@ namespace YooAsset
/// 轮询更新
/// </summary>
public abstract void Update();
/// <summary>
/// 销毁
/// </summary>
@@ -148,7 +154,7 @@ namespace YooAsset
}
// 从列表里移除Providers
AssetSystem.RemoveBundleProviders(_providers);
Impl.RemoveBundleProviders(_providers);
_providers.Clear();
}

View File

@@ -31,7 +31,7 @@ namespace YooAsset
private AssetBundleCreateRequest _createRequest;
public AssetBundleWebLoader(BundleInfo bundleInfo) : base(bundleInfo)
public AssetBundleWebLoader(AssetSystemImpl impl, BundleInfo bundleInfo) : base(impl, bundleInfo)
{
}
@@ -110,13 +110,13 @@ namespace YooAsset
// Load assetBundle file
if (MainBundleInfo.Bundle.IsEncrypted)
{
if (AssetSystem.DecryptionServices == null)
if (Impl.DecryptionServices == null)
throw new Exception($"{nameof(AssetBundleFileLoader)} need {nameof(IDecryptionServices)} : {MainBundleInfo.Bundle.BundleName}");
DecryptionFileInfo fileInfo = new DecryptionFileInfo();
fileInfo.BundleName = MainBundleInfo.Bundle.BundleName;
fileInfo.FileHash = MainBundleInfo.Bundle.FileHash;
ulong offset = AssetSystem.DecryptionServices.GetFileOffset(fileInfo);
ulong offset = Impl.DecryptionServices.GetFileOffset(fileInfo);
_createRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath, 0, offset);
}
else

View File

@@ -17,7 +17,7 @@ namespace YooAsset
}
}
public BundledAssetProvider(string providerGUID, AssetInfo assetInfo) : base(providerGUID, assetInfo)
public BundledAssetProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
{
}
public override void Update()

View File

@@ -8,13 +8,13 @@ namespace YooAsset
protected AssetBundleLoaderBase OwnerBundle { private set; get; }
protected DependAssetBundleGroup DependBundleGroup { private set; get; }
public BundledProvider(string providerGUID, AssetInfo assetInfo) : base(providerGUID, assetInfo)
public BundledProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
{
OwnerBundle = AssetSystem.CreateOwnerAssetBundleLoader(assetInfo);
OwnerBundle = impl.CreateOwnerAssetBundleLoader(assetInfo);
OwnerBundle.Reference();
OwnerBundle.AddProvider(this);
var dependBundles = AssetSystem.CreateDependAssetBundleLoaders(assetInfo);
var dependBundles = impl.CreateDependAssetBundleLoaders(assetInfo);
DependBundleGroup = new DependAssetBundleGroup(dependBundles);
DependBundleGroup.Reference();
}

View File

@@ -23,7 +23,7 @@ namespace YooAsset
}
}
public BundledSceneProvider(string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) : base(providerGUID, assetInfo)
public BundledSceneProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) : base(impl, providerGUID, assetInfo)
{
SceneMode = sceneMode;
_sceneName = Path.GetFileNameWithoutExtension(assetInfo.AssetPath);

View File

@@ -17,7 +17,7 @@ namespace YooAsset
}
}
public BundledSubAssetsProvider(string providerGUID, AssetInfo assetInfo) : base(providerGUID, assetInfo)
public BundledSubAssetsProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
{
}
public override void Update()

View File

@@ -14,7 +14,7 @@ namespace YooAsset
}
}
public CompletedProvider(AssetInfo assetInfo) : base(string.Empty, assetInfo)
public CompletedProvider(AssetInfo assetInfo) : base(null, string.Empty, assetInfo)
{
}
public override void Update()

View File

@@ -17,7 +17,7 @@ namespace YooAsset
}
}
public DatabaseAssetProvider(string providerGUID, AssetInfo assetInfo) : base(providerGUID, assetInfo)
public DatabaseAssetProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
{
}
public override void Update()

View File

@@ -19,7 +19,7 @@ namespace YooAsset
}
}
public DatabaseSceneProvider(string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) : base(providerGUID, assetInfo)
public DatabaseSceneProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo, LoadSceneMode sceneMode, bool activateOnLoad, int priority) : base(impl, providerGUID, assetInfo)
{
SceneMode = sceneMode;
_activateOnLoad = activateOnLoad;

View File

@@ -17,7 +17,7 @@ namespace YooAsset
}
}
public DatabaseSubAssetsProvider(string providerGUID, AssetInfo assetInfo) : base(providerGUID, assetInfo)
public DatabaseSubAssetsProvider(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo) : base(impl, providerGUID, assetInfo)
{
}
public override void Update()

View File

@@ -22,6 +22,11 @@ namespace YooAsset
/// </summary>
public string ProviderGUID { private set; get; }
/// <summary>
/// 所属资源系统
/// </summary>
public AssetSystemImpl Impl { private set; get; }
/// <summary>
/// 资源信息
/// </summary>
@@ -90,8 +95,9 @@ namespace YooAsset
private readonly List<OperationHandleBase> _handles = new List<OperationHandleBase>();
public ProviderBase(string providerGUID, AssetInfo assetInfo)
public ProviderBase(AssetSystemImpl impl, string providerGUID, AssetInfo assetInfo)
{
Impl = impl;
ProviderGUID = providerGUID;
MainAssetInfo = assetInfo;
}

View File

@@ -13,13 +13,13 @@ namespace YooAsset
/// <summary>
/// 初始化时的验证级别
/// </summary>
public static EVerifyLevel InitVerifyLevel { private set; get; }
public static EVerifyLevel InitVerifyLevel { set; get; } = EVerifyLevel.Low;
public static void Initialize(EVerifyLevel initVerifyLevel)
{
InitVerifyLevel = initVerifyLevel;
}
public static void DestroyAll()
/// <summary>
/// 清空所有数据
/// </summary>
public static void ClearAll()
{
_cachedDic.Clear();
}

View File

@@ -11,7 +11,7 @@ namespace YooAsset
/// </summary>
internal abstract class PatchCacheVerifier
{
public abstract bool InitVerifier(PatchManifest appPatchManifest, PatchManifest localPatchManifest, bool weaklyUpdate);
public abstract bool InitVerifier(HostPlayModeImpl impl, bool weaklyUpdate);
public abstract bool UpdateVerifier();
public abstract float GetVerifierProgress();
@@ -42,22 +42,18 @@ namespace YooAsset
private int _verifyMaxNum;
private int _verifyTotalCount;
public override bool InitVerifier(PatchManifest appPatchManifest, PatchManifest localPatchManifest, bool weaklyUpdate)
public override bool InitVerifier(HostPlayModeImpl impl, bool weaklyUpdate)
{
// 遍历所有文件然后验证并缓存合法文件
foreach (var patchBundle in localPatchManifest.BundleList)
foreach (var patchBundle in impl.LocalPatchManifest.BundleList)
{
// 忽略缓存文件
if (CacheSystem.IsCached(patchBundle))
continue;
// 忽略APP资源
// 注意如果是APP资源并且哈希值相同则不需要下载
if (appPatchManifest.TryGetPatchBundle(patchBundle.BundleName, out PatchBundle appPatchBundle))
{
if (appPatchBundle.IsBuildin && appPatchBundle.Equals(patchBundle))
continue;
}
if (impl.IsBuildinPatchBundle(patchBundle))
continue;
// 注意:在弱联网模式下,我们需要验证指定资源版本的所有资源完整性
if (weaklyUpdate)
@@ -167,22 +163,18 @@ namespace YooAsset
private int _verifyMaxNum;
private int _verifyTotalCount;
public override bool InitVerifier(PatchManifest appPatchManifest, PatchManifest localPatchManifest, bool weaklyUpdate)
public override bool InitVerifier(HostPlayModeImpl impl, bool weaklyUpdate)
{
// 遍历所有文件然后验证并缓存合法文件
foreach (var patchBundle in localPatchManifest.BundleList)
foreach (var patchBundle in impl.LocalPatchManifest.BundleList)
{
// 忽略缓存文件
if (CacheSystem.IsCached(patchBundle))
continue;
// 忽略APP资源
// 注意如果是APP资源并且哈希值相同则不需要下载
if (appPatchManifest.TryGetPatchBundle(patchBundle.BundleName, out PatchBundle appPatchBundle))
{
if (appPatchBundle.IsBuildin && appPatchBundle.Equals(patchBundle))
continue;
}
if (impl.IsBuildinPatchBundle(patchBundle))
continue;
// 注意:在弱联网模式下,我们需要验证指定资源版本的所有资源完整性
if (weaklyUpdate)

View File

@@ -7,6 +7,11 @@ namespace YooAsset
[Serializable]
internal class DebugProviderInfo : IComparer<DebugProviderInfo>, IComparable<DebugProviderInfo>
{
/// <summary>
/// 所属的资源包裹
/// </summary>
public string PackageName;
/// <summary>
/// 资源对象路径
/// </summary>
@@ -35,7 +40,7 @@ namespace YooAsset
/// <summary>
/// 依赖的资源包列表
/// </summary>
public List<DebugBundleInfo> BundleInfos;
public List<DebugBundleInfo> DependBundleInfos;
public int CompareTo(DebugProviderInfo other)
{

View File

@@ -19,17 +19,6 @@ namespace YooAsset
/// </summary>
public int FrameCount;
/// <summary>
/// 资源包总数
/// </summary>
public int BundleCount;
/// <summary>
/// 资源对象总数
/// </summary>
public int AssetCount;
/// <summary>
/// 序列化
/// </summary>

View File

@@ -20,7 +20,7 @@ namespace YooAsset
{
if(UnityEditor.EditorApplication.isPlaying)
{
var report = AssetSystem.GetDebugReport();
var report = YooAssets.GetDebugReport();
EditorHandleDebugReportCallback?.Invoke(0, report);
}
}
@@ -39,7 +39,7 @@ namespace YooAsset
YooLogger.Log($"On handle remote command : {command.CommandType} Param : {command.CommandParam}");
if (command.CommandType == (int)ERemoteCommand.SampleOnce)
{
var debugReport = AssetSystem.GetDebugReport();
var debugReport = YooAssets.GetDebugReport();
var data = DebugReport.Serialize(debugReport);
PlayerConnection.instance.Send(RemoteDebuggerDefine.kMsgSendPlayerToEditor, data);
}

View File

@@ -14,16 +14,11 @@ namespace YooAsset
{
private static readonly Dictionary<string, DownloaderBase> _downloaderDic = new Dictionary<string, DownloaderBase>();
private static readonly List<string> _removeList = new List<string>(100);
private static int _breakpointResumeFileSize = int.MaxValue;
/// <summary>
/// 初始化
/// 启用断点续传的文件大小
/// </summary>
public static void Initialize(int breakpointResumeFileSize)
{
_breakpointResumeFileSize = breakpointResumeFileSize;
}
public static int BreakpointResumeFileSize { set; get; } = int.MaxValue;
/// <summary>
/// 更新所有下载器
@@ -59,7 +54,7 @@ namespace YooAsset
}
_downloaderDic.Clear();
_removeList.Clear();
_breakpointResumeFileSize = int.MaxValue;
BreakpointResumeFileSize = int.MaxValue;
}
@@ -86,7 +81,7 @@ namespace YooAsset
{
YooLogger.Log($"Beginning to download file : {bundleInfo.Bundle.FileName} URL : {bundleInfo.RemoteMainURL}");
FileUtility.CreateFileDirectory(bundleInfo.Bundle.CachedFilePath);
bool breakDownload = bundleInfo.Bundle.FileSize >= _breakpointResumeFileSize;
bool breakDownload = bundleInfo.Bundle.FileSize >= BreakpointResumeFileSize;
DownloaderBase newDownloader = new FileDownloader(bundleInfo, breakDownload);
newDownloader.SendRequest(failedTryAgain, timeout);
_downloaderDic.Add(bundleInfo.Bundle.CachedFilePath, newDownloader);

View File

@@ -0,0 +1,93 @@
using UnityEngine;
namespace YooAsset
{
/// <summary>
/// 运行模式
/// </summary>
public enum EPlayMode
{
/// <summary>
/// 编辑器下的模拟模式
/// 注意:在初始化的时候自动构建真机模拟环境。
/// </summary>
EditorSimulateMode,
/// <summary>
/// 离线运行模式
/// </summary>
OfflinePlayMode,
/// <summary>
/// 联机运行模式
/// </summary>
HostPlayMode,
}
/// <summary>
/// 初始化参数
/// </summary>
public abstract class InitializeParameters
{
/// <summary>
/// 资源定位地址大小写不敏感
/// 注意默认值为False
/// </summary>
public bool LocationToLower = false;
/// <summary>
/// 资源定位服务接口
/// </summary>
public ILocationServices LocationServices = null;
/// <summary>
/// 文件解密服务接口
/// </summary>
public IDecryptionServices DecryptionServices = null;
/// <summary>
/// 资源加载的最大数量
/// 注意默认值为MaxValue
/// </summary>
public int AssetLoadingMaxNumber = int.MaxValue;
}
/// <summary>
/// 编辑器下模拟运行模式的初始化参数
/// </summary>
public class EditorSimulateModeParameters : InitializeParameters
{
/// <summary>
/// 用于模拟运行的资源清单路径
/// </summary>
public string SimulatePatchManifestPath = string.Empty;
}
/// <summary>
/// 离线运行模式的初始化参数
/// </summary>
public class OfflinePlayModeParameters : InitializeParameters
{
}
/// <summary>
/// 联机运行模式的初始化参数
/// </summary>
public class HostPlayModeParameters : InitializeParameters
{
/// <summary>
/// 默认的资源服务器下载地址
/// </summary>
public string DefaultHostServer = string.Empty;
/// <summary>
/// 备用的资源服务器下载地址
/// </summary>
public string FallbackHostServer = string.Empty;
/// <summary>
/// 内置资源查询服务接口
/// </summary>
public IQueryServices QueryServices = null;
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 5c77e17c3a3a57548a218f1cd26f5a55
guid: a9b5e8a77215adb45b203be8a4fb9eda
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -10,9 +10,13 @@ namespace YooAsset
// 计时器相关
private static Stopwatch _watch;
private static long _maxTimeSlice;
private static long _frameTime;
/// <summary>
/// 异步操作的最小时间片段
/// </summary>
public static long MaxTimeSlice { set; get; } = long.MaxValue;
/// <summary>
/// 处理器是否繁忙
/// </summary>
@@ -20,7 +24,7 @@ namespace YooAsset
{
get
{
return _watch.ElapsedMilliseconds - _frameTime >= _maxTimeSlice;
return _watch.ElapsedMilliseconds - _frameTime >= MaxTimeSlice;
}
}
@@ -28,9 +32,8 @@ namespace YooAsset
/// <summary>
/// 初始化异步操作系统
/// </summary>
public static void Initialize(long maxTimeSlice)
public static void Initialize()
{
_maxTimeSlice = maxTimeSlice;
_watch = Stopwatch.StartNew();
}
@@ -63,8 +66,8 @@ namespace YooAsset
{
_operations.Clear();
_watch = null;
_maxTimeSlice = 0;
_frameTime = 0;
MaxTimeSlice = long.MaxValue;
}
/// <summary>

View File

@@ -1,60 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace YooAsset
{
[Serializable]
internal sealed class CacheData
{
/// <summary>
/// 缓存的APP内置版本
/// </summary>
public string CacheAppVersion = string.Empty;
/// <summary>
/// 读取缓存文件
/// 注意:如果文件不存在则创建新的缓存文件
/// </summary>
public static CacheData LoadCache()
{
string filePath = GetCacheDataFilePath();
if (File.Exists(filePath))
{
string jsonData = FileUtility.ReadFile(filePath);
var cacheData = JsonUtility.FromJson<CacheData>(jsonData);
YooLogger.Log($"Load cache data : {cacheData.CacheAppVersion}");
return cacheData;
}
else
{
YooLogger.Log($"Create cache data : {Application.version}");
CacheData cacheData = new CacheData();
cacheData.CacheAppVersion = Application.version;
string jsonData = JsonUtility.ToJson(cacheData);
FileUtility.CreateFile(filePath, jsonData);
return cacheData;
}
}
/// <summary>
/// 更新缓存文件
/// </summary>
public static void UpdateCache()
{
YooLogger.Log($"Update cache data to disk : {Application.version}");
CacheData cacheData = new CacheData();
cacheData.CacheAppVersion = Application.version;
string filePath = GetCacheDataFilePath();
string jsonData = JsonUtility.ToJson(cacheData);
FileUtility.CreateFile(filePath, jsonData);
}
private static string GetCacheDataFilePath()
{
return PathHelper.MakePersistentLoadPath("CacheData.bytes");
}
}
}

View File

@@ -1,111 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace YooAsset
{
/// <summary>
/// 清理未使用的缓存资源操作类
/// </summary>
public abstract class ClearUnusedCacheFilesOperation : AsyncOperationBase
{
}
/// <summary>
/// 编辑器模式
/// </summary>
internal sealed class EditorPlayModeClearUnusedCacheFilesOperation : ClearUnusedCacheFilesOperation
{
internal override void Start()
{
Status = EOperationStatus.Succeed;
}
internal override void Update()
{
}
}
/// <summary>
/// 离线模式
/// </summary>
internal sealed class OfflinePlayModeClearUnusedCacheFilesOperation : ClearUnusedCacheFilesOperation
{
internal override void Start()
{
Status = EOperationStatus.Succeed;
}
internal override void Update()
{
}
}
/// <summary>
/// 联机模式
/// </summary>
internal sealed class HostPlayModeClearUnusedCacheFilesOperation : ClearUnusedCacheFilesOperation
{
private enum ESteps
{
None,
GetUnusedCacheFiles,
ClearUnusedCacheFiles,
Done,
}
private ESteps _steps = ESteps.None;
private List<string> _unusedCacheFilePaths;
private int _unusedFileTotalCount = 0;
private HostPlayModeImpl _impl;
internal HostPlayModeClearUnusedCacheFilesOperation(HostPlayModeImpl impl)
{
_impl = impl;
}
internal override void Start()
{
_steps = ESteps.GetUnusedCacheFiles;
}
internal override void Update()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.GetUnusedCacheFiles)
{
_unusedCacheFilePaths = _impl.ClearUnusedCacheFilePaths();
_unusedFileTotalCount = _unusedCacheFilePaths.Count;
YooLogger.Log($"Found unused cache file count : {_unusedFileTotalCount}");
_steps = ESteps.ClearUnusedCacheFiles;
}
if (_steps == ESteps.ClearUnusedCacheFiles)
{
for (int i = _unusedCacheFilePaths.Count - 1; i >= 0; i--)
{
string filePath = _unusedCacheFilePaths[i];
if (File.Exists(filePath))
{
YooLogger.Log($"Delete unused cache file : {filePath}");
File.Delete(filePath);
}
_unusedCacheFilePaths.RemoveAt(i);
if (OperationSystem.IsBusy)
break;
}
if (_unusedFileTotalCount == 0)
Progress = 1.0f;
else
Progress = 1.0f - (_unusedCacheFilePaths.Count / _unusedFileTotalCount);
if (_unusedCacheFilePaths.Count == 0)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
}

View File

@@ -20,7 +20,6 @@ namespace YooAsset
private enum ESteps
{
None,
Builder,
Load,
Done,
}
@@ -36,26 +35,10 @@ namespace YooAsset
}
internal override void Start()
{
if (string.IsNullOrEmpty(_simulatePatchManifestPath))
_steps = ESteps.Builder;
else
_steps = ESteps.Load;
_steps = ESteps.Load;
}
internal override void Update()
{
if (_steps == ESteps.Builder)
{
_simulatePatchManifestPath = EditorSimulateModeHelper.SimulateBuild();
if (string.IsNullOrEmpty(_simulatePatchManifestPath))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Simulate build failed, see the detail info on the console window.";
return;
}
_steps = ESteps.Load;
}
if (_steps == ESteps.Load)
{
if (File.Exists(_simulatePatchManifestPath) == false)
@@ -89,12 +72,13 @@ namespace YooAsset
}
private readonly OfflinePlayModeImpl _impl;
private readonly AppManifestLoader _appManifestLoader = new AppManifestLoader();
private AppManifestLoader _appManifestLoader;
private ESteps _steps = ESteps.None;
internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl)
internal OfflinePlayModeInitializationOperation(OfflinePlayModeImpl impl, string buildinPackageName)
{
_impl = impl;
_appManifestLoader = new AppManifestLoader(buildinPackageName);
}
internal override void Start()
{
@@ -133,94 +117,15 @@ namespace YooAsset
/// </summary>
internal sealed class HostPlayModeInitializationOperation : InitializationOperation
{
private enum ESteps
internal HostPlayModeInitializationOperation()
{
None,
InitCache,
LoadManifest,
CopyManifest,
Done,
}
private readonly HostPlayModeImpl _impl;
private readonly AppManifestLoader _appManifestLoader = new AppManifestLoader();
private readonly AppManifestCopyer _appManifestCopyer = new AppManifestCopyer();
private ESteps _steps = ESteps.None;
internal HostPlayModeInitializationOperation(HostPlayModeImpl impl)
{
_impl = impl;
}
internal override void Start()
{
_steps = ESteps.InitCache;
Status = EOperationStatus.Succeed;
}
internal override void Update()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.InitCache)
{
// 每次启动时比对APP版本号是否一致
CacheData cacheData = CacheData.LoadCache();
if (cacheData.CacheAppVersion != Application.version)
{
YooLogger.Warning($"Cache is dirty ! Cache application version is {cacheData.CacheAppVersion}, Current application version is {Application.version}");
// 注意在覆盖安装的时候会保留APP沙盒目录可以选择清空缓存目录
if (_impl.ClearCacheWhenDirty)
{
YooLogger.Warning("Clear cache files.");
SandboxHelper.DeleteCacheFolder();
}
// 更新缓存文件
CacheData.UpdateCache();
}
_steps = ESteps.LoadManifest;
}
if (_steps == ESteps.LoadManifest)
{
_appManifestLoader.Update();
Progress = _appManifestLoader.Progress();
if (_appManifestLoader.IsDone() == false)
return;
if (_appManifestLoader.Result == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _appManifestLoader.Error;
}
else
{
_impl.SetAppPatchManifest(_appManifestLoader.Result);
_impl.SetLocalPatchManifest(_appManifestLoader.Result);
_appManifestCopyer.Init(_appManifestLoader.StaticVersion);
_steps = ESteps.CopyManifest;
}
}
if (_steps == ESteps.CopyManifest)
{
_appManifestCopyer.Update();
if (_appManifestCopyer.IsDone() == false)
return;
if (_appManifestCopyer.Result == false)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _appManifestCopyer.Error;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
}
}
@@ -239,6 +144,7 @@ namespace YooAsset
Done,
}
private string _buildinPackageName;
private ESteps _steps = ESteps.LoadStaticVersion;
private UnityWebDataRequester _downloader1;
private UnityWebDataRequester _downloader2;
@@ -254,9 +160,15 @@ namespace YooAsset
public PatchManifest Result { private set; get; }
/// <summary>
/// 内置补丁清单版本号
/// 内置补丁清单CRC
/// </summary>
public int StaticVersion { private set; get; }
public string BuildinPackageCRC { private set; get; }
public AppManifestLoader(string buildinPackageName)
{
_buildinPackageName = buildinPackageName;
}
/// <summary>
/// 是否已经完成
@@ -286,12 +198,13 @@ namespace YooAsset
if (_steps == ESteps.LoadStaticVersion)
{
YooLogger.Log($"Load application static version.");
string filePath = PathHelper.MakeStreamingLoadPath(YooAssetSettings.VersionFileName);
string fileName = YooAssetSettingsData.GetStaticVersionFileName(_buildinPackageName);
string filePath = PathHelper.MakeStreamingLoadPath(fileName);
string url = PathHelper.ConvertToWWWPath(filePath);
_downloader1 = new UnityWebDataRequester();
_downloader1.SendRequest(url);
_steps = ESteps.CheckStaticVersion;
YooLogger.Log($"Load static version file : {filePath}");
}
if (_steps == ESteps.CheckStaticVersion)
@@ -306,7 +219,7 @@ namespace YooAsset
}
else
{
StaticVersion = int.Parse(_downloader1.GetText());
BuildinPackageCRC = _downloader1.GetText();
_steps = ESteps.LoadAppManifest;
}
_downloader1.Dispose();
@@ -314,12 +227,13 @@ namespace YooAsset
if (_steps == ESteps.LoadAppManifest)
{
YooLogger.Log($"Load application patch manifest.");
string filePath = PathHelper.MakeStreamingLoadPath(YooAssetSettingsData.GetPatchManifestFileName(StaticVersion));
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_buildinPackageName, BuildinPackageCRC);
string filePath = PathHelper.MakeStreamingLoadPath(fileName);
string url = PathHelper.ConvertToWWWPath(filePath);
_downloader2 = new UnityWebDataRequester();
_downloader2.SendRequest(url);
_steps = ESteps.CheckAppManifest;
YooLogger.Log($"Load patch manifest file : {filePath}");
}
if (_steps == ESteps.CheckAppManifest)
@@ -355,10 +269,10 @@ namespace YooAsset
Done,
}
private string _buildinPackageName;
private string _buildinPackageCRC;
private ESteps _steps = ESteps.CopyAppManifest;
private UnityWebFileRequester _downloader1;
private int _staticVersion;
/// <summary>
/// 错误日志
@@ -370,20 +284,11 @@ namespace YooAsset
/// </summary>
public bool Result { private set; get; }
/// <summary>
/// 是否已经完成
/// </summary>
public bool IsDone()
{
return _steps == ESteps.Done;
}
/// <summary>
/// 初始化流程
/// </summary>
public void Init(int staticVersion)
public AppManifestCopyer(string buildinPackageName, string buildinPackageCRC)
{
_staticVersion = staticVersion;
_buildinPackageName = buildinPackageName;
_buildinPackageCRC = buildinPackageCRC;
}
/// <summary>
@@ -396,7 +301,8 @@ namespace YooAsset
if (_steps == ESteps.CopyAppManifest)
{
string destFilePath = PathHelper.MakePersistentLoadPath(YooAssetSettingsData.GetPatchManifestFileName(_staticVersion));
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_buildinPackageName, _buildinPackageCRC);
string destFilePath = PathHelper.MakePersistentLoadPath(fileName);
if (File.Exists(destFilePath))
{
Result = true;
@@ -406,7 +312,7 @@ namespace YooAsset
else
{
YooLogger.Log($"Copy application patch manifest.");
string sourceFilePath = PathHelper.MakeStreamingLoadPath(YooAssetSettingsData.GetPatchManifestFileName(_staticVersion));
string sourceFilePath = PathHelper.MakeStreamingLoadPath(fileName);
string url = PathHelper.ConvertToWWWPath(sourceFilePath);
_downloader1 = new UnityWebFileRequester();
_downloader1.SendRequest(url, destFilePath);
@@ -433,5 +339,13 @@ namespace YooAsset
_downloader1.Dispose();
}
}
/// <summary>
/// 是否已经完成
/// </summary>
public bool IsDone()
{
return _steps == ESteps.Done;
}
}
}

View File

@@ -52,8 +52,7 @@ namespace YooAsset
private enum ESteps
{
None,
LoadWebManifestHash,
CheckWebManifestHash,
CheckManifestHash,
LoadWebManifest,
CheckWebManifest,
InitVerifyingCache,
@@ -63,18 +62,19 @@ namespace YooAsset
private static int RequestCount = 0;
private readonly HostPlayModeImpl _impl;
private readonly int _resourceVersion;
private readonly string _packageName;
private readonly string _packageCRC;
private readonly int _timeout;
private ESteps _steps = ESteps.None;
private UnityWebDataRequester _downloader1;
private UnityWebDataRequester _downloader2;
private UnityWebDataRequester _downloader;
private PatchCacheVerifier _patchCacheVerifier;
private float _verifyTime;
internal HostPlayModeUpdateManifestOperation(HostPlayModeImpl impl, int resourceVersion, int timeout)
internal HostPlayModeUpdateManifestOperation(HostPlayModeImpl impl, string packageName, string packageCRC, int timeout)
{
_impl = impl;
_resourceVersion = resourceVersion;
_packageName = packageName;
_packageCRC = packageCRC;
_timeout = timeout;
#if UNITY_WEBGL
@@ -86,82 +86,59 @@ namespace YooAsset
internal override void Start()
{
RequestCount++;
_steps = ESteps.LoadWebManifestHash;
_steps = ESteps.CheckManifestHash;
}
internal override void Update()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadWebManifestHash)
if (_steps == ESteps.CheckManifestHash)
{
string webURL = GetPatchManifestRequestURL(YooAssetSettingsData.GetPatchManifestHashFileName(_resourceVersion));
YooLogger.Log($"Beginning to request patch manifest hash : {webURL}");
_downloader1 = new UnityWebDataRequester();
_downloader1.SendRequest(webURL, _timeout);
_steps = ESteps.CheckWebManifestHash;
}
string cachedManifestCRC = GetSandboxPatchManifestFileHash(_packageName, _packageCRC);
if (_steps == ESteps.CheckWebManifestHash)
{
if (_downloader1.IsDone() == false)
return;
// Check error
if (_downloader1.HasError())
// 如果补丁清单文件的哈希值相同
if (cachedManifestCRC == _packageCRC)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader1.GetError();
YooLogger.Log($"Patch manifest file hash is not change : {_packageCRC}");
LoadSandboxPatchManifest(_packageName, _packageCRC);
FoundNewManifest = false;
_steps = ESteps.InitVerifyingCache;
}
else
{
string webManifestHash = _downloader1.GetText();
string cachedManifestHash = GetSandboxPatchManifestFileHash(_resourceVersion);
// 如果补丁清单文件的哈希值相同
if (cachedManifestHash == webManifestHash)
{
YooLogger.Log($"Patch manifest file hash is not change : {webManifestHash}");
LoadSandboxPatchManifest(_resourceVersion);
FoundNewManifest = false;
_steps = ESteps.InitVerifyingCache;
}
else
{
YooLogger.Log($"Patch manifest hash is change : {webManifestHash} -> {cachedManifestHash}");
FoundNewManifest = true;
_steps = ESteps.LoadWebManifest;
}
YooLogger.Log($"Patch manifest hash is change : {cachedManifestCRC} -> {_packageCRC}");
FoundNewManifest = true;
_steps = ESteps.LoadWebManifest;
}
_downloader1.Dispose();
}
if (_steps == ESteps.LoadWebManifest)
{
string webURL = GetPatchManifestRequestURL(YooAssetSettingsData.GetPatchManifestFileName(_resourceVersion));
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_packageName, _packageCRC);
string webURL = GetPatchManifestRequestURL(fileName);
YooLogger.Log($"Beginning to request patch manifest : {webURL}");
_downloader2 = new UnityWebDataRequester();
_downloader2.SendRequest(webURL, _timeout);
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(webURL, _timeout);
_steps = ESteps.CheckWebManifest;
}
if (_steps == ESteps.CheckWebManifest)
{
if (_downloader2.IsDone() == false)
if (_downloader.IsDone() == false)
return;
// Check error
if (_downloader2.HasError())
if (_downloader.HasError())
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _downloader2.GetError();
Error = _downloader.GetError();
}
else
{
// 解析补丁清单
if (ParseAndSaveRemotePatchManifest(_resourceVersion, _downloader2.GetText()))
if (ParseAndSaveRemotePatchManifest(_packageName, _packageCRC, _downloader.GetText()))
{
_steps = ESteps.InitVerifyingCache;
}
@@ -169,15 +146,15 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"URL : {_downloader2.URL} Error : remote patch manifest content is invalid";
Error = $"URL : {_downloader.URL} Error : remote patch manifest content is invalid";
}
}
_downloader2.Dispose();
_downloader.Dispose();
}
if (_steps == ESteps.InitVerifyingCache)
{
_patchCacheVerifier.InitVerifier(_impl.AppPatchManifest, _impl.LocalPatchManifest, false);
_patchCacheVerifier.InitVerifier(_impl, false);
_verifyTime = UnityEngine.Time.realtimeSinceStartup;
_steps = ESteps.UpdateVerifyingCache;
}
@@ -210,7 +187,7 @@ namespace YooAsset
/// <summary>
/// 解析并保存远端请求的补丁清单
/// </summary>
private bool ParseAndSaveRemotePatchManifest(int updateResourceVersion, string content)
private bool ParseAndSaveRemotePatchManifest(string packageName, string packageCRC, string content)
{
try
{
@@ -218,7 +195,8 @@ namespace YooAsset
_impl.SetLocalPatchManifest(remotePatchManifest);
YooLogger.Log("Save remote patch manifest file.");
string savePath = PathHelper.MakePersistentLoadPath(YooAssetSettingsData.GetPatchManifestFileName(updateResourceVersion));
string fileName = YooAssetSettingsData.GetPatchManifestFileName(packageName, packageCRC);
string savePath = PathHelper.MakePersistentLoadPath(fileName);
PatchManifest.Serialize(savePath, remotePatchManifest);
return true;
}
@@ -233,10 +211,11 @@ namespace YooAsset
/// 加载沙盒内的补丁清单
/// 注意:在加载本地补丁清单之前,已经验证过文件的哈希值
/// </summary>
private void LoadSandboxPatchManifest(int updateResourceVersion)
private void LoadSandboxPatchManifest(string packageName, string packageCRC)
{
YooLogger.Log("Load sandbox patch manifest file.");
string filePath = PathHelper.MakePersistentLoadPath(YooAssetSettingsData.GetPatchManifestFileName(updateResourceVersion));
string fileName = YooAssetSettingsData.GetPatchManifestFileName(packageName, packageCRC);
string filePath = PathHelper.MakePersistentLoadPath(fileName);
string jsonData = File.ReadAllText(filePath);
var sandboxPatchManifest = PatchManifest.Deserialize(jsonData);
_impl.SetLocalPatchManifest(sandboxPatchManifest);
@@ -246,11 +225,12 @@ namespace YooAsset
/// 获取沙盒内补丁清单文件的哈希值
/// 注意:如果沙盒内补丁清单文件不存在,返回空字符串
/// </summary>
private string GetSandboxPatchManifestFileHash(int updateResourceVersion)
private string GetSandboxPatchManifestFileHash(string packageName, string packageCRC)
{
string filePath = PathHelper.MakePersistentLoadPath(YooAssetSettingsData.GetPatchManifestFileName(updateResourceVersion));
string fileName = YooAssetSettingsData.GetPatchManifestFileName(packageName, packageCRC);
string filePath = PathHelper.MakePersistentLoadPath(fileName);
if (File.Exists(filePath))
return HashUtility.FileMD5(filePath);
return HashUtility.FileCRC32(filePath);
else
return string.Empty;
}
@@ -271,15 +251,17 @@ namespace YooAsset
}
private readonly HostPlayModeImpl _impl;
private readonly int _resourceVersion;
private readonly string _packageName;
private readonly string _packageCRC;
private ESteps _steps = ESteps.None;
private PatchCacheVerifier _patchCacheVerifier;
private float _verifyTime;
internal HostPlayModeWeaklyUpdateManifestOperation(HostPlayModeImpl impl, int resourceVersion)
internal HostPlayModeWeaklyUpdateManifestOperation(HostPlayModeImpl impl, string packageName, string packageCRC)
{
_impl = impl;
_resourceVersion = resourceVersion;
_packageName = packageName;
_packageCRC = packageCRC;
#if UNITY_WEBGL
_patchCacheVerifier = new PatchCacheVerifierWithoutThread();
@@ -298,13 +280,13 @@ namespace YooAsset
if (_steps == ESteps.LoadSandboxManifestHash)
{
LoadSandboxPatchManifest(_resourceVersion);
LoadSandboxPatchManifest(_packageName, _packageCRC);
_steps = ESteps.InitVerifyingCache;
}
if (_steps == ESteps.InitVerifyingCache)
{
if (_patchCacheVerifier.InitVerifier(_impl.AppPatchManifest, _impl.LocalPatchManifest, true))
if (_patchCacheVerifier.InitVerifier(_impl, true))
{
_verifyTime = UnityEngine.Time.realtimeSinceStartup;
_steps = ESteps.UpdateVerifyingCache;
@@ -313,7 +295,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The resource version {_resourceVersion} content is not complete !";
Error = $"The package resource {_packageName}_{_packageCRC} content is not complete !";
}
}
@@ -328,7 +310,7 @@ namespace YooAsset
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"The resource version {_resourceVersion} content has verify failed file !";
Error = $"The package resource {_packageName}_{_packageCRC} content has verify failed file !";
}
else
{
@@ -343,9 +325,10 @@ namespace YooAsset
/// 加载沙盒内的补丁清单
/// 注意:在加载本地补丁清单之前,未验证过文件的哈希值
/// </summary>
private void LoadSandboxPatchManifest(int updateResourceVersion)
private void LoadSandboxPatchManifest(string packageName, string packageCRC)
{
string filePath = PathHelper.MakePersistentLoadPath(YooAssetSettingsData.GetPatchManifestFileName(updateResourceVersion));
string fileName = YooAssetSettingsData.GetPatchManifestFileName(packageName, packageCRC);
string filePath = PathHelper.MakePersistentLoadPath(fileName);
if (File.Exists(filePath))
{
YooLogger.Log("Load sandbox patch manifest file.");

View File

@@ -78,21 +78,23 @@ namespace YooAsset
private static int RequestCount = 0;
private readonly HostPlayModeImpl _impl;
private readonly int _resourceVersion;
private readonly string _packageName;
private readonly string _packageCRC;
private readonly int _timeout;
private ESteps _steps = ESteps.None;
private UnityWebDataRequester _downloader;
private PatchManifest _remotePatchManifest;
internal HostPlayModeUpdatePackageOperation(HostPlayModeImpl impl, int resourceVersion, int timeout)
internal HostPlayModeUpdatePackageOperation(HostPlayModeImpl impl, string packageName, string packageCRC, int timeout)
{
_impl = impl;
_resourceVersion = resourceVersion;
_packageName = packageName;
_packageCRC = packageCRC;
_timeout = timeout;
}
internal override void Start()
{
RequestCount++;
RequestCount++;
_steps = ESteps.LoadWebManifest;
}
internal override void Update()
@@ -102,7 +104,8 @@ namespace YooAsset
if (_steps == ESteps.LoadWebManifest)
{
string webURL = GetPatchManifestRequestURL(YooAssetSettingsData.GetPatchManifestFileName(_resourceVersion));
string fileName = YooAssetSettingsData.GetPatchManifestFileName(_packageName, _packageCRC);
string webURL = GetPatchManifestRequestURL(fileName);
YooLogger.Log($"Beginning to request patch manifest : {webURL}");
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(webURL, _timeout);
@@ -202,12 +205,8 @@ namespace YooAsset
continue;
// 忽略APP资源
// 注意如果是APP资源并且哈希值相同则不需要下载
if (_impl.AppPatchManifest.TryGetPatchBundle(patchBundle.BundleName, out PatchBundle appPatchBundle))
{
if (appPatchBundle.IsBuildin && appPatchBundle.Equals(patchBundle))
continue;
}
if (_impl.IsBuildinPatchBundle(patchBundle))
continue;
downloadList.Add(patchBundle);
}

View File

@@ -9,9 +9,9 @@ namespace YooAsset
public abstract class UpdateStaticVersionOperation : AsyncOperationBase
{
/// <summary>
/// 资源版本号
/// 包裹文件的哈希值
/// </summary>
public int ResourceVersion { protected set; get; } = 0;
public string PackageCRC { protected set; get; } = string.Empty;
}
/// <summary>
@@ -57,13 +57,15 @@ namespace YooAsset
private static int RequestCount = 0;
private readonly HostPlayModeImpl _impl;
private readonly string _packageName;
private readonly int _timeout;
private ESteps _steps = ESteps.None;
private UnityWebDataRequester _downloader;
internal HostPlayModeUpdateStaticVersionOperation(HostPlayModeImpl impl, int timeout)
internal HostPlayModeUpdateStaticVersionOperation(HostPlayModeImpl impl, string packageName, int timeout)
{
_impl = impl;
_packageName = packageName;
_timeout = timeout;
}
internal override void Start()
@@ -78,7 +80,8 @@ namespace YooAsset
if (_steps == ESteps.LoadStaticVersion)
{
string webURL = GetStaticVersionRequestURL(YooAssetSettings.VersionFileName);
string versionFileName = YooAssetSettingsData.GetStaticVersionFileName(_packageName);
string webURL = GetStaticVersionRequestURL(versionFileName);
YooLogger.Log($"Beginning to request static version : {webURL}");
_downloader = new UnityWebDataRequester();
_downloader.SendRequest(webURL, _timeout);
@@ -99,17 +102,18 @@ namespace YooAsset
}
else
{
if (int.TryParse(_downloader.GetText(), out int value))
{
ResourceVersion = value;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
else
string packageCRC = _downloader.GetText();
if(string.IsNullOrEmpty(packageCRC))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"URL : {_downloader.URL} Error : static version content is invalid.";
Error = $"URL : {_downloader.URL} Error : static version content is empty.";
}
else
{
PackageCRC = packageCRC;
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
_downloader.Dispose();

View File

@@ -38,21 +38,16 @@ namespace YooAsset
public int Flags;
/// <summary>
/// 是否为加密文件
/// </summary>
public bool IsEncrypted { private set; get; }
/// <summary>
/// 是否为内置文件
/// </summary>
public bool IsBuildin { private set; get; }
/// <summary>
/// 是否为原生文件
/// </summary>
public bool IsRawFile { private set; get; }
/// <summary>
/// 是否为加密文件
/// </summary>
public bool IsEncrypted { private set; get; }
/// <summary>
/// 文件名称
/// </summary>
@@ -69,7 +64,7 @@ namespace YooAsset
if (string.IsNullOrEmpty(_cachedFilePath) == false)
return _cachedFilePath;
string cacheRoot = SandboxHelper.GetCacheFolderPath();
string cacheRoot = SandboxHelper.GetCacheFolderPath();
_cachedFilePath = $"{cacheRoot}/{FileName}";
return _cachedFilePath;
}
@@ -104,16 +99,14 @@ namespace YooAsset
/// <summary>
/// 设置Flags
/// </summary>
public void SetFlagsValue(bool isEncrypted, bool isBuildin, bool isRawFile)
public void SetFlagsValue(bool isRawFile, bool isEncrypted)
{
IsEncrypted = isEncrypted;
IsBuildin = isBuildin;
IsRawFile = isRawFile;
IsEncrypted = isEncrypted;
BitMask32 mask = new BitMask32(0);
if (isEncrypted) mask.Open(0);
if (isBuildin) mask.Open(1);
if (isRawFile) mask.Open(2);
if (isRawFile) mask.Open(0);
if (isEncrypted) mask.Open(1);
Flags = mask;
}
@@ -123,9 +116,8 @@ namespace YooAsset
public void ParseFlagsValue()
{
BitMask32 value = Flags;
IsEncrypted = value.Test(0);
IsBuildin = value.Test(1);
IsRawFile = value.Test(2);
IsRawFile = value.Test(0);
IsEncrypted = value.Test(1);
}
/// <summary>
@@ -179,11 +171,11 @@ namespace YooAsset
}
/// <summary>
/// 是否为纯内置资源不带任何Tag的资源
/// 是否包含任意Tags
/// </summary>
public bool IsPureBuildin()
public bool HasAnyTags()
{
if (Tags == null || Tags.Length == 0)
if (Tags != null && Tags.Length > 0)
return true;
else
return false;
@@ -196,7 +188,7 @@ namespace YooAsset
{
if (FileHash == otherBundle.FileHash)
return true;
return false;
}
}

View File

@@ -17,11 +17,6 @@ namespace YooAsset
/// </summary>
public string FileVersion;
/// <summary>
/// 资源版本号
/// </summary>
public int ResourceVersion;
/// <summary>
/// 启用可寻址资源定位
/// </summary>
@@ -33,9 +28,9 @@ namespace YooAsset
public int OutputNameStyle;
/// <summary>
/// 内置资源的标签列表(首包资源)
/// 资源包裹名称
/// </summary>
public string BuildinTags;
public string PackageName;
/// <summary>
/// 资源列表(主动收集的资源列表)

View File

@@ -3,20 +3,22 @@ using System.Reflection;
namespace YooAsset
{
internal static class EditorSimulateModeHelper
public static class EditorSimulateModeHelper
{
private static System.Type _classType;
public static string SimulateBuild()
/// <summary>
/// 编辑器下模拟构建补丁清单
/// </summary>
public static string SimulateBuild(string packageName, bool enableAddressable)
{
_classType = Assembly.Load("YooAsset.Editor").GetType("YooAsset.Editor.AssetBundleSimulateBuilder");
InvokePublicStaticMethod(_classType, "SimulateBuild");
return GetPatchManifestFilePath();
}
private static string GetPatchManifestFilePath()
{
return (string)InvokePublicStaticMethod(_classType, "GetPatchManifestPath");
if (_classType == null)
_classType = Assembly.Load("YooAsset.Editor").GetType("YooAsset.Editor.AssetBundleSimulateBuilder");
string manifestFilePath = (string)InvokePublicStaticMethod(_classType, "SimulateBuild", packageName, enableAddressable);
return manifestFilePath;
}
private static object InvokePublicStaticMethod(System.Type type, string method, params object[] parameters)
{
var methodInfo = type.GetMethod(method, BindingFlags.Public | BindingFlags.Static);
@@ -30,8 +32,14 @@ namespace YooAsset
}
}
#else
internal static class EditorSimulateModeHelper
namespace YooAsset
{
public static class EditorSimulateModeHelper
{
public static string SimulateBuild() { throw new System.Exception("Only support in unity editor !"); }
/// <summary>
/// 编辑器下模拟构建补丁清单
/// </summary>
public static string SimulateBuild(string packageName, bool enableAddressable) { throw new System.Exception("Only support in unity editor !"); }
}
}
#endif

View File

@@ -20,16 +20,6 @@ namespace YooAsset
return operation;
}
/// <summary>
/// 获取资源版本号
/// </summary>
public int GetResourceVersion()
{
if (_simulatePatchManifest == null)
return 0;
return _simulatePatchManifest.ResourceVersion;
}
// 设置资源清单
internal void SetSimulatePatchManifest(PatchManifest patchManifest)
{
@@ -67,6 +57,10 @@ namespace YooAsset
{
return _simulatePatchManifest.MappingToAssetPath(location);
}
string IBundleServices.GetPackageName()
{
return _simulatePatchManifest.PackageName;
}
#endregion
}
}

View File

@@ -8,31 +8,25 @@ namespace YooAsset
internal class HostPlayModeImpl : IBundleServices
{
// 补丁清单
internal PatchManifest AppPatchManifest { private set; get; }
internal PatchManifest LocalPatchManifest { private set; get; }
// 参数相关
private bool _locationToLower;
private bool _clearCacheWhenDirty;
private string _defaultHostServer;
private string _fallbackHostServer;
public bool ClearCacheWhenDirty
{
get { return _clearCacheWhenDirty; }
}
private IQueryServices _queryServices;
/// <summary>
/// 异步初始化
/// </summary>
public InitializationOperation InitializeAsync(bool locationToLower, bool clearCacheWhenDirty, string defaultHostServer, string fallbackHostServer)
public InitializationOperation InitializeAsync(bool locationToLower, string defaultHostServer, string fallbackHostServer, IQueryServices queryServices)
{
_locationToLower = locationToLower;
_clearCacheWhenDirty = clearCacheWhenDirty;
_defaultHostServer = defaultHostServer;
_fallbackHostServer = fallbackHostServer;
_queryServices = queryServices;
var operation = new HostPlayModeInitializationOperation(this);
var operation = new HostPlayModeInitializationOperation();
OperationSystem.StartOperation(operation);
return operation;
}
@@ -40,9 +34,9 @@ namespace YooAsset
/// <summary>
/// 异步更新资源版本号
/// </summary>
public UpdateStaticVersionOperation UpdateStaticVersionAsync(int timeout)
public UpdateStaticVersionOperation UpdateStaticVersionAsync(string packageName, int timeout)
{
var operation = new HostPlayModeUpdateStaticVersionOperation(this, timeout);
var operation = new HostPlayModeUpdateStaticVersionOperation(this, packageName, timeout);
OperationSystem.StartOperation(operation);
return operation;
}
@@ -50,9 +44,9 @@ namespace YooAsset
/// <summary>
/// 异步更新补丁清单
/// </summary>
public UpdateManifestOperation UpdatePatchManifestAsync(int resourceVersion, int timeout)
public UpdateManifestOperation UpdatePatchManifestAsync(string packageName, string packageCRC, int timeout)
{
var operation = new HostPlayModeUpdateManifestOperation(this, resourceVersion, timeout);
var operation = new HostPlayModeUpdateManifestOperation(this, packageName, packageCRC, timeout);
OperationSystem.StartOperation(operation);
return operation;
}
@@ -60,9 +54,9 @@ namespace YooAsset
/// <summary>
/// 异步更新补丁清单(弱联网)
/// </summary>
public UpdateManifestOperation WeaklyUpdatePatchManifestAsync(int resourceVersion)
public UpdateManifestOperation WeaklyUpdatePatchManifestAsync(string packageName, string packageCRC)
{
var operation = new HostPlayModeWeaklyUpdateManifestOperation(this, resourceVersion);
var operation = new HostPlayModeWeaklyUpdateManifestOperation(this, packageName, packageCRC);
OperationSystem.StartOperation(operation);
return operation;
}
@@ -70,52 +64,13 @@ namespace YooAsset
/// <summary>
/// 异步更新资源包裹
/// </summary>
public UpdatePackageOperation UpdatePackageAsync(int resourceVersion, int timeout)
public UpdatePackageOperation UpdatePackageAsync(string packageName, string packageCRC, int timeout)
{
var operation = new HostPlayModeUpdatePackageOperation(this, resourceVersion, timeout);
var operation = new HostPlayModeUpdatePackageOperation(this, packageName, packageCRC, timeout);
OperationSystem.StartOperation(operation);
return operation;
}
/// <summary>
/// 获取资源版本号
/// </summary>
public int GetResourceVersion()
{
if (LocalPatchManifest == null)
return 0;
return LocalPatchManifest.ResourceVersion;
}
/// <summary>
/// 获取未被使用的缓存文件路径集合
/// </summary>
public List<string> ClearUnusedCacheFilePaths()
{
string cacheFolderPath = SandboxHelper.GetCacheFolderPath();
if (Directory.Exists(cacheFolderPath) == false)
return new List<string>();
DirectoryInfo directoryInfo = new DirectoryInfo(cacheFolderPath);
FileInfo[] fileInfos = directoryInfo.GetFiles();
List<string> result = new List<string>(fileInfos.Length);
foreach (FileInfo fileInfo in fileInfos)
{
bool used = false;
foreach (var patchBundle in LocalPatchManifest.BundleList)
{
if (fileInfo.Name == patchBundle.FileName)
{
used = true;
break;
}
}
if (used == false)
result.Add(fileInfo.FullName);
}
return result;
}
/// <summary>
/// 创建下载器
/// </summary>
@@ -135,12 +90,8 @@ namespace YooAsset
continue;
// 忽略APP资源
// 注意如果是APP资源并且哈希值相同则不需要下载
if (AppPatchManifest.TryGetPatchBundle(patchBundle.BundleName, out PatchBundle appPatchBundle))
{
if (appPatchBundle.IsBuildin && appPatchBundle.Equals(patchBundle))
continue;
}
if (IsBuildinPatchBundle(patchBundle))
continue;
downloadList.Add(patchBundle);
}
@@ -167,17 +118,11 @@ namespace YooAsset
continue;
// 忽略APP资源
// 注意如果是APP资源并且哈希值相同则不需要下载
if (AppPatchManifest.TryGetPatchBundle(patchBundle.BundleName, out PatchBundle appPatchBundle))
{
if (appPatchBundle.IsBuildin && appPatchBundle.Equals(patchBundle))
continue;
}
if (IsBuildinPatchBundle(patchBundle))
continue;
// 如果是纯内置资源,则统一下载
// 注意:可能是新增的或者变化的内置资源
// 注意:可能是由热更资源转换的内置资源
if (patchBundle.IsPureBuildin())
// 如果未带任何标记,则统一下载
if (patchBundle.HasAnyTags() == false)
{
downloadList.Add(patchBundle);
}
@@ -237,12 +182,8 @@ namespace YooAsset
continue;
// 忽略APP资源
// 注意如果是APP资源并且哈希值相同则不需要下载
if (AppPatchManifest.TryGetPatchBundle(patchBundle.BundleName, out PatchBundle appPatchBundle))
{
if (appPatchBundle.IsBuildin && appPatchBundle.Equals(patchBundle))
continue;
}
if (IsBuildinPatchBundle(patchBundle))
continue;
downloadList.Add(patchBundle);
}
@@ -262,20 +203,19 @@ namespace YooAsset
private List<BundleInfo> GetUnpackListByTags(string[] tags)
{
List<PatchBundle> downloadList = new List<PatchBundle>(1000);
foreach (var patchBundle in AppPatchManifest.BundleList)
foreach (var patchBundle in LocalPatchManifest.BundleList)
{
// 如果不是内置资源
if (patchBundle.IsBuildin == false)
continue;
// 忽略缓存文件
if (CacheSystem.IsCached(patchBundle))
continue;
// 查询DLC资源
if (patchBundle.HasTag(tags))
if (IsBuildinPatchBundle(patchBundle))
{
downloadList.Add(patchBundle);
if (patchBundle.HasTag(tags))
{
downloadList.Add(patchBundle);
}
}
}
@@ -294,17 +234,16 @@ namespace YooAsset
private List<BundleInfo> GetUnpackListByAll()
{
List<PatchBundle> downloadList = new List<PatchBundle>(1000);
foreach (var patchBundle in AppPatchManifest.BundleList)
foreach (var patchBundle in LocalPatchManifest.BundleList)
{
// 如果不是内置资源
if (patchBundle.IsBuildin == false)
continue;
// 忽略缓存文件
if (CacheSystem.IsCached(patchBundle))
continue;
downloadList.Add(patchBundle);
if (IsBuildinPatchBundle(patchBundle))
{
downloadList.Add(patchBundle);
}
}
return PatchHelper.ConvertToUnpackList(downloadList);
@@ -339,16 +278,15 @@ namespace YooAsset
return bundleInfo;
}
// 设置资源清单
internal void SetAppPatchManifest(PatchManifest patchManifest)
{
AppPatchManifest = patchManifest;
}
internal void SetLocalPatchManifest(PatchManifest patchManifest)
{
LocalPatchManifest = patchManifest;
LocalPatchManifest.InitAssetPathMapping(_locationToLower);
}
internal bool IsBuildinPatchBundle(PatchBundle patchBundle)
{
return _queryServices.QueryStreamingAssets(patchBundle.FileName);
}
#region IBundleServices接口
private BundleInfo CreateBundleInfo(PatchBundle patchBundle)
@@ -364,13 +302,10 @@ namespace YooAsset
}
// 查询APP资源
if (AppPatchManifest.TryGetPatchBundle(patchBundle.BundleName, out PatchBundle appPatchBundle))
if (IsBuildinPatchBundle(patchBundle))
{
if (appPatchBundle.IsBuildin && appPatchBundle.Equals(patchBundle))
{
BundleInfo bundleInfo = new BundleInfo(appPatchBundle, BundleInfo.ELoadMode.LoadFromStreaming);
return bundleInfo;
}
BundleInfo bundleInfo = new BundleInfo(patchBundle, BundleInfo.ELoadMode.LoadFromStreaming);
return bundleInfo;
}
// 从服务端下载
@@ -415,6 +350,10 @@ namespace YooAsset
{
return LocalPatchManifest.MappingToAssetPath(location);
}
string IBundleServices.GetPackageName()
{
return LocalPatchManifest.PackageName;
}
#endregion
}
}

View File

@@ -12,24 +12,14 @@ namespace YooAsset
/// <summary>
/// 异步初始化
/// </summary>
public InitializationOperation InitializeAsync(bool locationToLower)
public InitializationOperation InitializeAsync(bool locationToLower, string buildinPackageName)
{
_locationToLower = locationToLower;
var operation = new OfflinePlayModeInitializationOperation(this);
var operation = new OfflinePlayModeInitializationOperation(this, buildinPackageName);
OperationSystem.StartOperation(operation);
return operation;
}
/// <summary>
/// 获取资源版本号
/// </summary>
public int GetResourceVersion()
{
if (_appPatchManifest == null)
return 0;
return _appPatchManifest.ResourceVersion;
}
// 设置资源清单
internal void SetAppPatchManifest(PatchManifest patchManifest)
{
@@ -95,6 +85,10 @@ namespace YooAsset
{
return _appPatchManifest.MappingToAssetPath(location);
}
string IBundleServices.GetPackageName()
{
return _appPatchManifest.PackageName;
}
#endregion
}
}

View File

@@ -27,5 +27,10 @@ namespace YooAsset
/// 映射为资源路径
/// </summary>
string MappingToAssetPath(string location);
/// <summary>
/// 获取所属的包裹名
/// </summary>
string GetPackageName();
}
}

View File

@@ -6,6 +6,6 @@ namespace YooAsset
/// <summary>
/// 定位地址转换为资源路径
/// </summary>
string ConvertLocationToAssetPath(string location);
string ConvertLocationToAssetPath(YooAssetPackage package, string location);
}
}

View File

@@ -0,0 +1,11 @@

namespace YooAsset
{
public interface IQueryServices
{
/// <summary>
/// 查询内置资源
/// </summary>
bool QueryStreamingAssets(string fileName);
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f4c94d5687e1d884d833f88928d048c9
guid: 71b4ac2c7d7f15b40a457f355d535f33
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -3,9 +3,9 @@ namespace YooAsset
{
public class AddressLocationServices : ILocationServices
{
string ILocationServices.ConvertLocationToAssetPath(string location)
string ILocationServices.ConvertLocationToAssetPath(YooAssetPackage package, string location)
{
return YooAssets.MappingToAssetPath(location);
return package.MappingToAssetPath(location);
}
}
}

View File

@@ -11,16 +11,16 @@ namespace YooAsset
_resourceRoot = PathHelper.GetRegularPath(resourceRoot);
}
string ILocationServices.ConvertLocationToAssetPath(string location)
string ILocationServices.ConvertLocationToAssetPath(YooAssetPackage package, string location)
{
if (string.IsNullOrEmpty(_resourceRoot))
{
return YooAssets.MappingToAssetPath(location);
return package.MappingToAssetPath(location);
}
else
{
string tempLocation = $"{_resourceRoot}/{location}";
return YooAssets.MappingToAssetPath(tempLocation);
return package.MappingToAssetPath(tempLocation);
}
}
}

View File

@@ -24,7 +24,7 @@ namespace YooAsset
/// <summary>
/// 补丁清单文件版本
/// </summary>
public const string PatchManifestFileVersion = "1.2.2";
public const string PatchManifestFileVersion = "1.3.0";
/// <summary>
/// 构建输出文件夹名称
@@ -39,7 +39,7 @@ namespace YooAsset
/// <summary>
/// 静态版本文件
/// </summary>
public const string VersionFileName = "StaticVersion.bytes";
public const string VersionFileName = "StaticVersion";
/// <summary>
/// Unity着色器资源包名称

View File

@@ -35,25 +35,33 @@ namespace YooAsset
/// <summary>
/// 获取构建报告文件名
/// </summary>
public static string GetReportFileName(int resourceVersion)
public static string GetReportFileName(string packageName, string packageCRC)
{
return $"{YooAssetSettings.ReportFileName}_{resourceVersion}.json";
return $"{YooAssetSettings.ReportFileName}_{packageName}_{packageCRC}.json";
}
/// <summary>
/// 获取补丁清单文件完整名称
/// </summary>
public static string GetPatchManifestFileName(int resourceVersion)
public static string GetPatchManifestFileName(string packageName, string packageCRC)
{
return $"{Setting.PatchManifestFileName}_{resourceVersion}.bytes";
return $"{Setting.PatchManifestFileName}_{packageName}_{packageCRC}.bytes";
}
/// <summary>
/// 获取补丁清单哈希文件完整名称
/// 获取补丁清单文件临时名称
/// </summary>
public static string GetPatchManifestHashFileName(int resourceVersion)
public static string GetPatchManifestTempFileName(string packageName)
{
return $"{Setting.PatchManifestFileName}_{resourceVersion}.hash";
return $"{Setting.PatchManifestFileName}_{packageName}.temp";
}
/// <summary>
/// 获取静态版本文件名称
/// </summary>
public static string GetStaticVersionFileName(string packageName)
{
return $"{YooAssetSettings.VersionFileName}_{packageName}.bytes";
}
/// <summary>

View File

@@ -6,12 +6,17 @@ namespace YooAsset
{
void Update()
{
YooAssets.InternalUpdate();
YooAssets.Update();
}
void OnDestroy()
{
YooAssets.Destroy();
}
void OnApplicationQuit()
{
YooAssets.InternalDestroy();
YooAssets.Destroy();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 37a7daecdb1361140b44ba4724e8866e
guid: 6fcda791b973f5b4499e8bd3ede91312
MonoImporter:
externalObjects: {}
serializedVersion: 2

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,409 @@
using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
namespace YooAsset
{
public static partial class YooAssets
{
private static YooAssetPackage _mainPackage;
/// <summary>
/// 是否已经初始化
/// </summary>
public static bool IsInitialized
{
get { return _mainPackage.IsInitialized; }
}
/// <summary>
/// 异步初始化
/// </summary>
public static InitializationOperation InitializeAsync(InitializeParameters parameters, string packageName = "DefaultPackage")
{
if (_mainPackage != null)
throw new Exception("Main package is initialized yet.");
_mainPackage = CreateAssetPackage(packageName);
return _mainPackage.InitializeAsync(parameters);
}
/// <summary>
/// 向网络端请求静态资源版本
/// </summary>
/// <param name="timeout">超时时间默认值60秒</param>
public static UpdateStaticVersionOperation UpdateStaticVersionAsync(int timeout = 60)
{
return _mainPackage.UpdateStaticVersionAsync(timeout);
}
/// <summary>
/// 向网络端请求并更新补丁清单
/// </summary>
/// <param name="packageCRC">更新的资源包裹版本</param>
/// <param name="timeout">超时时间默认值60秒</param>
public static UpdateManifestOperation UpdateManifestAsync(string packageCRC, int timeout = 60)
{
return _mainPackage.UpdateManifestAsync(packageCRC, timeout);
}
/// <summary>
/// 弱联网情况下加载补丁清单
/// 注意:当指定版本内容验证失败后会返回失败。
/// </summary>
/// <param name="packageCRC">指定的资源包裹版本</param>
public static UpdateManifestOperation WeaklyUpdateManifestAsync(string packageCRC)
{
return _mainPackage.WeaklyUpdateManifestAsync(packageCRC);
}
/// <summary>
/// 资源回收(卸载引用计数为零的资源)
/// </summary>
public static void UnloadUnusedAssets()
{
_mainPackage.UnloadUnusedAssets();
}
/// <summary>
/// 强制回收所有资源
/// </summary>
public static void ForceUnloadAllAssets()
{
_mainPackage.ForceUnloadAllAssets();
}
#region
/// <summary>
/// 是否需要从远端更新下载
/// </summary>
/// <param name="location">资源的定位地址</param>
public static bool IsNeedDownloadFromRemote(string location)
{
return _mainPackage.IsNeedDownloadFromRemote(location);
}
/// <summary>
/// 是否需要从远端更新下载
/// </summary>
/// <param name="location">资源的定位地址</param>
public static bool IsNeedDownloadFromRemote(AssetInfo assetInfo)
{
return _mainPackage.IsNeedDownloadFromRemote(assetInfo);
}
/// <summary>
/// 获取资源信息列表
/// </summary>
/// <param name="tag">资源标签</param>
public static AssetInfo[] GetAssetInfos(string tag)
{
return _mainPackage.GetAssetInfos(tag);
}
/// <summary>
/// 获取资源信息列表
/// </summary>
/// <param name="tags">资源标签列表</param>
public static AssetInfo[] GetAssetInfos(string[] tags)
{
return _mainPackage.GetAssetInfos(tags);
}
/// <summary>
/// 获取资源信息
/// </summary>
/// <param name="location">资源的定位地址</param>
public static AssetInfo GetAssetInfo(string location)
{
return _mainPackage.GetAssetInfo(location);
}
/// <summary>
/// 获取资源路径
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <returns>如果location地址无效则返回空字符串</returns>
public static string GetAssetPath(string location)
{
return _mainPackage.GetAssetPath(location);
}
#endregion
#region
/// <summary>
/// 异步获取原生文件
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="copyPath">拷贝路径</param>
public static RawFileOperation GetRawFileAsync(string location, string copyPath = null)
{
return _mainPackage.GetRawFileAsync(location, copyPath);
}
/// <summary>
/// 异步获取原生文件
/// </summary>
/// <param name="assetInfo">资源信息</param>
/// <param name="copyPath">拷贝路径</param>
public static RawFileOperation GetRawFileAsync(AssetInfo assetInfo, string copyPath = null)
{
return _mainPackage.GetRawFileAsync(assetInfo, copyPath);
}
#endregion
#region
/// <summary>
/// 异步加载场景
/// </summary>
/// <param name="location">场景的定位地址</param>
/// <param name="sceneMode">场景加载模式</param>
/// <param name="activateOnLoad">加载完毕时是否主动激活</param>
/// <param name="priority">优先级</param>
public static SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100)
{
return _mainPackage.LoadSceneAsync(location, sceneMode, activateOnLoad, priority);
}
/// <summary>
/// 异步加载场景
/// </summary>
/// <param name="assetInfo">场景的资源信息</param>
/// <param name="sceneMode">场景加载模式</param>
/// <param name="activateOnLoad">加载完毕时是否主动激活</param>
/// <param name="priority">优先级</param>
public static SceneOperationHandle LoadSceneAsync(AssetInfo assetInfo, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100)
{
return _mainPackage.LoadSceneAsync(assetInfo, sceneMode, activateOnLoad, priority);
}
#endregion
#region
/// <summary>
/// 同步加载资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public static AssetOperationHandle LoadAssetSync(AssetInfo assetInfo)
{
return _mainPackage.LoadAssetSync(assetInfo);
}
/// <summary>
/// 同步加载资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public static AssetOperationHandle LoadAssetSync<TObject>(string location) where TObject : UnityEngine.Object
{
return _mainPackage.LoadAssetSync<TObject>(location);
}
/// <summary>
/// 同步加载资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">资源类型</param>
public static AssetOperationHandle LoadAssetSync(string location, System.Type type)
{
return _mainPackage.LoadAssetSync(location, type);
}
/// <summary>
/// 异步加载资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public static AssetOperationHandle LoadAssetAsync(AssetInfo assetInfo)
{
return _mainPackage.LoadAssetAsync(assetInfo);
}
/// <summary>
/// 异步加载资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public static AssetOperationHandle LoadAssetAsync<TObject>(string location) where TObject : UnityEngine.Object
{
return _mainPackage.LoadAssetAsync<TObject>(location);
}
/// <summary>
/// 异步加载资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">资源类型</param>
public static AssetOperationHandle LoadAssetAsync(string location, System.Type type)
{
return _mainPackage.LoadAssetAsync(location, type);
}
#endregion
#region
/// <summary>
/// 同步加载子资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public static SubAssetsOperationHandle LoadSubAssetsSync(AssetInfo assetInfo)
{
return _mainPackage.LoadSubAssetsSync(assetInfo);
}
/// <summary>
/// 同步加载子资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public static SubAssetsOperationHandle LoadSubAssetsSync<TObject>(string location) where TObject : UnityEngine.Object
{
return _mainPackage.LoadSubAssetsSync<TObject>(location);
}
/// <summary>
/// 同步加载子资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">子对象类型</param>
public static SubAssetsOperationHandle LoadSubAssetsSync(string location, System.Type type)
{
return _mainPackage.LoadSubAssetsSync(location, type);
}
/// <summary>
/// 异步加载子资源对象
/// </summary>
/// <param name="assetInfo">资源信息</param>
public static SubAssetsOperationHandle LoadSubAssetsAsync(AssetInfo assetInfo)
{
return _mainPackage.LoadSubAssetsAsync(assetInfo);
}
/// <summary>
/// 异步加载子资源对象
/// </summary>
/// <typeparam name="TObject">资源类型</typeparam>
/// <param name="location">资源的定位地址</param>
public static SubAssetsOperationHandle LoadSubAssetsAsync<TObject>(string location) where TObject : UnityEngine.Object
{
return _mainPackage.LoadSubAssetsAsync<TObject>(location);
}
/// <summary>
/// 异步加载子资源对象
/// </summary>
/// <param name="location">资源的定位地址</param>
/// <param name="type">子对象类型</param>
public static SubAssetsOperationHandle LoadSubAssetsAsync(string location, System.Type type)
{
return _mainPackage.LoadSubAssetsAsync(location, type);
}
#endregion
#region
/// <summary>
/// 创建补丁下载器,用于下载更新资源标签指定的资源包文件
/// </summary>
/// <param name="tag">资源标签</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
public static PatchDownloaderOperation CreatePatchDownloader(string tag, int downloadingMaxNumber, int failedTryAgain)
{
return _mainPackage.CreatePatchDownloader(new string[] { tag }, downloadingMaxNumber, failedTryAgain);
}
/// <summary>
/// 创建补丁下载器,用于下载更新资源标签指定的资源包文件
/// </summary>
/// <param name="tags">资源标签列表</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
public static PatchDownloaderOperation CreatePatchDownloader(string[] tags, int downloadingMaxNumber, int failedTryAgain)
{
return _mainPackage.CreatePatchDownloader(tags, downloadingMaxNumber, failedTryAgain);
}
/// <summary>
/// 创建补丁下载器,用于下载更新当前资源版本所有的资源包文件
/// </summary>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
public static PatchDownloaderOperation CreatePatchDownloader(int downloadingMaxNumber, int failedTryAgain)
{
return _mainPackage.CreatePatchDownloader(downloadingMaxNumber, failedTryAgain);
}
/// <summary>
/// 创建补丁下载器,用于下载更新指定的资源列表依赖的资源包文件
/// </summary>
/// <param name="locations">资源定位列表</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
public static PatchDownloaderOperation CreateBundleDownloader(string[] locations, int downloadingMaxNumber, int failedTryAgain)
{
return _mainPackage.CreateBundleDownloader(locations, downloadingMaxNumber, failedTryAgain);
}
/// <summary>
/// 创建补丁下载器,用于下载更新指定的资源列表依赖的资源包文件
/// </summary>
/// <param name="assetInfos">资源信息列表</param>
/// <param name="downloadingMaxNumber">同时下载的最大文件数</param>
/// <param name="failedTryAgain">下载失败的重试次数</param>
public static PatchDownloaderOperation CreateBundleDownloader(AssetInfo[] assetInfos, int downloadingMaxNumber, int failedTryAgain)
{
return _mainPackage.CreateBundleDownloader(assetInfos, downloadingMaxNumber, failedTryAgain);
}
#endregion
#region
/// <summary>
/// 创建补丁解压器
/// </summary>
/// <param name="tag">资源标签</param>
/// <param name="unpackingMaxNumber">同时解压的最大文件数</param>
/// <param name="failedTryAgain">解压失败的重试次数</param>
public static PatchUnpackerOperation CreatePatchUnpacker(string tag, int unpackingMaxNumber, int failedTryAgain)
{
return _mainPackage.CreatePatchUnpacker(tag, unpackingMaxNumber, failedTryAgain);
}
/// <summary>
/// 创建补丁解压器
/// </summary>
/// <param name="tags">资源标签列表</param>
/// <param name="unpackingMaxNumber">同时解压的最大文件数</param>
/// <param name="failedTryAgain">解压失败的重试次数</param>
public static PatchUnpackerOperation CreatePatchUnpacker(string[] tags, int unpackingMaxNumber, int failedTryAgain)
{
return _mainPackage.CreatePatchUnpacker(tags, unpackingMaxNumber, failedTryAgain);
}
/// <summary>
/// 创建补丁解压器
/// </summary>
/// <param name="unpackingMaxNumber">同时解压的最大文件数</param>
/// <param name="failedTryAgain">解压失败的重试次数</param>
public static PatchUnpackerOperation CreatePatchUnpacker(int unpackingMaxNumber, int failedTryAgain)
{
return _mainPackage.CreatePatchUnpacker(unpackingMaxNumber, failedTryAgain);
}
#endregion
#region
/// <summary>
/// 创建资源包裹下载器,用于下载更新指定资源版本所有的资源包文件
/// </summary>
/// <param name="packageCRC">指定更新的资源包裹版本</param>
/// <param name="timeout">超时时间</param>
public static UpdatePackageOperation UpdatePackageAsync(string packageCRC, int timeout = 60)
{
return _mainPackage.UpdatePackageAsync(packageCRC, timeout);
}
#endregion
}
}

View File

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

View File

@@ -823,7 +823,6 @@ RectTransform:
- {fileID: 856012950}
- {fileID: 1722199052}
- {fileID: 851382668}
- {fileID: 1756455456}
- {fileID: 1410518846}
- {fileID: 2140485207}
m_Father: {fileID: 0}
@@ -1031,84 +1030,6 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 482913471}
m_CullTransparentMesh: 1
--- !u!1 &544279671
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 544279672}
- component: {fileID: 544279674}
- component: {fileID: 544279673}
m_Layer: 5
m_Name: label
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &544279672
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 544279671}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1756455456}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &544279673
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 544279671}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 12800000, guid: 35204a17be9c96649b254d2bad80f4dd, type: 3}
m_FontSize: 22
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 2
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: res version
--- !u!222 &544279674
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 544279671}
m_CullTransparentMesh: 1
--- !u!1 &748725809
GameObject:
m_ObjectHideFlags: 0
@@ -2739,81 +2660,6 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1722199051}
m_CullTransparentMesh: 1
--- !u!1 &1756455455
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1756455456}
- component: {fileID: 1756455458}
- component: {fileID: 1756455457}
m_Layer: 5
m_Name: res_version
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1756455456
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1756455455}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 544279672}
m_Father: {fileID: 421995327}
m_RootOrder: 10
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: -167.48999, y: 55}
m_SizeDelta: {x: 250, y: 50}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1756455457
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1756455455}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.227451, g: 0.5176471, b: 0.5137255, a: 1}
m_RaycastTarget: 1
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!222 &1756455458
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1756455455}
m_CullTransparentMesh: 1
--- !u!1 &1905438978
GameObject:
m_ObjectHideFlags: 0
@@ -2996,7 +2842,7 @@ RectTransform:
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 421995327}
m_RootOrder: 12
m_RootOrder: 11
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

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