mirror of
https://github.com/tuyoogame/YooAsset.git
synced 2026-05-14 19:40:47 +00:00
Compare commits
20 Commits
1.2.4
...
1.3.0-prev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f07cbcbb81 | ||
|
|
9df32816a1 | ||
|
|
f7fd589b13 | ||
|
|
852d031254 | ||
|
|
38c0ca0ce1 | ||
|
|
4eca73303b | ||
|
|
d5292f3fc3 | ||
|
|
6549fbb552 | ||
|
|
a71921cdd1 | ||
|
|
46c219505f | ||
|
|
0a129f9250 | ||
|
|
4ece14e921 | ||
|
|
a4c8fb6e1b | ||
|
|
c8d3f6efed | ||
|
|
fe47de01d3 | ||
|
|
84045b13c6 | ||
|
|
af37bb6e54 | ||
|
|
e1801a5fba | ||
|
|
50bfde6e8e | ||
|
|
f0ac319a73 |
@@ -2,6 +2,49 @@
|
||||
|
||||
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
|
||||
|
||||
@@ -59,7 +59,6 @@ namespace YooAsset.Editor
|
||||
new TaskCreatePatchManifest(), //创建清单文件
|
||||
new TaskCreateReport(), //创建报告文件
|
||||
new TaskCreatePatchPackage(), //制作补丁包
|
||||
new TaskCopyBuildinFiles(), //拷贝内置文件
|
||||
};
|
||||
}
|
||||
else if (buildParameters.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
|
||||
@@ -74,7 +73,6 @@ namespace YooAsset.Editor
|
||||
new TaskCreatePatchManifest(), //创建清单文件
|
||||
new TaskCreateReport(), //创建报告文件
|
||||
new TaskCreatePatchPackage(), //制作补丁包
|
||||
new TaskCopyBuildinFiles(), //拷贝内置文件
|
||||
};
|
||||
}
|
||||
else
|
||||
@@ -86,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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
/// 压缩方式
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>();
|
||||
|
||||
@@ -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, ';');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -86,7 +113,8 @@ namespace YooAsset.Editor
|
||||
throw new Exception("Should never get here !");
|
||||
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -25,5 +25,10 @@ namespace YooAsset.Editor
|
||||
/// 输出的补丁包目录
|
||||
/// </summary>
|
||||
public string OutputPackageDirectory;
|
||||
|
||||
/// <summary>
|
||||
/// 输出的包裹清单哈希值
|
||||
/// </summary>
|
||||
public string OutputPackageCRC;
|
||||
}
|
||||
}
|
||||
@@ -25,14 +25,15 @@ 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.PipelineOutputDirectory}/{YooAssetSettings.OutputFolderName}";
|
||||
string unityOutputManifestFilePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{YooAssetSettings.OutputFolderName}";
|
||||
if(System.IO.File.Exists(unityOutputManifestFilePath) == false)
|
||||
throw new Exception("构建过程中发生严重错误!请查阅上下文日志!");
|
||||
}
|
||||
@@ -54,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)
|
||||
@@ -73,11 +75,12 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
private void UpdateBuildBundleInfo(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext, BuildResultContext buildResult)
|
||||
{
|
||||
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
|
||||
foreach (var bundleInfo in buildMapContext.BundleInfos)
|
||||
{
|
||||
if (bundleInfo.IsRawFile)
|
||||
{
|
||||
string filePath = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
|
||||
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
|
||||
bundleInfo.ContentHash = HashUtility.FileMD5(filePath);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -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,11 +78,12 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
private void UpdateBuildBundleInfo(BuildMapContext buildMapContext, BuildParametersContext buildParametersContext, BuildResultContext buildResult)
|
||||
{
|
||||
string pipelineOutputDirectory = buildParametersContext.GetPipelineOutputDirectory();
|
||||
foreach (var bundleInfo in buildMapContext.BundleInfos)
|
||||
{
|
||||
if (bundleInfo.IsRawFile)
|
||||
{
|
||||
string filePath = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
|
||||
string filePath = $"{pipelineOutputDirectory}/{bundleInfo.BundleName}";
|
||||
bundleInfo.ContentHash = HashUtility.FileMD5(filePath);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -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()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,23 +21,23 @@ 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)
|
||||
{
|
||||
if(buildParameters.Parameters.BuildMode == EBuildMode.IncrementalBuild)
|
||||
if(buildParameters.BuildMode == EBuildMode.IncrementalBuild)
|
||||
{
|
||||
var buildResultContext = context.GetContextObject<TaskBuilding_SBP.BuildResultContext>();
|
||||
UpdateBuiltInBundleReference(patchManifest, buildResultContext.Results);
|
||||
@@ -45,21 +45,24 @@ namespace YooAsset.Editor
|
||||
}
|
||||
|
||||
// 创建补丁清单文件
|
||||
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>
|
||||
@@ -72,8 +75,6 @@ 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;
|
||||
@@ -82,36 +83,21 @@ namespace YooAsset.Editor
|
||||
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)
|
||||
{
|
||||
// 注意:没有任何分类标签的Bundle文件默认为内置文件
|
||||
if (bundleTags.Length == 0)
|
||||
return true;
|
||||
|
||||
foreach (var tag in bundleTags)
|
||||
{
|
||||
if (buildinTags.Contains(tag))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private string GetBundleFileHash(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
|
||||
{
|
||||
var buildMode = buildParametersContext.Parameters.BuildMode;
|
||||
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
|
||||
return "00000000000000000000000000000000"; //32位
|
||||
|
||||
string filePath = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
|
||||
string filePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{bundleInfo.BundleName}";
|
||||
return HashUtility.FileMD5(filePath);
|
||||
}
|
||||
private string GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
|
||||
@@ -120,7 +106,7 @@ namespace YooAsset.Editor
|
||||
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
|
||||
return "00000000"; //8位
|
||||
|
||||
string filePath = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
|
||||
string filePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{bundleInfo.BundleName}";
|
||||
return HashUtility.FileCRC32(filePath);
|
||||
}
|
||||
private long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
|
||||
@@ -129,7 +115,7 @@ namespace YooAsset.Editor
|
||||
if (buildMode == EBuildMode.DryRunBuild || buildMode == EBuildMode.SimulateBuild)
|
||||
return 0;
|
||||
|
||||
string filePath = $"{buildParametersContext.PipelineOutputDirectory}/{bundleInfo.BundleName}";
|
||||
string filePath = $"{buildParametersContext.GetPipelineOutputDirectory()}/{bundleInfo.BundleName}";
|
||||
return FileUtility.GetFileSize(filePath);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -24,9 +24,12 @@ namespace YooAsset.Editor
|
||||
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();
|
||||
|
||||
// 概述信息
|
||||
@@ -38,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);
|
||||
@@ -101,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);
|
||||
|
||||
@@ -174,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;
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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("构建内容准备完毕!");
|
||||
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace YooAsset.Editor
|
||||
/// <summary>
|
||||
/// 获取打包收集的资源文件
|
||||
/// </summary>
|
||||
public List<CollectAssetInfo> GetAllCollectAssets(EBuildMode buildMode, AssetBundleCollectorGroup group)
|
||||
public List<CollectAssetInfo> GetAllCollectAssets(EBuildMode buildMode, bool enableAddressable, AssetBundleCollectorGroup group)
|
||||
{
|
||||
// 注意:模拟构建模式下只收集主资源
|
||||
if (buildMode == EBuildMode.SimulateBuild)
|
||||
@@ -187,7 +187,7 @@ namespace YooAsset.Editor
|
||||
}
|
||||
|
||||
// 检测可寻址地址是否重复
|
||||
if (AssetBundleCollectorSettingData.Setting.EnableAddressable)
|
||||
if (enableAddressable)
|
||||
{
|
||||
HashSet<string> adressTemper = new HashSet<string>();
|
||||
foreach (var collectInfoPair in result)
|
||||
|
||||
@@ -10,14 +10,21 @@ 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";
|
||||
@@ -39,85 +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)
|
||||
{
|
||||
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}");
|
||||
|
||||
string collectorGUID = string.Empty;
|
||||
if (collectorElement.HasAttribute(XmlCollectorGUID))
|
||||
collectorGUID = collectorElement.GetAttribute(XmlCollectorGUID);
|
||||
AssetBundleCollectorGroup group = new AssetBundleCollectorGroup();
|
||||
group.GroupName = groupElement.GetAttribute(XmlGroupName);
|
||||
group.GroupDesc = groupElement.GetAttribute(XmlGroupDesc);
|
||||
group.AssetTags = groupElement.GetAttribute(XmlAssetTags);
|
||||
package.Groups.Add(group);
|
||||
|
||||
AssetBundleCollector collector = new AssetBundleCollector();
|
||||
collector.CollectPath = collectorElement.GetAttribute(XmlCollectPath);
|
||||
collector.CollectorGUID = collectorGUID;
|
||||
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);
|
||||
// 读取收集器配置
|
||||
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($"导入配置完毕!");
|
||||
}
|
||||
@@ -145,29 +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(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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d188c50fd00bf941b2eeebb374dc0d1
|
||||
guid: 154d1124b6089254895b0f2b672394d5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -8,25 +8,39 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,88 +49,64 @@ namespace YooAsset.Editor
|
||||
/// </summary>
|
||||
public bool FixConfigError()
|
||||
{
|
||||
bool result = false;
|
||||
foreach (var group in Groups)
|
||||
bool isFixed = false;
|
||||
foreach (var package in Packages)
|
||||
{
|
||||
foreach (var collector in group.Collectors)
|
||||
if (package.FixConfigError())
|
||||
{
|
||||
bool isFixed = collector.FixConfigError();
|
||||
if (isFixed)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
isFixed = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,14 +256,13 @@ namespace YooAsset.Editor
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 清空所有数据
|
||||
/// </summary>
|
||||
public static void ClearAll()
|
||||
{
|
||||
Setting.EnableAddressable = false;
|
||||
Setting.Groups.Clear();
|
||||
Setting.ClearAll();
|
||||
SaveFile();
|
||||
}
|
||||
|
||||
@@ -337,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;
|
||||
}
|
||||
@@ -363,18 +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)
|
||||
public static void CreateCollector(AssetBundleCollectorGroup group, AssetBundleCollector collector)
|
||||
{
|
||||
AssetBundleCollector collector = new AssetBundleCollector();
|
||||
group.Collectors.Add(collector);
|
||||
IsDirty = true;
|
||||
}
|
||||
@@ -400,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,20 @@ 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;
|
||||
@@ -76,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);
|
||||
}
|
||||
});
|
||||
|
||||
// 分组列表相关
|
||||
@@ -110,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);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -122,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);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -134,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);
|
||||
@@ -163,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();
|
||||
}
|
||||
});
|
||||
@@ -208,10 +279,12 @@ 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()
|
||||
{
|
||||
@@ -239,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()
|
||||
@@ -274,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;
|
||||
@@ -290,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();
|
||||
}
|
||||
|
||||
@@ -314,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();
|
||||
@@ -570,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)
|
||||
{
|
||||
@@ -611,7 +775,8 @@ namespace YooAsset.Editor
|
||||
return;
|
||||
|
||||
Undo.RecordObject(AssetBundleCollectorSettingData.Setting, "YooAsset.AssetBundleCollectorWindow AddCollector");
|
||||
AssetBundleCollectorSettingData.CreateCollector(selectGroup);
|
||||
AssetBundleCollector collector = new AssetBundleCollector();
|
||||
AssetBundleCollectorSettingData.CreateCollector(selectGroup, collector);
|
||||
FillCollectorViewData();
|
||||
}
|
||||
private void RemoveCollectorBtn_clicked(AssetBundleCollector selectCollector)
|
||||
|
||||
@@ -5,28 +5,39 @@
|
||||
<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>
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace YooAsset.Editor
|
||||
{
|
||||
_dependListView.Clear();
|
||||
_dependListView.ClearSelection();
|
||||
_dependListView.itemsSource = providerInfo.BundleInfos;
|
||||
_dependListView.itemsSource = providerInfo.DependBundleInfos;
|
||||
_dependListView.Rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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}"));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace YooAsset
|
||||
|
||||
// 卸载子场景
|
||||
Scene sceneObject = SceneObject;
|
||||
AssetSystem.UnloadSubScene(Provider);
|
||||
Provider.Impl.UnloadSubScene(Provider);
|
||||
{
|
||||
var operation = new UnloadSceneOperation(sceneObject);
|
||||
OperationSystem.StartOperation(operation);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -19,17 +19,6 @@ namespace YooAsset
|
||||
/// </summary>
|
||||
public int FrameCount;
|
||||
|
||||
/// <summary>
|
||||
/// 资源包总数
|
||||
/// </summary>
|
||||
public int BundleCount;
|
||||
|
||||
/// <summary>
|
||||
/// 资源对象总数
|
||||
/// </summary>
|
||||
public int AssetCount;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 序列化
|
||||
/// </summary>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
93
Assets/YooAsset/Runtime/InitializeParameters.cs
Normal file
93
Assets/YooAsset/Runtime/InitializeParameters.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c77e17c3a3a57548a218f1cd26f5a55
|
||||
guid: a9b5e8a77215adb45b203be8a4fb9eda
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
/// 资源列表(主动收集的资源列表)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -27,5 +27,10 @@ namespace YooAsset
|
||||
/// 映射为资源路径
|
||||
/// </summary>
|
||||
string MappingToAssetPath(string location);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所属的包裹名
|
||||
/// </summary>
|
||||
string GetPackageName();
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,6 @@ namespace YooAsset
|
||||
/// <summary>
|
||||
/// 定位地址转换为资源路径
|
||||
/// </summary>
|
||||
string ConvertLocationToAssetPath(string location);
|
||||
string ConvertLocationToAssetPath(YooAssetPackage package, string location);
|
||||
}
|
||||
}
|
||||
11
Assets/YooAsset/Runtime/Services/IQueryServices.cs
Normal file
11
Assets/YooAsset/Runtime/Services/IQueryServices.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
namespace YooAsset
|
||||
{
|
||||
public interface IQueryServices
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询内置资源
|
||||
/// </summary>
|
||||
bool QueryStreamingAssets(string fileName);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4c94d5687e1d884d833f88928d048c9
|
||||
guid: 71b4ac2c7d7f15b40a457f355d535f33
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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着色器资源包名称
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -6,17 +6,17 @@ namespace YooAsset
|
||||
{
|
||||
void Update()
|
||||
{
|
||||
YooAssets.InternalUpdate();
|
||||
YooAssets.Update();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
YooAssets.InternalDestroy();
|
||||
YooAssets.Destroy();
|
||||
}
|
||||
|
||||
void OnApplicationQuit()
|
||||
{
|
||||
YooAssets.InternalDestroy();
|
||||
YooAssets.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
1001
Assets/YooAsset/Runtime/YooAssetPackage.cs
Normal file
1001
Assets/YooAsset/Runtime/YooAssetPackage.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37a7daecdb1361140b44ba4724e8866e
|
||||
guid: 6fcda791b973f5b4499e8bd3ede91312
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
File diff suppressed because it is too large
Load Diff
409
Assets/YooAsset/Runtime/YooAssetsExtension.cs
Normal file
409
Assets/YooAsset/Runtime/YooAssetsExtension.cs
Normal 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
|
||||
}
|
||||
}
|
||||
11
Assets/YooAsset/Runtime/YooAssetsExtension.cs.meta
Normal file
11
Assets/YooAsset/Runtime/YooAssetsExtension.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2db868c2aaaee8e42a7f035117e747c4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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}
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
using Better.StreamingAssets;
|
||||
|
||||
public class BootScene : MonoBehaviour
|
||||
{
|
||||
public static BootScene Instance { private set; get; }
|
||||
public static YooAssets.EPlayMode GamePlayMode;
|
||||
public static EPlayMode GamePlayMode;
|
||||
|
||||
public YooAssets.EPlayMode PlayMode = YooAssets.EPlayMode.EditorSimulateMode;
|
||||
public EPlayMode PlayMode = EPlayMode.EditorSimulateMode;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
@@ -36,33 +37,37 @@ public class BootScene : MonoBehaviour
|
||||
GamePlayMode = PlayMode;
|
||||
Debug.Log($"资源系统运行模式:{PlayMode}");
|
||||
|
||||
// 初始化BetterStreaming
|
||||
BetterStreamingAssets.Initialize();
|
||||
|
||||
// 初始化资源系统
|
||||
YooAssets.Initialize();
|
||||
|
||||
// 编辑器下的模拟模式
|
||||
if (PlayMode == YooAssets.EPlayMode.EditorSimulateMode)
|
||||
if (PlayMode == EPlayMode.EditorSimulateMode)
|
||||
{
|
||||
var createParameters = new YooAssets.EditorSimulateModeParameters();
|
||||
var createParameters = new EditorSimulateModeParameters();
|
||||
createParameters.LocationServices = new AddressLocationServices();
|
||||
//createParameters.SimulatePatchManifestPath = GetPatchManifestPath();
|
||||
createParameters.SimulatePatchManifestPath = EditorSimulateModeHelper.SimulateBuild("DefaultPackage", true);
|
||||
yield return YooAssets.InitializeAsync(createParameters);
|
||||
}
|
||||
|
||||
// 单机运行模式
|
||||
if (PlayMode == YooAssets.EPlayMode.OfflinePlayMode)
|
||||
if (PlayMode == EPlayMode.OfflinePlayMode)
|
||||
{
|
||||
var createParameters = new YooAssets.OfflinePlayModeParameters();
|
||||
var createParameters = new OfflinePlayModeParameters();
|
||||
createParameters.LocationServices = new AddressLocationServices();
|
||||
yield return YooAssets.InitializeAsync(createParameters);
|
||||
}
|
||||
|
||||
// 联机运行模式
|
||||
if (PlayMode == YooAssets.EPlayMode.HostPlayMode)
|
||||
if (PlayMode == EPlayMode.HostPlayMode)
|
||||
{
|
||||
var createParameters = new YooAssets.HostPlayModeParameters();
|
||||
var createParameters = new HostPlayModeParameters();
|
||||
createParameters.LocationServices = new AddressLocationServices();
|
||||
createParameters.DecryptionServices = null;
|
||||
createParameters.ClearCacheWhenDirty = false;
|
||||
createParameters.QueryServices = new QueryStreamingAssetsFileServices();
|
||||
createParameters.DefaultHostServer = GetHostServerURL();
|
||||
createParameters.FallbackHostServer = GetHostServerURL();
|
||||
createParameters.VerifyLevel = EVerifyLevel.High;
|
||||
yield return YooAssets.InitializeAsync(createParameters);
|
||||
}
|
||||
|
||||
@@ -70,11 +75,6 @@ public class BootScene : MonoBehaviour
|
||||
PatchUpdater.Run();
|
||||
}
|
||||
|
||||
private string GetPatchManifestPath()
|
||||
{
|
||||
string directory = System.IO.Path.GetDirectoryName(Application.dataPath);
|
||||
return $"{directory}/Bundles/StandaloneWindows64/UnityManifest_SimulateBuild/PatchManifest_100.bytes";
|
||||
}
|
||||
private string GetHostServerURL()
|
||||
{
|
||||
//string hostServerIP = "http://10.0.2.2"; //安卓模拟器地址
|
||||
@@ -101,4 +101,11 @@ public class BootScene : MonoBehaviour
|
||||
return $"{hostServerIP}/CDN/PC/{gameVersion}";
|
||||
#endif
|
||||
}
|
||||
private class QueryStreamingAssetsFileServices : IQueryServices
|
||||
{
|
||||
public bool QueryStreamingAssets(string fileName)
|
||||
{
|
||||
return BetterStreamingAssets.FileExists($"YooAssets/{fileName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,15 +45,12 @@ public class GameScene1 : MonoBehaviour
|
||||
|
||||
void InitWindow()
|
||||
{
|
||||
var resVersion = CanvasRoot.transform.Find("res_version/label").GetComponent<Text>();
|
||||
resVersion.text = $"资源版本 : {YooAssets.GetResourceVersion()}";
|
||||
|
||||
var playMode = CanvasRoot.transform.Find("play_mode/label").GetComponent<Text>();
|
||||
if (BootScene.GamePlayMode == YooAssets.EPlayMode.EditorSimulateMode)
|
||||
if (BootScene.GamePlayMode == EPlayMode.EditorSimulateMode)
|
||||
playMode.text = "编辑器下模拟模式";
|
||||
else if (BootScene.GamePlayMode == YooAssets.EPlayMode.OfflinePlayMode)
|
||||
else if (BootScene.GamePlayMode == EPlayMode.OfflinePlayMode)
|
||||
playMode.text = "离线运行模式";
|
||||
else if (BootScene.GamePlayMode == YooAssets.EPlayMode.HostPlayMode)
|
||||
else if (BootScene.GamePlayMode == EPlayMode.HostPlayMode)
|
||||
playMode.text = "网络运行模式";
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
|
||||
@@ -24,7 +24,7 @@ public class FsmUpdateManifest : IFsmNode
|
||||
yield return new WaitForSecondsRealtime(0.5f);
|
||||
|
||||
// 更新补丁清单
|
||||
var operation = YooAssets.UpdateManifestAsync(PatchUpdater.ResourceVersion, 30);
|
||||
var operation = YooAssets.UpdateManifestAsync(PatchUpdater.PackageCRC, 30);
|
||||
yield return operation;
|
||||
|
||||
if(operation.Status == EOperationStatus.Succeed)
|
||||
|
||||
@@ -29,8 +29,8 @@ internal class FsmUpdateStaticVersion : IFsmNode
|
||||
|
||||
if (operation.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
Debug.Log($"Found static version : {operation.ResourceVersion}");
|
||||
PatchUpdater.ResourceVersion = operation.ResourceVersion;
|
||||
Debug.Log($"Found static version : {operation.PackageCRC}");
|
||||
PatchUpdater.PackageCRC = operation.PackageCRC;
|
||||
FsmManager.Transition(nameof(FsmUpdateManifest));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -16,7 +16,7 @@ public static class PatchUpdater
|
||||
/// <summary>
|
||||
/// 资源版本
|
||||
/// </summary>
|
||||
public static int ResourceVersion { set; get; }
|
||||
public static string PackageCRC { set; get; }
|
||||
|
||||
/// <summary>
|
||||
/// 开启初始化流程
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f807a00a11cdd24490fd433a55ecd4f
|
||||
guid: e214524cdc329d646b50bf3e8ba8e7a0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22d47ea6e32e3c64c8463e1f0fa7506a
|
||||
guid: 89357359fd1b3f74fa7cb048a1ffa2b6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
34
Assets/YooAsset/Samples~/Basic Sample/Plugins/BetterStreamingAssets/.gitignore
vendored
Normal file
34
Assets/YooAsset/Samples~/Basic Sample/Plugins/BetterStreamingAssets/.gitignore
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/[Ll]ibrary/
|
||||
/[Tt]emp/
|
||||
/[Oo]bj/
|
||||
/[Bb]uild/
|
||||
/[Bb]uilds/
|
||||
/Assets/AssetStoreTools*
|
||||
|
||||
# Visual Studio 2015 cache directory
|
||||
/.vs/
|
||||
|
||||
# Autogenerated VS/MD/Consulo solution and project files
|
||||
ExportedObj/
|
||||
.consulo/
|
||||
*.csproj
|
||||
*.unityproj
|
||||
*.sln
|
||||
*.suo
|
||||
*.tmp
|
||||
*.user
|
||||
*.userprefs
|
||||
*.pidb
|
||||
*.booproj
|
||||
*.svd
|
||||
*.pdb
|
||||
|
||||
# Unity3D generated meta files
|
||||
*.pidb.meta
|
||||
|
||||
# Unity3D Generated File On Crash Reports
|
||||
sysinfo.txt
|
||||
|
||||
# Builds
|
||||
*.apk
|
||||
*.unitypackage
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 gwiazdorrr
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 528b2874f5351ca4894d885979739c4d
|
||||
guid: f3d9e435137e34d34a54f181bf3dc7c2
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
@@ -0,0 +1,117 @@
|
||||
# Better Streaming Assets
|
||||
|
||||
Better Streaming Assets is a plugin that lets you access Streaming Assets directly in an uniform and thread-safe way, with tiny overhead. Mostly beneficial for Android projects, where the alternatives are to use archaic and hugely inefficient WWW or embed data in Asset Bundles. API is based on Syste.IO.File and System.IO.Directory classes.
|
||||
|
||||
# Note on Android & App Bundles
|
||||
|
||||
App Bundles (.aab) builds are bugged when it comes to Streaming Assets. See https://github.com/gwiazdorrr/BetterStreamingAssets/issues/10 for details. The bottom line is:
|
||||
|
||||
⚠️ **Keep all file names in Streaming Assets lowercase!** ⚠️
|
||||
|
||||
# Getting started
|
||||
|
||||
This plugin can be installed in following ways:
|
||||
* Select "Add package from git URL..." in the Unity Package Manager and use this URL: `https://github.com/gwiazdorrr/BetterStreamingAssets.git`
|
||||
* Clone this repository and copy `Runtime` directory to your project.
|
||||
* Download the latest release from the [Asset Store](https://assetstore.unity.com/packages/tools/input-management/better-streaming-assets-103788).
|
||||
|
||||
# Usage
|
||||
|
||||
Check examples below. Note that all the paths are relative to StreamingAssets directory. That is, if you have files
|
||||
|
||||
```
|
||||
<project>/Assets/StreamingAssets/foo.bar
|
||||
<project>/Assets/StreamingAssets/dir/foo.bar
|
||||
````
|
||||
|
||||
You are expected to use following paths:
|
||||
|
||||
```
|
||||
foo.bar (or /foo.bar)
|
||||
dir/foo.bar (or /dir/foo.bar)
|
||||
```
|
||||
|
||||
# Examples
|
||||
|
||||
Initialization (before first use, needs to be called on main thread):
|
||||
|
||||
```csharp
|
||||
BetterStreamingAssets.Initialize();
|
||||
```
|
||||
|
||||
Typical scenario, deserializing from Xml:
|
||||
|
||||
```csharp
|
||||
public static Foo ReadFromXml(string path)
|
||||
{
|
||||
if ( !BetterStreamingAssets.FileExists(path) )
|
||||
{
|
||||
Debug.LogErrorFormat("Streaming asset not found: {0}", path);
|
||||
return null;
|
||||
}
|
||||
|
||||
using ( var stream = BetterStreamingAssets.OpenRead(path) )
|
||||
{
|
||||
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(Foo));
|
||||
return (Foo)serializer.Deserialize(stream);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that ReadFromXml can be called from any thread, as long as Foo's constructor doesn't make any UnityEngine calls.
|
||||
|
||||
Listing all Streaming Assets in with .xml extension:
|
||||
|
||||
```csharp
|
||||
// all the xmls
|
||||
string[] paths = BetterStreamingAssets.GetFiles("\\", "*.xml", SearchOption.AllDirectories);
|
||||
// just xmls in Config directory (and nested)
|
||||
string[] paths = BetterStreamingAssets.GetFiles("Config", "*.xml", SearchOption.AllDirectories);
|
||||
```
|
||||
|
||||
Checking if a directory exists:
|
||||
|
||||
```csharp
|
||||
Debug.Assert( BetterStreamingAssets.DirectoryExists("Config") );
|
||||
```
|
||||
|
||||
Ways of reading a file:
|
||||
|
||||
```csharp
|
||||
// all at once
|
||||
byte[] data = BetterStreamingAssets.ReadAllBytes("Foo/bar.data");
|
||||
|
||||
// as stream, last 10 bytes
|
||||
byte[] footer = new byte[10];
|
||||
using (var stream = BetterStreamingAssets.OpenRead("Foo/bar.data"))
|
||||
{
|
||||
stream.Seek(-footer.Length, SeekOrigin.End);
|
||||
stream.Read(footer, 0, footer.Length);
|
||||
}
|
||||
```
|
||||
|
||||
Asset bundles (again, main thread only):
|
||||
|
||||
```csharp
|
||||
// synchronous
|
||||
var bundle = BetterStreamingAssets.LoadAssetBundle(path);
|
||||
// async
|
||||
var bundleOp = BetterStreamingAssets.LoadAssetBundleAsync(path);
|
||||
```
|
||||
|
||||
# (Android) False-positive compressed Streaming Assets messages
|
||||
|
||||
Streaming Assets end up in the same part of APK as files added by many custom plugins (`assets` directory), so it is impossible to tell whether a compressed file is a Streaming Asset (an indication something has gone terribly wrong) or not. This tool acts conservatively and logs errors whenever it finds a compressed file inside of `assets`, but outside of `assets/bin`. If you are annoyed by this and are certain a compressed file was not meant to be a Streaming Asset, add a file like this in the same assembly as Better Streaming Assets:
|
||||
|
||||
```csharp
|
||||
partial class BetterStreamingAssets
|
||||
{
|
||||
static partial void AndroidIsCompressedFileStreamingAsset(string path, ref bool result)
|
||||
{
|
||||
if ( path == "assets/my_custom_plugin_settings.json")
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c59a049ac5cdb4a48996edcefd9ac9c7
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89bc753a71211472587f0baa7a08d0e7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,663 @@
|
||||
// Better Streaming Assets, Piotr Gwiazdowski <gwiazdorrr+github at gmail.com>, 2017
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using Better;
|
||||
using Better.StreamingAssets;
|
||||
using Better.StreamingAssets.ZipArchive;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using BetterStreamingAssetsImp = BetterStreamingAssets.EditorImpl;
|
||||
#elif UNITY_ANDROID
|
||||
using BetterStreamingAssetsImp = BetterStreamingAssets.ApkImpl;
|
||||
#else
|
||||
using BetterStreamingAssetsImp = BetterStreamingAssets.LooseFilesImpl;
|
||||
#endif
|
||||
|
||||
public static partial class BetterStreamingAssets
|
||||
{
|
||||
internal struct ReadInfo
|
||||
{
|
||||
public string readPath;
|
||||
public long size;
|
||||
public long offset;
|
||||
public uint crc32;
|
||||
}
|
||||
|
||||
public static string Root
|
||||
{
|
||||
get { return BetterStreamingAssetsImp.s_root; }
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
BetterStreamingAssetsImp.Initialize(Application.dataPath, Application.streamingAssetsPath);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public static void InitializeWithExternalApk(string apkPath)
|
||||
{
|
||||
BetterStreamingAssetsImp.ApkMode = true;
|
||||
BetterStreamingAssetsImp.Initialize(apkPath, "jar:file://" + apkPath + "!/assets/");
|
||||
}
|
||||
|
||||
public static void InitializeWithExternalDirectories(string dataPath, string streamingAssetsPath)
|
||||
{
|
||||
BetterStreamingAssetsImp.ApkMode = false;
|
||||
BetterStreamingAssetsImp.Initialize(dataPath, streamingAssetsPath);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static bool FileExists(string path)
|
||||
{
|
||||
ReadInfo info;
|
||||
return BetterStreamingAssetsImp.TryGetInfo(path, out info);
|
||||
}
|
||||
|
||||
public static bool DirectoryExists(string path)
|
||||
{
|
||||
return BetterStreamingAssetsImp.DirectoryExists(path);
|
||||
}
|
||||
|
||||
public static AssetBundleCreateRequest LoadAssetBundleAsync(string path, uint crc = 0)
|
||||
{
|
||||
var info = GetInfoOrThrow(path);
|
||||
return AssetBundle.LoadFromFileAsync(info.readPath, crc, (ulong)info.offset);
|
||||
}
|
||||
|
||||
public static AssetBundle LoadAssetBundle(string path, uint crc = 0)
|
||||
{
|
||||
var info = GetInfoOrThrow(path);
|
||||
return AssetBundle.LoadFromFile(info.readPath, crc, (ulong)info.offset);
|
||||
}
|
||||
|
||||
public static System.IO.Stream OpenRead(string path)
|
||||
{
|
||||
if ( path == null )
|
||||
throw new ArgumentNullException("path");
|
||||
if ( path.Length == 0 )
|
||||
throw new ArgumentException("Empty path", "path");
|
||||
|
||||
return BetterStreamingAssetsImp.OpenRead(path);
|
||||
}
|
||||
|
||||
public static System.IO.StreamReader OpenText(string path)
|
||||
{
|
||||
Stream str = OpenRead(path);
|
||||
try
|
||||
{
|
||||
return new StreamReader(str);
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
if (str != null)
|
||||
str.Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReadAllText(string path)
|
||||
{
|
||||
using ( var sr = OpenText(path) )
|
||||
{
|
||||
return sr.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] ReadAllLines(string path)
|
||||
{
|
||||
string line;
|
||||
var lines = new List<string>();
|
||||
|
||||
using ( var sr = OpenText(path) )
|
||||
{
|
||||
while ( ( line = sr.ReadLine() ) != null )
|
||||
{
|
||||
lines.Add(line);
|
||||
}
|
||||
}
|
||||
|
||||
return lines.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ReadAllBytes(string path)
|
||||
{
|
||||
if ( path == null )
|
||||
throw new ArgumentNullException("path");
|
||||
if ( path.Length == 0 )
|
||||
throw new ArgumentException("Empty path", "path");
|
||||
|
||||
return BetterStreamingAssetsImp.ReadAllBytes(path);
|
||||
}
|
||||
|
||||
public static string[] GetFiles(string path, string searchPattern, SearchOption searchOption)
|
||||
{
|
||||
return BetterStreamingAssetsImp.GetFiles(path, searchPattern, searchOption);
|
||||
}
|
||||
|
||||
public static string[] GetFiles(string path)
|
||||
{
|
||||
return GetFiles(path, null);
|
||||
}
|
||||
|
||||
public static string[] GetFiles(string path, string searchPattern)
|
||||
{
|
||||
return GetFiles(path, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
}
|
||||
|
||||
private static ReadInfo GetInfoOrThrow(string path)
|
||||
{
|
||||
ReadInfo result;
|
||||
if ( !BetterStreamingAssetsImp.TryGetInfo(path, out result) )
|
||||
ThrowFileNotFound(path);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void ThrowFileNotFound(string path)
|
||||
{
|
||||
throw new FileNotFoundException("File not found", path);
|
||||
}
|
||||
|
||||
static partial void AndroidIsCompressedFileStreamingAsset(string path, ref bool result);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
internal static class EditorImpl
|
||||
{
|
||||
public static bool ApkMode = false;
|
||||
|
||||
public static string s_root
|
||||
{
|
||||
get { return ApkMode ? ApkImpl.s_root : LooseFilesImpl.s_root; }
|
||||
}
|
||||
|
||||
internal static void Initialize(string dataPath, string streamingAssetsPath)
|
||||
{
|
||||
if ( ApkMode )
|
||||
{
|
||||
ApkImpl.Initialize(dataPath, streamingAssetsPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
LooseFilesImpl.Initialize(dataPath, streamingAssetsPath);
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool TryGetInfo(string path, out ReadInfo info)
|
||||
{
|
||||
if ( ApkMode )
|
||||
return ApkImpl.TryGetInfo(path, out info);
|
||||
else
|
||||
return LooseFilesImpl.TryGetInfo(path, out info);
|
||||
}
|
||||
|
||||
internal static bool DirectoryExists(string path)
|
||||
{
|
||||
if ( ApkMode )
|
||||
return ApkImpl.DirectoryExists(path);
|
||||
else
|
||||
return LooseFilesImpl.DirectoryExists(path);
|
||||
}
|
||||
|
||||
internal static Stream OpenRead(string path)
|
||||
{
|
||||
if ( ApkMode )
|
||||
return ApkImpl.OpenRead(path);
|
||||
else
|
||||
return LooseFilesImpl.OpenRead(path);
|
||||
}
|
||||
|
||||
internal static byte[] ReadAllBytes(string path)
|
||||
{
|
||||
if ( ApkMode )
|
||||
return ApkImpl.ReadAllBytes(path);
|
||||
else
|
||||
return LooseFilesImpl.ReadAllBytes(path);
|
||||
}
|
||||
|
||||
internal static string[] GetFiles(string path, string searchPattern, SearchOption searchOption)
|
||||
{
|
||||
if ( ApkMode )
|
||||
return ApkImpl.GetFiles(path, searchPattern, searchOption);
|
||||
else
|
||||
return LooseFilesImpl.GetFiles(path, searchPattern, searchOption);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UNITY_EDITOR || !UNITY_ANDROID
|
||||
internal static class LooseFilesImpl
|
||||
{
|
||||
public static string s_root;
|
||||
private static string[] s_emptyArray = new string[0];
|
||||
|
||||
public static void Initialize(string dataPath, string streamingAssetsPath)
|
||||
{
|
||||
s_root = Path.GetFullPath(streamingAssetsPath).Replace('\\', '/').TrimEnd('/');
|
||||
}
|
||||
|
||||
public static string[] GetFiles(string path, string searchPattern, SearchOption searchOption)
|
||||
{
|
||||
if (!Directory.Exists(s_root))
|
||||
return s_emptyArray;
|
||||
|
||||
// this will throw if something is fishy
|
||||
path = PathUtil.NormalizeRelativePath(path, forceTrailingSlash : true);
|
||||
|
||||
Debug.Assert(s_root.Last() != '\\' && s_root.Last() != '/' && path.StartsWith("/"));
|
||||
|
||||
var files = Directory.GetFiles(s_root + path, searchPattern ?? "*", searchOption);
|
||||
|
||||
for ( int i = 0; i < files.Length; ++i )
|
||||
{
|
||||
Debug.Assert(files[i].StartsWith(s_root));
|
||||
files[i] = files[i].Substring(s_root.Length + 1).Replace('\\', '/');
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
// purge meta files
|
||||
{
|
||||
int j = 0;
|
||||
for ( int i = 0; i < files.Length; ++i )
|
||||
{
|
||||
if ( !files[i].EndsWith(".meta") )
|
||||
{
|
||||
files[j++] = files[i];
|
||||
}
|
||||
}
|
||||
Array.Resize(ref files, j);
|
||||
}
|
||||
|
||||
#endif
|
||||
return files;
|
||||
}
|
||||
|
||||
public static bool TryGetInfo(string path, out ReadInfo info)
|
||||
{
|
||||
path = PathUtil.NormalizeRelativePath(path);
|
||||
|
||||
info = new ReadInfo();
|
||||
|
||||
var fullPath = s_root + path;
|
||||
if ( !File.Exists(fullPath) )
|
||||
return false;
|
||||
|
||||
info.readPath = fullPath;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool DirectoryExists(string path)
|
||||
{
|
||||
var normalized = PathUtil.NormalizeRelativePath(path);
|
||||
return Directory.Exists(s_root + normalized);
|
||||
}
|
||||
|
||||
public static byte[] ReadAllBytes(string path)
|
||||
{
|
||||
ReadInfo info;
|
||||
|
||||
if ( !TryGetInfo(path, out info) )
|
||||
ThrowFileNotFound(path);
|
||||
|
||||
return File.ReadAllBytes(info.readPath);
|
||||
}
|
||||
|
||||
public static System.IO.Stream OpenRead(string path)
|
||||
{
|
||||
ReadInfo info;
|
||||
if ( !TryGetInfo(path, out info) )
|
||||
ThrowFileNotFound(path);
|
||||
|
||||
Stream fileStream = File.OpenRead(info.readPath);
|
||||
try
|
||||
{
|
||||
return new SubReadOnlyStream(fileStream, leaveOpen: false);
|
||||
}
|
||||
catch ( System.Exception )
|
||||
{
|
||||
fileStream.Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UNITY_EDITOR || UNITY_ANDROID
|
||||
internal static class ApkImpl
|
||||
{
|
||||
private static string[] s_paths;
|
||||
private static PartInfo[] s_streamingAssets;
|
||||
public static string s_root;
|
||||
|
||||
private struct PartInfo
|
||||
{
|
||||
public long size;
|
||||
public long offset;
|
||||
public uint crc32;
|
||||
}
|
||||
|
||||
public static void Initialize(string dataPath, string streamingAssetsPath)
|
||||
{
|
||||
s_root = dataPath;
|
||||
|
||||
List<string> paths = new List<string>();
|
||||
List<PartInfo> parts = new List<PartInfo>();
|
||||
|
||||
GetStreamingAssetsInfoFromJar(s_root, paths, parts);
|
||||
|
||||
if (paths.Count == 0 && !Application.isEditor && Path.GetFileName(dataPath) != "base.apk")
|
||||
{
|
||||
// maybe split?
|
||||
var newDataPath = Path.GetDirectoryName(dataPath) + "/base.apk";
|
||||
if (File.Exists(newDataPath))
|
||||
{
|
||||
s_root = newDataPath;
|
||||
GetStreamingAssetsInfoFromJar(newDataPath, paths, parts);
|
||||
}
|
||||
}
|
||||
|
||||
s_paths = paths.ToArray();
|
||||
s_streamingAssets = parts.ToArray();
|
||||
}
|
||||
|
||||
public static bool TryGetInfo(string path, out ReadInfo info)
|
||||
{
|
||||
path = PathUtil.NormalizeRelativePath(path);
|
||||
info = new ReadInfo();
|
||||
|
||||
var index = Array.BinarySearch(s_paths, path, StringComparer.OrdinalIgnoreCase);
|
||||
if ( index < 0 )
|
||||
return false;
|
||||
|
||||
var dataInfo = s_streamingAssets[index];
|
||||
info.crc32 = dataInfo.crc32;
|
||||
info.offset = dataInfo.offset;
|
||||
info.size = dataInfo.size;
|
||||
info.readPath = s_root;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool DirectoryExists(string path)
|
||||
{
|
||||
var normalized = PathUtil.NormalizeRelativePath(path, forceTrailingSlash : true);
|
||||
var dirIndex = GetDirectoryIndex(normalized);
|
||||
return dirIndex >= 0 && dirIndex < s_paths.Length;
|
||||
}
|
||||
|
||||
public static string[] GetFiles(string path, string searchPattern, SearchOption searchOption)
|
||||
{
|
||||
if ( path == null )
|
||||
throw new ArgumentNullException("path");
|
||||
|
||||
var actualDirPath = PathUtil.NormalizeRelativePath(path, forceTrailingSlash : true);
|
||||
|
||||
// find first file there
|
||||
var index = GetDirectoryIndex(actualDirPath);
|
||||
if ( index < 0 )
|
||||
throw new IOException();
|
||||
if ( index == s_paths.Length )
|
||||
throw new DirectoryNotFoundException();
|
||||
|
||||
Predicate<string> filter;
|
||||
if ( string.IsNullOrEmpty(searchPattern) || searchPattern == "*" )
|
||||
{
|
||||
filter = null;
|
||||
}
|
||||
else if ( searchPattern.IndexOf('*') >= 0 || searchPattern.IndexOf('?') >= 0 )
|
||||
{
|
||||
var regex = PathUtil.WildcardToRegex(searchPattern);
|
||||
filter = (x) => regex.IsMatch(x);
|
||||
}
|
||||
else
|
||||
{
|
||||
filter = (x) => string.Compare(x, searchPattern, true) == 0;
|
||||
}
|
||||
|
||||
List<string> results = new List<string>();
|
||||
string fixedPath = null;
|
||||
|
||||
for ( int i = index; i < s_paths.Length; ++i )
|
||||
{
|
||||
var filePath = s_paths[i];
|
||||
|
||||
if ( !filePath.StartsWith(actualDirPath) )
|
||||
break;
|
||||
|
||||
string fileName;
|
||||
|
||||
var dirSeparatorIndex = filePath.LastIndexOf('/', filePath.Length - 1, filePath.Length - actualDirPath.Length);
|
||||
if ( dirSeparatorIndex >= 0 )
|
||||
{
|
||||
if ( searchOption == SearchOption.TopDirectoryOnly )
|
||||
continue;
|
||||
|
||||
fileName = filePath.Substring(dirSeparatorIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fileName = filePath.Substring(actualDirPath.Length);
|
||||
}
|
||||
|
||||
// now do a match
|
||||
if ( filter == null || filter(fileName) )
|
||||
{
|
||||
var normalizedPart = filePath.Substring(actualDirPath.Length);
|
||||
|
||||
if ( fixedPath == null )
|
||||
{
|
||||
fixedPath = PathUtil.FixTrailingDirectorySeparators(path);
|
||||
if ( fixedPath == "/" )
|
||||
fixedPath = string.Empty;
|
||||
}
|
||||
|
||||
var result = PathUtil.CombineSlash(fixedPath, normalizedPart);
|
||||
results.Add(result);
|
||||
}
|
||||
}
|
||||
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] ReadAllBytes(string path)
|
||||
{
|
||||
ReadInfo info;
|
||||
if ( !TryGetInfo(path, out info) )
|
||||
ThrowFileNotFound(path);
|
||||
|
||||
byte[] buffer;
|
||||
using ( var fileStream = File.OpenRead(info.readPath) )
|
||||
{
|
||||
if ( info.offset != 0 )
|
||||
{
|
||||
if ( fileStream.Seek(info.offset, SeekOrigin.Begin) != info.offset )
|
||||
throw new IOException();
|
||||
}
|
||||
|
||||
if ( info.size > (long)int.MaxValue )
|
||||
throw new IOException();
|
||||
|
||||
int count = (int)info.size;
|
||||
int offset = 0;
|
||||
|
||||
buffer = new byte[count];
|
||||
while ( count > 0 )
|
||||
{
|
||||
int num = fileStream.Read(buffer, offset, count);
|
||||
if ( num == 0 )
|
||||
throw new EndOfStreamException();
|
||||
offset += num;
|
||||
count -= num;
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static System.IO.Stream OpenRead(string path)
|
||||
{
|
||||
ReadInfo info;
|
||||
if ( !TryGetInfo(path, out info) )
|
||||
ThrowFileNotFound(path);
|
||||
|
||||
Stream fileStream = File.OpenRead(info.readPath);
|
||||
try
|
||||
{
|
||||
return new SubReadOnlyStream(fileStream, info.offset, info.size, leaveOpen : false);
|
||||
}
|
||||
catch ( System.Exception )
|
||||
{
|
||||
fileStream.Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetDirectoryIndex(string path)
|
||||
{
|
||||
Debug.Assert(s_paths != null);
|
||||
|
||||
// find first file there
|
||||
var index = Array.BinarySearch(s_paths, path, StringComparer.OrdinalIgnoreCase);
|
||||
if ( index >= 0 )
|
||||
return ~index;
|
||||
|
||||
// if the end, no such directory exists
|
||||
index = ~index;
|
||||
if ( index == s_paths.Length )
|
||||
return index;
|
||||
|
||||
for ( int i = index; i < s_paths.Length && s_paths[i].StartsWith(path); ++i )
|
||||
{
|
||||
// because otherwise there would be a match
|
||||
Debug.Assert(s_paths[i].Length > path.Length);
|
||||
|
||||
if ( path[path.Length - 1] == '/' )
|
||||
return i;
|
||||
|
||||
if ( s_paths[i][path.Length] == '/' )
|
||||
return i;
|
||||
}
|
||||
|
||||
return s_paths.Length;
|
||||
}
|
||||
|
||||
private static void GetStreamingAssetsInfoFromJar(string apkPath, List<string> paths, List<PartInfo> parts)
|
||||
{
|
||||
using ( var stream = File.OpenRead(apkPath) )
|
||||
using ( var reader = new BinaryReader(stream) )
|
||||
{
|
||||
if ( !stream.CanRead )
|
||||
throw new ArgumentException();
|
||||
if ( !stream.CanSeek )
|
||||
throw new ArgumentException();
|
||||
|
||||
long expectedNumberOfEntries;
|
||||
long centralDirectoryStart;
|
||||
ZipArchiveUtils.ReadEndOfCentralDirectory(stream, reader, out expectedNumberOfEntries, out centralDirectoryStart);
|
||||
|
||||
try
|
||||
{
|
||||
stream.Seek(centralDirectoryStart, SeekOrigin.Begin);
|
||||
|
||||
long numberOfEntries = 0;
|
||||
|
||||
ZipCentralDirectoryFileHeader header;
|
||||
|
||||
const int prefixLength = 7;
|
||||
const string prefix = "assets/";
|
||||
const string assetsPrefix = "assets/bin/";
|
||||
Debug.Assert(prefixLength == prefix.Length);
|
||||
|
||||
while ( ZipCentralDirectoryFileHeader.TryReadBlock(reader, out header) )
|
||||
{
|
||||
if ( header.CompressedSize != header.UncompressedSize )
|
||||
{
|
||||
#if UNITY_ASSERTIONS
|
||||
var fileName = Encoding.UTF8.GetString(header.Filename);
|
||||
if (fileName.StartsWith(prefix) && !fileName.StartsWith(assetsPrefix))
|
||||
{
|
||||
bool isStreamingAsset = true;
|
||||
AndroidIsCompressedFileStreamingAsset(fileName, ref isStreamingAsset);
|
||||
if (isStreamingAsset)
|
||||
{
|
||||
Debug.LogAssertionFormat("BetterStreamingAssets: file {0} is where Streaming Assets are put, but is compressed. " +
|
||||
"If this is a App Bundle build, see README for a possible workaround. " +
|
||||
"If this file is not a Streaming Asset (has been on purpose by hand or by another plug-in), implement " +
|
||||
"BetterStreamingAssets.AndroidIsCompressedFileStreamingAsset partial method to prevent this message from appearing again. ",
|
||||
fileName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// we only want uncompressed files
|
||||
}
|
||||
else
|
||||
{
|
||||
var fileName = Encoding.UTF8.GetString(header.Filename);
|
||||
|
||||
if (fileName.EndsWith("/"))
|
||||
{
|
||||
// there's some strangeness when it comes to OBB: directories are listed as files
|
||||
// simply ignoring them should be enough
|
||||
Debug.Assert(header.UncompressedSize == 0);
|
||||
}
|
||||
else if ( fileName.StartsWith(prefix) )
|
||||
{
|
||||
// ignore normal assets...
|
||||
if ( fileName.StartsWith(assetsPrefix) )
|
||||
{
|
||||
// Note: if you put bin directory in your StreamingAssets you will get false negative here
|
||||
}
|
||||
else
|
||||
{
|
||||
var relativePath = fileName.Substring(prefixLength - 1);
|
||||
var entry = new PartInfo()
|
||||
{
|
||||
crc32 = header.Crc32,
|
||||
offset = header.RelativeOffsetOfLocalHeader, // this offset will need fixing later on
|
||||
size = header.UncompressedSize
|
||||
};
|
||||
|
||||
var index = paths.BinarySearch(relativePath, StringComparer.OrdinalIgnoreCase);
|
||||
if ( index >= 0 )
|
||||
throw new System.InvalidOperationException("Paths duplicate! " + fileName);
|
||||
|
||||
paths.Insert(~index, relativePath);
|
||||
parts.Insert(~index, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
numberOfEntries++;
|
||||
}
|
||||
|
||||
if ( numberOfEntries != expectedNumberOfEntries )
|
||||
throw new ZipArchiveException("Number of entries does not match");
|
||||
|
||||
}
|
||||
catch ( EndOfStreamException ex )
|
||||
{
|
||||
throw new ZipArchiveException("CentralDirectoryInvalid", ex);
|
||||
}
|
||||
|
||||
// now fix offsets
|
||||
for ( int i = 0; i < parts.Count; ++i )
|
||||
{
|
||||
var entry = parts[i];
|
||||
stream.Seek(entry.offset, SeekOrigin.Begin);
|
||||
|
||||
if ( !ZipLocalFileHeader.TrySkipBlock(reader) )
|
||||
throw new ZipArchiveException("Local file header corrupt");
|
||||
|
||||
entry.offset = stream.Position;
|
||||
|
||||
parts[i] = entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user