Update AssetBundleBuilder

This commit is contained in:
hevinci
2022-04-02 15:12:08 +08:00
parent b6c07cd956
commit 9de27e790d
16 changed files with 321 additions and 358 deletions
@@ -18,7 +18,7 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
var buildMapContext = context.GetContextObject<TaskGetBuildMap.BuildMapContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
Debug.Log($"开始构建......");
BuildAssetBundleOptions opt = buildParametersContext.GetPipelineBuildOptions();
@@ -57,7 +57,7 @@ namespace YooAsset.Editor
private void VerifyingBuildingResult(BuildContext context, AssetBundleManifest unityManifest)
{
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
var buildMapContext = context.GetContextObject<TaskGetBuildMap.BuildMapContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
string[] buildedBundles = unityManifest.GetAllAssetBundles();
// 1. 过滤掉原生Bundle
@@ -14,7 +14,7 @@ namespace YooAsset.Editor
{
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
var encryptionContext = context.GetContextObject<TaskEncryption.EncryptionContext>();
var buildMapContext = context.GetContextObject<TaskGetBuildMap.BuildMapContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
CreatePatchManifestFile(buildParameters, buildMapContext, encryptionContext);
}
@@ -22,7 +22,7 @@ namespace YooAsset.Editor
/// 创建补丁清单文件到输出目录
/// </summary>
private void CreatePatchManifestFile(AssetBundleBuilder.BuildParametersContext buildParameters,
TaskGetBuildMap.BuildMapContext buildMapContext, TaskEncryption.EncryptionContext encryptionContext)
BuildMapContext buildMapContext, TaskEncryption.EncryptionContext encryptionContext)
{
// 创建新补丁清单
PatchManifest patchManifest = new PatchManifest();
@@ -47,7 +47,7 @@ namespace YooAsset.Editor
/// 获取资源包列表
/// </summary>
private List<PatchBundle> GetAllPatchBundle(AssetBundleBuilder.BuildParametersContext buildParameters,
TaskGetBuildMap.BuildMapContext buildMapContext, TaskEncryption.EncryptionContext encryptionContext)
BuildMapContext buildMapContext, TaskEncryption.EncryptionContext encryptionContext)
{
List<PatchBundle> result = new List<PatchBundle>(1000);
@@ -111,12 +111,12 @@ namespace YooAsset.Editor
/// <summary>
/// 获取资源列表
/// </summary>
private List<PatchAsset> GetAllPatchAsset(TaskGetBuildMap.BuildMapContext buildMapContext, PatchManifest patchManifest)
private List<PatchAsset> GetAllPatchAsset(BuildMapContext buildMapContext, PatchManifest patchManifest)
{
List<PatchAsset> result = new List<PatchAsset>(1000);
foreach (var bundleInfo in buildMapContext.BundleInfos)
{
var assetInfos = bundleInfo.GetCollectAssetInfos();
var assetInfos = bundleInfo.GetAllPatchAssetInfos();
foreach (var assetInfo in assetInfos)
{
PatchAsset patchAsset = new PatchAsset();
@@ -12,11 +12,11 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context)
{
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
var buildMapContext = context.GetContextObject<TaskGetBuildMap.BuildMapContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
CreateReportFile(buildParameters, buildMapContext);
}
private void CreateReportFile(AssetBundleBuilder.BuildParametersContext buildParameters, TaskGetBuildMap.BuildMapContext buildMapContext)
private void CreateReportFile(AssetBundleBuilder.BuildParametersContext buildParameters, BuildMapContext buildMapContext)
{
PatchManifest patchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(buildParameters.PipelineOutputDirectory);
BuildReport buildReport = new BuildReport();
@@ -31,8 +31,8 @@ namespace YooAsset.Editor
buildReport.Summary.BuildVersion = buildParameters.Parameters.BuildVersion;
buildReport.Summary.EnableAutoCollect = buildParameters.Parameters.EnableAutoCollect;
buildReport.Summary.AppendFileExtension = buildParameters.Parameters.AppendFileExtension;
buildReport.Summary.AutoCollectShaders = AssetBundleCollectorSettingData.Setting.AutoCollectShaders;
buildReport.Summary.ShadersBundleName = AssetBundleCollectorSettingData.Setting.ShadersBundleName;
buildReport.Summary.AutoCollectShaders = AssetBundleGrouperSettingData.Setting.AutoCollectShaders;
buildReport.Summary.ShadersBundleName = AssetBundleGrouperSettingData.Setting.ShadersBundleName;
buildReport.Summary.EncryptionServicesClassName = buildParameters.Parameters.EncryptionServices == null ?
"null" : buildParameters.Parameters.EncryptionServices.GetType().FullName;
buildReport.Summary.RedundancyServicesClassName = buildParameters.Parameters.RedundancyServices == null ?
@@ -49,7 +49,6 @@ namespace YooAsset.Editor
// 构建结果
buildReport.Summary.AssetFileTotalCount = buildMapContext.AssetFileCount;
buildReport.Summary.RedundancyAssetFileCount = buildMapContext.RedundancyAssetList.Count;
buildReport.Summary.AllBundleTotalCount = GetAllBundleCount(patchManifest);
buildReport.Summary.AllBundleTotalSize = GetAllBundleSize(patchManifest);
buildReport.Summary.BuildinBundleTotalCount = GetBuildinBundleCount(patchManifest);
@@ -58,8 +57,6 @@ namespace YooAsset.Editor
buildReport.Summary.EncryptedBundleTotalSize = GetEncryptedBundleSize(patchManifest);
buildReport.Summary.RawBundleTotalCount = GetRawBundleCount(patchManifest);
buildReport.Summary.RawBundleTotalSize = GetRawBundleSize(patchManifest);
}
// 资源对象列表
@@ -90,20 +87,6 @@ namespace YooAsset.Editor
buildReport.BundleInfos.Add(reportBundleInfo);
}
// 收集器列表
for (int i = 0; i < AssetBundleCollectorSettingData.Setting.Collectors.Count; i++)
{
var wrapper = AssetBundleCollectorSettingData.Setting.Collectors[i];
buildReport.CollectorInfoList.Add(wrapper.ToString());
}
// 冗余资源列表
for (int i = 0; i < buildMapContext.RedundancyAssetList.Count; i++)
{
string redundancyAssetPath = buildMapContext.RedundancyAssetList[i];
buildReport.RedundancyAssetList.Add(redundancyAssetPath);
}
// 删除旧文件
string filePath = $"{buildParameters.PipelineOutputDirectory}/{YooAssetSettings.ReportFileName}";
if (File.Exists(filePath))
@@ -130,7 +113,7 @@ namespace YooAsset.Editor
/// <summary>
/// 获取资源对象依赖的其它所有资源
/// </summary>
private List<string> GetDependAssets(TaskGetBuildMap.BuildMapContext buildMapContext, string bundleName, string assetPath)
private List<string> GetDependAssets(BuildMapContext buildMapContext, string bundleName, string assetPath)
{
List<string> result = new List<string>();
if (buildMapContext.TryGetBundleInfo(bundleName, out BuildBundleInfo bundleInfo))
@@ -24,7 +24,7 @@ namespace YooAsset.Editor
void IBuildTask.Run(BuildContext context)
{
var buildParameters = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
var buildMapContext = context.GetContextObject<TaskGetBuildMap.BuildMapContext>();
var buildMapContext = context.GetContextObject<BuildMapContext>();
EncryptionContext encryptionContext = new EncryptionContext();
encryptionContext.EncryptList = EncryptFiles(buildParameters, buildMapContext);
@@ -34,7 +34,7 @@ namespace YooAsset.Editor
/// <summary>
/// 加密文件
/// </summary>
private List<string> EncryptFiles(AssetBundleBuilder.BuildParametersContext buildParameters, TaskGetBuildMap.BuildMapContext buildMapContext)
private List<string> EncryptFiles(AssetBundleBuilder.BuildParametersContext buildParameters, BuildMapContext buildMapContext)
{
var encryptionServices = buildParameters.Parameters.EncryptionServices;
@@ -9,267 +9,15 @@ namespace YooAsset.Editor
{
public class TaskGetBuildMap : IBuildTask
{
public class BuildMapContext : IContextObject
{
/// <summary>
/// 参与构建的资源总数
/// 说明:包括主动收集的资源以及其依赖的所有资源
/// </summary>
public int AssetFileCount;
/// <summary>
/// 资源包列表
/// </summary>
public readonly List<BuildBundleInfo> BundleInfos = new List<BuildBundleInfo>(1000);
/// <summary>
/// 冗余的资源列表
/// </summary>
public readonly List<string> RedundancyAssetList = new List<string>(1000);
/// <summary>
/// 添加一个打包资源
/// </summary>
public void PackAsset(BuildAssetInfo assetInfo)
{
if (TryGetBundleInfo(assetInfo.BundleName, out BuildBundleInfo bundleInfo))
{
bundleInfo.PackAsset(assetInfo);
}
else
{
BuildBundleInfo newBundleInfo = new BuildBundleInfo(assetInfo.BundleName);
newBundleInfo.PackAsset(assetInfo);
BundleInfos.Add(newBundleInfo);
}
}
/// <summary>
/// 获取所有的打包资源
/// </summary>
public List<BuildAssetInfo> GetAllAssets()
{
List<BuildAssetInfo> result = new List<BuildAssetInfo>(BundleInfos.Count);
foreach (var bundleInfo in BundleInfos)
{
result.AddRange(bundleInfo.BuildinAssets);
}
return result;
}
/// <summary>
/// 获取AssetBundle内包含的标记列表
/// </summary>
public string[] GetAssetTags(string bundleFullName)
{
if (TryGetBundleInfo(bundleFullName, out BuildBundleInfo bundleInfo))
{
return bundleInfo.GetAssetTags();
}
throw new Exception($"Not found {nameof(BuildBundleInfo)} : {bundleFullName}");
}
/// <summary>
/// 获取AssetBundle内构建的资源路径列表
/// </summary>
public string[] GetBuildinAssetPaths(string bundleFullName)
{
if (TryGetBundleInfo(bundleFullName, out BuildBundleInfo bundleInfo))
{
return bundleInfo.GetBuildinAssetPaths();
}
throw new Exception($"Not found {nameof(BuildBundleInfo)} : {bundleFullName}");
}
/// <summary>
/// 获取构建管线里需要的数据
/// </summary>
public UnityEditor.AssetBundleBuild[] GetPipelineBuilds()
{
List<UnityEditor.AssetBundleBuild> builds = new List<UnityEditor.AssetBundleBuild>(BundleInfos.Count);
foreach (var bundleInfo in BundleInfos)
{
if (bundleInfo.IsRawFile == false)
builds.Add(bundleInfo.CreatePipelineBuild());
}
return builds.ToArray();
}
/// <summary>
/// 是否包含资源包
/// </summary>
public bool IsContainsBundle(string bundleFullName)
{
return TryGetBundleInfo(bundleFullName, out BuildBundleInfo bundleInfo);
}
public bool TryGetBundleInfo(string bundleFullName, out BuildBundleInfo result)
{
foreach (var bundleInfo in BundleInfos)
{
if (bundleInfo.BundleName == bundleFullName)
{
result = bundleInfo;
return true;
}
}
result = null;
return false;
}
}
void IBuildTask.Run(BuildContext context)
{
var buildParametersContext = context.GetContextObject<AssetBundleBuilder.BuildParametersContext>();
BuildMapContext buildMapContext = new BuildMapContext();
var buildMapContext = BuildMapHelper.SetupBuildMap();
context.SetContextObject(buildMapContext);
SetupBuildMap(buildMapContext, buildParametersContext);
// 检测构建结果
CheckBuildMapContent(buildMapContext);
}
/// <summary>
/// 组织构建的资源包
/// </summary>
private void SetupBuildMap(BuildMapContext buildMapContext, AssetBundleBuilder.BuildParametersContext buildParameters)
{
Dictionary<string, BuildAssetInfo> buildAssetDic = new Dictionary<string, BuildAssetInfo>();
// 1. 获取主动收集的资源
List<CollectAssetInfo> allCollectInfos = AssetBundleCollectorSettingData.GetAllCollectAssets();
// 2. 对收集的资源进行依赖分析
int progressValue = 0;
foreach (CollectAssetInfo collectInfo in allCollectInfos)
{
string mainAssetPath = collectInfo.AssetPath;
// 获取所有依赖资源
List<BuildAssetInfo> depends = GetAllDependencies(mainAssetPath);
for (int i = 0; i < depends.Count; i++)
{
string assetPath = depends[i].AssetPath;
// 如果已经存在,则增加该资源的依赖计数
if (buildAssetDic.ContainsKey(assetPath))
buildAssetDic[assetPath].DependCount++;
else
buildAssetDic.Add(assetPath, depends[i]);
// 添加资源标记
buildAssetDic[assetPath].AddAssetTags(collectInfo.AssetTags);
// 注意:检测是否为主动收集资源
if (assetPath == mainAssetPath)
{
buildAssetDic[mainAssetPath].IsCollectAsset = true;
buildAssetDic[mainAssetPath].IsRawAsset = collectInfo.IsRawAsset;
}
}
// 添加所有的依赖资源列表
// 注意:不包括自己
var allDependAssetInfos = new List<BuildAssetInfo>(depends.Count);
for (int i = 0; i < depends.Count; i++)
{
string assetPath = depends[i].AssetPath;
if (assetPath != mainAssetPath)
allDependAssetInfos.Add(buildAssetDic[assetPath]);
}
buildAssetDic[mainAssetPath].SetAllDependAssetInfos(allDependAssetInfos);
EditorTools.DisplayProgressBar("依赖文件分析", ++progressValue, allCollectInfos.Count);
}
EditorTools.ClearProgressBar();
// 3. 记录参与构建的资源总数
buildMapContext.AssetFileCount = buildAssetDic.Values.Count;
// 4. 移除零依赖的资源
var redundancyServices = buildParameters.Parameters.RedundancyServices;
List<BuildAssetInfo> undependentAssets = new List<BuildAssetInfo>();
foreach (KeyValuePair<string, BuildAssetInfo> pair in buildAssetDic)
{
var buildAssetInfo = pair.Value;
if (buildAssetInfo.IsCollectAsset)
continue;
// 零依赖资源
if (buildAssetInfo.DependCount == 0)
{
undependentAssets.Add(buildAssetInfo);
continue;
}
// 冗余扩展
if (redundancyServices != null && redundancyServices.Check(buildAssetInfo.AssetPath))
{
undependentAssets.Add(buildAssetInfo);
buildMapContext.RedundancyAssetList.Add(buildAssetInfo.AssetPath);
continue;
}
// 如果没有开启自动分包,没有被收集到的资源会造成冗余
if (buildParameters.Parameters.EnableAutoCollect == false)
{
if (AssetBundleCollectorSettingData.HasCollector(buildAssetInfo.AssetPath) == false)
{
undependentAssets.Add(buildAssetInfo);
buildMapContext.RedundancyAssetList.Add(buildAssetInfo.AssetPath);
}
}
}
foreach (var assetInfo in undependentAssets)
{
buildAssetDic.Remove(assetInfo.AssetPath);
}
// 5. 设置资源包名
progressValue = 0;
foreach (KeyValuePair<string, BuildAssetInfo> pair in buildAssetDic)
{
var assetInfo = pair.Value;
var bundleLabel = AssetBundleCollectorSettingData.GetBundleLabel(assetInfo.AssetPath);
if (assetInfo.IsRawAsset)
assetInfo.SetBundleLabelAndVariant(bundleLabel, YooAssetSettingsData.Setting.RawFileVariant);
else
assetInfo.SetBundleLabelAndVariant(bundleLabel, YooAssetSettingsData.Setting.AssetBundleFileVariant);
EditorTools.DisplayProgressBar("设置资源包名", ++progressValue, buildAssetDic.Count);
}
EditorTools.ClearProgressBar();
// 6. 构建资源包
var allAssets = buildAssetDic.Values.ToList();
if (allAssets.Count == 0)
throw new Exception("构建的资源列表不能为空");
foreach (var assetInfo in allAssets)
{
buildMapContext.PackAsset(assetInfo);
}
}
/// <summary>
/// 获取指定资源依赖的所有资源列表
/// 注意:返回列表里已经包括主资源自己
/// </summary>
private List<BuildAssetInfo> GetAllDependencies(string mainAssetPath)
{
List<BuildAssetInfo> result = new List<BuildAssetInfo>();
string[] depends = AssetDatabase.GetDependencies(mainAssetPath, true);
foreach (string assetPath in depends)
{
if (AssetBundleCollectorSettingData.IsValidateAsset(assetPath))
{
BuildAssetInfo assetInfo = new BuildAssetInfo(assetPath);
result.Add(assetInfo);
}
}
return result;
}
/// <summary>
/// 检测构建结果
/// </summary>
@@ -25,10 +25,6 @@ namespace YooAsset.Editor
if (string.IsNullOrEmpty(buildParameters.PipelineOutputDirectory))
throw new Exception("输出目录不能为空");
// 检测资源收集配置文件
if (AssetBundleCollectorSettingData.GetCollecterCount() == 0)
throw new Exception("配置的资源收集路径为空");
// 增量更新时候的必要检测
if (buildParameters.Parameters.ForceRebuild == false)
{
@@ -46,10 +42,10 @@ namespace YooAsset.Editor
if (Directory.Exists(packageDirectory))
throw new Exception($"补丁包已经存在:{packageDirectory}");
// 检测内置资源标记是否一致
// 检测内置资源分类标签是否一致
PatchManifest oldPatchManifest = AssetBundleBuilderHelper.LoadPatchManifestFile(buildParameters.PipelineOutputDirectory);
if (buildParameters.Parameters.BuildinTags != oldPatchManifest.BuildinTags)
throw new Exception($"增量更新时内置资源标记必须一致:{buildParameters.Parameters.BuildinTags} != {oldPatchManifest.BuildinTags}");
throw new Exception($"增量更新时内置资源标签必须一致:{buildParameters.Parameters.BuildinTags} != {oldPatchManifest.BuildinTags}");
}
// 如果是强制重建