| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- using System;
- using System.IO;
- using System.Linq;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEditor;
- namespace YooAsset.Editor
- {
- public class TaskGetBuildMap
- {
- /// <summary>
- /// 生成资源构建上下文
- /// </summary>
- public BuildMapContext CreateBuildMap(bool simulateBuild, BuildParameters buildParameters)
- {
- BuildMapContext context = new BuildMapContext();
- var packageName = buildParameters.PackageName;
- Dictionary<string, BuildAssetInfo> allBuildAssetInfos = new Dictionary<string, BuildAssetInfo>(1000);
- // 1. 获取所有收集器收集的资源
- bool useAssetDependencyDB = buildParameters.UseAssetDependencyDB;
- var collectResult = AssetBundleCollectorSettingData.Setting.BeginCollect(packageName, simulateBuild, useAssetDependencyDB);
- List<CollectAssetInfo> allCollectAssets = collectResult.CollectAssets;
- // 2. 剔除未被引用的依赖项资源
- RemoveZeroReferenceAssets(context, allCollectAssets);
- // 3. 录入所有收集器主动收集的资源
- foreach (var collectAssetInfo in allCollectAssets)
- {
- if (allBuildAssetInfos.ContainsKey(collectAssetInfo.AssetInfo.AssetPath))
- {
- throw new Exception($"Should never get here !");
- }
- if (collectAssetInfo.CollectorType != ECollectorType.MainAssetCollector)
- {
- if (collectAssetInfo.AssetTags.Count > 0)
- {
- collectAssetInfo.AssetTags.Clear();
- string warning = BuildLogger.GetErrorMessage(ErrorCode.RemoveInvalidTags, $"Remove asset tags that don't work, see the asset collector type : {collectAssetInfo.AssetInfo.AssetPath}");
- BuildLogger.Warning(warning);
- }
- }
- var buildAssetInfo = new BuildAssetInfo(collectAssetInfo.CollectorType, collectAssetInfo.BundleName, collectAssetInfo.Address, collectAssetInfo.AssetInfo);
- buildAssetInfo.AddAssetTags(collectAssetInfo.AssetTags);
- allBuildAssetInfos.Add(collectAssetInfo.AssetInfo.AssetPath, buildAssetInfo);
- }
- // 4. 录入所有收集资源依赖的其它资源
- foreach (var collectAssetInfo in allCollectAssets)
- {
- string bundleName = collectAssetInfo.BundleName;
- foreach (var dependAsset in collectAssetInfo.DependAssets)
- {
- if (allBuildAssetInfos.TryGetValue(dependAsset.AssetPath, out var value))
- {
- value.AddReferenceBundleName(bundleName);
- }
- else
- {
- var buildAssetInfo = new BuildAssetInfo(dependAsset);
- buildAssetInfo.AddReferenceBundleName(bundleName);
- allBuildAssetInfos.Add(dependAsset.AssetPath, buildAssetInfo);
- }
- }
- }
- // 5. 填充所有收集资源的依赖列表
- foreach (var collectAssetInfo in allCollectAssets)
- {
- var dependAssetInfos = new List<BuildAssetInfo>(collectAssetInfo.DependAssets.Count);
- foreach (var dependAsset in collectAssetInfo.DependAssets)
- {
- if (allBuildAssetInfos.TryGetValue(dependAsset.AssetPath, out BuildAssetInfo value))
- dependAssetInfos.Add(value);
- else
- throw new Exception("Should never get here !");
- }
- allBuildAssetInfos[collectAssetInfo.AssetInfo.AssetPath].SetDependAssetInfos(dependAssetInfos);
- }
- // 6. 自动收集所有依赖的着色器
- if (collectResult.Command.AutoCollectShaders)
- {
- // 获取着色器打包规则结果
- PackRuleResult shaderPackRuleResult = DefaultPackRule.CreateShadersPackRuleResult();
- string shaderBundleName = shaderPackRuleResult.GetBundleName(collectResult.Command.PackageName, collectResult.Command.UniqueBundleName);
- foreach (var buildAssetInfo in allBuildAssetInfos.Values)
- {
- if (buildAssetInfo.CollectorType == ECollectorType.None)
- {
- if (buildAssetInfo.AssetInfo.IsShaderAsset())
- {
- buildAssetInfo.SetBundleName(shaderBundleName);
- }
- }
- }
- }
- // 7. 计算共享资源的包名
- if (buildParameters.EnableSharePackRule)
- {
- PreProcessPackShareBundle(buildParameters, collectResult.Command, allBuildAssetInfos);
- foreach (var buildAssetInfo in allBuildAssetInfos.Values)
- {
- if (buildAssetInfo.HasBundleName() == false)
- {
- ProcessingPackShareBundle(buildParameters, collectResult.Command, buildAssetInfo);
- }
- }
- PostProcessPackShareBundle(buildParameters, collectResult.Command, allBuildAssetInfos);
- }
- // 8. 记录关键信息
- context.AssetFileCount = allBuildAssetInfos.Count;
- context.Command = collectResult.Command;
- // 9. 移除不参与构建的资源
- List<BuildAssetInfo> removeBuildList = new List<BuildAssetInfo>();
- foreach (var buildAssetInfo in allBuildAssetInfos.Values)
- {
- if (buildAssetInfo.HasBundleName() == false)
- removeBuildList.Add(buildAssetInfo);
- }
- foreach (var removeValue in removeBuildList)
- {
- allBuildAssetInfos.Remove(removeValue.AssetInfo.AssetPath);
- }
- // 10. 构建资源列表
- var allPackAssets = allBuildAssetInfos.Values.ToList();
- if (allPackAssets.Count == 0)
- {
- string message = BuildLogger.GetErrorMessage(ErrorCode.PackAssetListIsEmpty, "The pack asset info is empty !");
- throw new Exception(message);
- }
- foreach (var assetInfo in allPackAssets)
- {
- context.PackAsset(assetInfo);
- }
- return context;
- }
- private void RemoveZeroReferenceAssets(BuildMapContext context, List<CollectAssetInfo> allCollectAssets)
- {
- // 1. 检测依赖资源收集器是否存在
- if (allCollectAssets.Exists(x => x.CollectorType == ECollectorType.DependAssetCollector) == false)
- return;
- // 2. 获取所有主资源的依赖资源集合
- HashSet<string> allDependAsset = new HashSet<string>();
- foreach (var collectAsset in allCollectAssets)
- {
- var collectorType = collectAsset.CollectorType;
- if (collectorType == ECollectorType.MainAssetCollector || collectorType == ECollectorType.StaticAssetCollector)
- {
- foreach (var dependAsset in collectAsset.DependAssets)
- {
- if (allDependAsset.Contains(dependAsset.AssetPath) == false)
- allDependAsset.Add(dependAsset.AssetPath);
- }
- }
- }
- // 3. 找出所有零引用的依赖资源集合
- List<CollectAssetInfo> removeList = new List<CollectAssetInfo>();
- foreach (var collectAssetInfo in allCollectAssets)
- {
- var collectorType = collectAssetInfo.CollectorType;
- if (collectorType == ECollectorType.DependAssetCollector)
- {
- if (allDependAsset.Contains(collectAssetInfo.AssetInfo.AssetPath) == false)
- removeList.Add(collectAssetInfo);
- }
- }
- // 4. 移除所有零引用的依赖资源
- foreach (var removeValue in removeList)
- {
- string warning = BuildLogger.GetErrorMessage(ErrorCode.FoundUndependedAsset, $"Found undepended asset and remove it : {removeValue.AssetInfo.AssetPath}");
- BuildLogger.Warning(warning);
- var independAsset = new ReportIndependAsset();
- independAsset.AssetPath = removeValue.AssetInfo.AssetPath;
- independAsset.AssetGUID = removeValue.AssetInfo.AssetGUID;
- independAsset.AssetType = removeValue.AssetInfo.AssetType.ToString();
- independAsset.FileSize = FileUtility.GetFileSize(removeValue.AssetInfo.AssetPath);
- context.IndependAssets.Add(independAsset);
- allCollectAssets.Remove(removeValue);
- }
- }
- #region 共享资源打包规则
- /// <summary>
- /// 共享资源打包前置处理
- /// </summary>
- protected virtual void PreProcessPackShareBundle(BuildParameters buildParameters, CollectCommand command, Dictionary<string, BuildAssetInfo> allBuildAssetInfos)
- {
- }
- /// <summary>
- /// 共享资源打包机制
- /// </summary>
- protected virtual void ProcessingPackShareBundle(BuildParameters buildParameters, CollectCommand command, BuildAssetInfo buildAssetInfo)
- {
- PackRuleResult packRuleResult = GetShareBundleName(buildAssetInfo);
- if (packRuleResult.IsValid() == false)
- return;
- // 处理单个引用的共享资源
- if (buildAssetInfo.GetReferenceBundleCount() <= 1)
- {
- if (buildParameters.SingleReferencedPackAlone == false)
- return;
- }
- // 设置共享资源包名
- string shareBundleName = packRuleResult.GetShareBundleName(command.PackageName, command.UniqueBundleName);
- buildAssetInfo.SetBundleName(shareBundleName);
- }
- private PackRuleResult GetShareBundleName(BuildAssetInfo buildAssetInfo)
- {
- string bundleName = Path.GetDirectoryName(buildAssetInfo.AssetInfo.AssetPath);
- PackRuleResult result = new PackRuleResult(bundleName, DefaultPackRule.AssetBundleFileExtension);
- return result;
- }
- /// <summary>
- /// 共享资源打包后置处理
- /// </summary>
- protected virtual void PostProcessPackShareBundle(BuildParameters buildParameters, CollectCommand command, Dictionary<string, BuildAssetInfo> allBuildAssetInfos)
- {
- }
- #endregion
- }
- }
|