123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- using XGame.Editor.Asset;
- using XGame.Framework.Asset;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using UnityEditor;
- using UnityEngine;
- namespace XGame.Editor.Build.AssetBundles
- {
- internal partial class BundleManifestsController
- {
- /// <summary>
- /// ab加密的偏移值上限
- /// </summary>
- internal readonly uint EncryptOffsetLimit = 256;
- private BundleContext _context;
- private AssetBundleCollector _bundleCollector;
- private BundleDepsController _depsController;
- private SceneManifestController _sceneController;
- public BundleManifestsController(BundleContext context, AssetBundleCollector bundleCollector, BundleDepsController depsController, SceneManifestController sceneController)
- {
- _context = context;
- _bundleCollector = bundleCollector;
- _depsController = depsController;
- _sceneController = sceneController;
- }
- public bool GenerateManifests()
- {
- _bundleCollector.CollectBundleBuilds(true);
- //检查重名资源
- if (!CheckAssetsNameRepeat())
- {
- //有同名资源就中断打包
- return false;
- }
- if (!_bundleCollector.CollectSceneBundles())
- {
- //可能有同名Scene
- return false;
- }
- //if (!_bundleCollector.MergeSceneBundles())
- //{
- // return false;
- //}
- //处理AssetBundle分组
- //_groupController.ModifyBundleNameByGroup();
- BuildLog.Log("BuildBundles count:" + _context.bundleDataMap.Count);
- if (!Directory.Exists(PathDefine.ConfigsRelative))
- {
- Directory.CreateDirectory(PathDefine.ConfigsRelative);
- }
- if (!GenerateBundleManifest() || !_sceneController.GenerateManifest() || !GenReferencesManifest())
- {
- return false;
- }
- BuildLog.Log($"AssetBundle GenerateManifests completed.");
- return true;
- }
- /// <summary>
- /// 收集bundle信息,后期可能需要改成异步操作
- /// </summary>
- /// <param name="bundleBuilds"></param>
- /// <returns></returns>
- private bool GenerateBundleManifest()
- {
- if (_context.bundleDataMap.Count == 0)
- {
- return false;
- }
- if (!_depsController.CollectBundleDependencies())
- {
- return false;
- }
- //BundleManifest
- string bundleManifestPath = PathDefine.BundleManifestPath;//"Assets/KCAssetBundlesData/KCAssetBundleManifest.asset";
- var kcBundleManifest = AssetDatabase.LoadAssetAtPath<AssetBundleInfosSo>(bundleManifestPath);
- if (kcBundleManifest == null)
- {
- kcBundleManifest = ScriptableObject.CreateInstance<AssetBundleInfosSo>();
- AssetDatabase.CreateAsset(kcBundleManifest, bundleManifestPath);
- }
- //bundle信息
- var bundleDataLst = _context.SortAssetBundleDatas();
- var count = bundleDataLst.Count;
- var bundleInfos = new AssetBundleInfo[count];
- var backupInfos = new AssetBundleBackupInfo[count];
- for (var index = 0; index < count; index++)
- {
- var bundleData = bundleDataLst[index];
- EditorUtility.DisplayProgressBar("Collect AssetBundleInfo", bundleData.assetBundleName, index / (float)count);
- var dependencies = _context.dependenciesMap[bundleData.bundleId];
- //var bundleId = CreateBundleId(build.assetBundleName, build.assetBundleVariant, build.addressableNames);
- //var bytes = System.Text.Encoding.UTF8.GetBytes(bundleData.originBundleName);
- //originBundleName大部分为guid,固定32字节,用bundleId取余数增加点offset的差异
- var originName = bundleData.originBundleName;
- var offset = (uint)Math.Clamp(bundleData.bundleId % originName.Length, 4, EncryptOffsetLimit);
- var bundleInfo = new AssetBundleInfo()
- {
- bundleName = bundleData.assetBundleName,
- variantName = bundleData.assetBundleVariant,
- bundleId = bundleData.bundleId,
- assets = bundleData.addressableNames,
- dependencies = dependencies,
- //originBundleName = originName,
- offset = offset,
- };
- bundleInfos[index] = bundleInfo;
- // 备份数据
- var backupInfo = new AssetBundleBackupInfo()
- {
- bundleName = bundleData.assetBundleName,
- variantName = bundleData.assetBundleVariant,
- bundleId = bundleData.bundleId,
- assets = bundleData.addressableNames,
- dependencies = dependencies,
- offset = offset,
- bundleType = bundleData.bundleType,
- nameOrGuid = originName,
- originAssetPath = _context.bundleNameMode == AssetBundleNameMode.Guid ? AssetDatabase.GUIDToAssetPath(originName) : string.Empty,
- };
- backupInfos[index] = backupInfo;
- }
- EditorUtility.ClearProgressBar();
- //保存
- kcBundleManifest.bundleInfos = bundleInfos;
- EditorUtility.SetDirty(kcBundleManifest);
- AssetBundleBackupManifest.Save(backupInfos, false);
- AssetDatabase.SaveAssets();
- BuildLog.Log("Save BundleManifest.");
- AssetDatabase.Refresh();
- return true;
- }
- bool GenReferencesManifest()
- {
- string refManifestPath = PathDefine.ReferenceManifestPath;
- var referenceManifest = AssetDatabase.LoadAssetAtPath<AssetReferenceInfosSo>(refManifestPath);
- if (referenceManifest == null)
- {
- referenceManifest = ScriptableObject.CreateInstance<AssetReferenceInfosSo>();
- AssetDatabase.CreateAsset(referenceManifest, refManifestPath);
- }
- //asset被引用信息
- var assetReferencesMap = new Dictionary<string, HashSet<string>>();
- //addressable信息
- //ResStatic的bundle不允许动态加载,因此不需要记录引用信息
- var addressableMap = _context.GetAddressableInfoMap();
- var sw = new System.Diagnostics.Stopwatch();
- foreach (var item in addressableMap)
- {
- if (_context.allTexturePaths.Contains(item.Key))
- {
- //忽略贴图资源
- continue;
- }
- var assetPath = item.Key;
- var assetAddressable = item.Value;
- sw.Start();
- var dependencies = AssetDatabase.GetDependencies(assetPath, true);
- sw.Stop();
- foreach (var dep in dependencies)
- {
- if (dep != assetPath && addressableMap.TryGetValue(dep, out var depAddressableName))
- { // 同bundle内的asset引用也需要记录
- if (assetReferencesMap.TryGetValue(depAddressableName, out var referenceLst) == false)
- {
- referenceLst = new HashSet<string>();
- assetReferencesMap.Add(depAddressableName, referenceLst);
- }
- referenceLst.Add(assetAddressable);
- }
- }
- }
- BuildLog.Log($"GenReferencesManifest GetDependencies Time:{sw.ElapsedMilliseconds}");
- AssetReferenceInfo[] referenceInfos = new AssetReferenceInfo[assetReferencesMap.Count];
- int index = 0;
- foreach (var item in assetReferencesMap)
- {
- referenceInfos[index++] = new AssetReferenceInfo()
- {
- assetName = item.Key,
- references = item.Value.ToArray()
- };
- }
- referenceManifest.references = referenceInfos;
- EditorUtility.SetDirty(referenceManifest);
- AssetDatabase.SaveAssets();
- BuildLog.Log("Save ReferenceManifest.");
- AssetDatabase.Refresh();
- return true;
- }
- /// <summary>
- /// 检查Assetbundle内是否存在同名资源
- /// </summary>
- /// <param name="assetBundleBuilds"></param>
- /// <returns></returns>
- private bool CheckAssetsNameRepeat()
- {
- bool result = true;
- Dictionary<string, string> assetPathMap = new Dictionary<string, string>();
- var allAssetPaths = new HashSet<string>();
- foreach (var item in _context.bundleDataMap)
- {
- assetPathMap.Clear();
- foreach (var assetPath in item.Value.assetNames)
- {
- var fileName = Path.GetFileName(assetPath);
- if (assetPathMap.ContainsKey(fileName))
- {
- result = false;
- BuildLog.Error($"[XBuild] AssetBundle存在重名资源。Bundle:{item.Value.originBundleName} 重名资源1:{assetPathMap[fileName]} 重名资源2:{assetPath}");
- }
- else
- {
- assetPathMap.Add(fileName, assetPath);
- }
- if (allAssetPaths.Contains(assetPath))
- {
- BuildLog.Error($"[XBuild] AssetBundle存在重复资源。Path:{assetPath}");
- result = false;
- continue;
- }
- allAssetPaths.Add(assetPath);
- }
- }
- return result;
- }
- }
- }
|