123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- using XGame.Framework.Asset;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using XGame.Framework.Json;
- namespace XGame.Editor.Build.AssetBundles
- {
- internal class AssetBundleGroupsTask
- {
- public class AssetbundleGroupsManifest
- {
- //public UnityEditor.AssetBundleBuild[] bundleBuilds;
- public AssetbundleGroup[] bundleGroups;
- }
- public class AssetbundleGroup
- {
- public int groupId;
- public AssetbundleData[] bundles;
- }
- public class AssetbundleData
- {
- public uint bundleId;
- public int buildIndex;
- public uint[] dependencies;
- }
- public enum AbGroupMode
- {
- Normal = 0,
- Dependencies,
- }
- private string _outputPath;
- private AbGroupMode _groupMode;
- //public AssetBundleGroupsTask()
- //{
- // _outputPath = string.Empty;
- // _groupMode = AbGroupMode.Dependencies;
- //}
- public AssetBundleGroupsTask(string outputPath, AbGroupMode groupMode)
- {
- _outputPath = outputPath;
- _groupMode = groupMode;
- if (string.IsNullOrEmpty(outputPath))
- return;
- var dirPath = Path.GetDirectoryName(outputPath);
- if (!Directory.Exists(dirPath))
- {
- Directory.CreateDirectory(dirPath);
- BuildLog.Log($"AssetBundleGroupsTask CreateDirectory: {dirPath}");
- }
- }
- public bool Excute()
- {
- XBuildPipeline.GenerateBundleManifests();
- var manifest = AssetBundleUtils.LoadManifest();
- if (manifest == null || manifest.bundleInfos == null)
- return false;
- if (!BundleGroup(manifest.bundleInfos, out var bundleGroupMap))
- {
- return false;
- }
- return Export(manifest.bundleInfos, bundleGroupMap);
- }
- internal bool BundleGroup(AssetBundleInfo[] bundleInfos, out Dictionary<uint, int> bundleGroupMap)
- {
- if (_groupMode == AbGroupMode.Dependencies)
- {
- return BundleGroupByDependencies(bundleInfos, out bundleGroupMap);
- }
- return BundleGroupNormal(bundleInfos, out bundleGroupMap);
- }
- private bool BundleGroupNormal(AssetBundleInfo[] bundleInfos, out Dictionary<uint, int> bundleGroupMap)
- {
- bundleGroupMap = new Dictionary<uint, int>();
- var groupIndex = 0;
- var bundleIds = new HashSet<uint>();
- var groups = new HashSet<int>();
- foreach (var bundleInfo in bundleInfos)
- {
- //先找出该bundle和依赖的所有groupId
- var min = -1;
- if (bundleGroupMap.TryGetValue(bundleInfo.bundleId, out var groupId))
- {
- min = groupId;
- groups.Add(groupId);
- }
- if (bundleInfo.dependencies != null)
- {
- foreach (var dependence in bundleInfo.dependencies)
- {
- if (bundleGroupMap.TryGetValue(dependence, out groupId))
- {
- groups.Add(groupId);
- if (min == -1 || groupId < min)
- min = groupId;
- }
- }
- }
- if (groups.Count > 0)
- {
- groups.Remove(min);
- if (groups.Count > 0)
- {
- //关联的bundle也必须同步修改groupId
- foreach (var key in bundleIds)
- {
- var val = bundleGroupMap[key];
- if (groups.Contains(val))
- {
- bundleGroupMap[key] = min;
- }
- }
- }
- //取groupId最小值
- groupId = min;
- }
- else
- {
- //新增一个Group
- groupId = groupIndex++;
- }
- //设置GroupId
- if (!bundleGroupMap.ContainsKey(bundleInfo.bundleId))
- {
- bundleGroupMap[bundleInfo.bundleId] = groupId;
- bundleIds.Add(bundleInfo.bundleId);
- }
- if (bundleInfo.dependencies != null)
- {
- foreach (var dependence in bundleInfo.dependencies)
- {
- if (!bundleGroupMap.ContainsKey(dependence))
- {
- bundleGroupMap[dependence] = groupId;
- bundleIds.Add(dependence);
- }
- }
- }
- //清除缓存
- groups.Clear();
- }
- return true;
- }
- private bool BundleGroupByDependencies(AssetBundleInfo[] bundleInfos, out Dictionary<uint, int> bundleGroupMap)
- {
- bundleGroupMap = new Dictionary<uint, int>();
- var bundlesMap = new Dictionary<uint, AssetBundleInfo>();
- var bundleIds = new List<uint>();
- foreach (var bundleInfo in bundleInfos)
- {
- bundlesMap.Add(bundleInfo.bundleId, bundleInfo);
- if (bundleInfo.DependenciesCount == 0)
- {
- bundleGroupMap.Add(bundleInfo.bundleId, 0);
- }
- else
- {
- bundleIds.Add(bundleInfo.bundleId);
- }
- }
- var groupId = 1;
- var tempIds = new List<uint>();
- while (bundleIds.Count > 0)
- {
- foreach (var bundleId in bundleIds)
- {
- var bundleInfo = bundlesMap[bundleId];
- var isTrue = true;
- foreach (var dep in bundleInfo.dependencies)
- {
- if (!bundleGroupMap.ContainsKey(dep))
- {
- isTrue = false;
- break;
- }
- }
- if (isTrue)
- {
- tempIds.Add(bundleId);
- }
- }
- if (tempIds.Count > 0)
- {
- foreach (var bundleId in tempIds)
- {
- bundleIds.Remove(bundleId);
- bundleGroupMap.Add(bundleId, groupId);
- }
- groupId += 1;
- tempIds.Clear();
- }
- else
- {
- Log.Error($"Assetbundle分组失败。已分数量:{bundleGroupMap.Count} 剩余:{bundleIds.Count} Group:{groupId}");
- return false;
- }
- }
- return true;
- }
- private bool Export(AssetBundleInfo[] bundleInfos, Dictionary<uint, int> bundleGroupMap)
- {
- var outputPath = _outputPath;
- var abCount = bundleInfos.Length;
- var manifest = new AssetbundleGroupsManifest()
- {
- //bundleBuilds = new UnityEditor.AssetBundleBuild[abCount],
- };
- var bundleDataMap = new Dictionary<uint, AssetbundleData>();
- var abIndex = 0;
- foreach (var bundleInfo in bundleInfos)
- {
- var bundleId = bundleInfo.bundleId;
- bundleDataMap[bundleId] = new AssetbundleData()
- {
- bundleId = bundleId,
- buildIndex = abIndex,
- dependencies = bundleInfo.dependencies,
- };
- //manifest.bundleBuilds[abIndex] = bundleBuildMap[bundleId].ToUniBuild();
- abIndex++;
- }
- var bundleGroups = bundleGroupMap.GroupBy(item => item.Value);
- var groupCount = bundleGroups.Count();
- var abGroups = new List<AssetbundleGroup>();
- foreach (var bundleGroup in bundleGroups)
- {
- var count = bundleGroup.Count();
- var abGroup = new AssetbundleGroup()
- {
- groupId = bundleGroup.Key,
- bundles = new AssetbundleData[count],
- };
- var bundleIdx = 0;
- foreach (var item in bundleGroup)
- {
- abGroup.bundles[bundleIdx++] = bundleDataMap[item.Key];
- }
- abGroups.Add(abGroup);
- }
- abGroups.Sort((a, b) => a.groupId - b.groupId);
- manifest.bundleGroups = abGroups.ToArray();
- var text = XJson.ToJson(manifest);
- File.WriteAllText(outputPath, text, System.Text.Encoding.UTF8);
- BuildLog.Log($"GenAssetbundleGroups finish. GroupCount:{groupCount} Path:{outputPath}");
- return true;
- }
- }
- }
|