赞
踩
前言
本篇文章是整个打包的核心,我们需要告诉打包API打包目标是什么,在整理目标的时候,可以定制化各种各样的收集策略,以及剔除策略、引用策略等。
正文开始
首先要明确,我们的最终目标是收集打包资源。但请注意,该步骤收集的不是最终调用打包接口的参数2。而是包含了我们自己自己需要的一些信息,当然,其中包含了参数2需要的信息。
AssetBundleManifest.BuildAssetBundles(string outputPath, AssetBundleBuild[] builds, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);
下面是收集资源的代码,非常重要!!!仔细看,多看,该方法的返回值是List<AssetInfo>
- private List<AssetInfo> GetBuildMap()
- {
- int progressBarCount = 0;
- Dictionary<string, AssetInfo> allAsset = new Dictionary<string, AssetInfo>();
-
- // 获取所有的收集路径,该方法在上一篇文章里有代码
- List<string> collectPathList = CollectionSettingData.GetAllCollectPath();
- if (collectPathList.Count == 0)
- throw new Exception("[BuildPatch] 配置的打包路径列表为空");
-
- // 获取所有资源
- string[] guids = AssetDatabase.FindAssets(string.Empty, collectPathList.ToArray());
- foreach (string guid in guids)
- {
- string mainAssetPath = AssetDatabase.GUIDToAssetPath(guid);
- if (CollectionSettingData.IsIgnoreAsset(mainAssetPath))
- continue;
- if (ValidateAsset(mainAssetPath) == false)
- continue;
-
- List<AssetInfo> depends = GetDependencies(mainAssetPath);
- for (int i = 0; i < depends.Count; i++)
- {
- AssetInfo assetInfo = depends[i];
- if (assetInfo.AssetPath.Contains("Activity.RU"))
- {
- throw new Exception($"[BuildPatch] Contain: {assetInfo.AssetPath} by {mainAssetPath}");
- }
-
- if (allAsset.ContainsKey(assetInfo.AssetPath))
- {
- AssetInfo cacheInfo = allAsset[assetInfo.AssetPath];
- cacheInfo.DependCount++;
- }
- else
- {
- allAsset.Add(assetInfo.AssetPath, assetInfo);
- }
- }
-
- // 进度条
- progressBarCount++;
- EditorUtility.DisplayProgressBar("进度", $"依赖文件分析:{progressBarCount}/{guids.Length}", (float)progressBarCount / guids.Length);
- }
- EditorUtility.ClearProgressBar();
- progressBarCount = 0;
-
- // 移除零依赖的资源
- List<string> removeList = new List<string>();
- foreach (KeyValuePair<string, AssetInfo> pair in allAsset)
- {
- if (pair.Value.IsCollectAsset)
- continue;
- if (pair.Value.DependCount == 0)
- removeList.Add(pair.Value.AssetPath);
- else if (pair.Value.AssetPath.ToLower().Contains("assets/worksart/panel/atlas/"))
- removeList.Add(pair.Value.AssetPath);
- }
- for (int i = 0; i < removeList.Count; i++)
- {
- allAsset.Remove(removeList[i]);
- }
-
- // 设置AssetBundleLabel资源标签
- foreach (KeyValuePair<string, AssetInfo> pair in allAsset)
- {
- SetAssetBundleLabelAndVariant(pair.Value);
- SetAssetEncrypt(pair.Value);
- // 进度条
- progressBarCount++;
- EditorUtility.DisplayProgressBar("进度", $"设置资源标签:{progressBarCount}/{allAsset.Count}", (float)progressBarCount / allAsset.Count);
- }
- EditorUtility.ClearProgressBar();
- progressBarCount = 0;
-
- // Dictionary<string, long> dicSortedBySize = allAsset.OrderBy(o => o.Value.sizeKB).ToDictionary(p => p.Key, o => o.Value.sizeKB);
- // foreach (KeyValuePair<string, long> pair in dicSortedBySize)
- // {
- // Log($"AB asset: {pair.Key}, sizeKB: {pair.Value}");
- // }
-
- // 返回结果
- return allAsset.Values.ToList();
- }
下面是获取所有依赖的方法
- private List<AssetInfo> GetDependencies(string assetPath)
- {
- List<AssetInfo> depends = new List<AssetInfo>();
- string[] dependArray = AssetDatabase.GetDependencies(assetPath, true);
- foreach (string dependPath in dependArray)
- {
- if (ValidateAsset(dependPath))
- {
- AssetInfo assetInfo = new AssetInfo(dependPath);
- depends.Add(assetInfo);
- }
- }
- return depends;
- }
下面是设置AssetBundleLabel的方法,请注意,CollectionSettingData.GetAssetBundleLabel在上一篇文章中有代码
variant变量就是ab包的后缀,一般.unity3d
还有一点非常重要,ab包的名字除了可以使用字符串,还可以使用MD5码
- private void SetAssetBundleLabelAndVariant(AssetInfo assetInfo)
- {
- string label = CollectionSettingData.GetAssetBundleLabel(assetInfo.AssetPath);
- string variant = VariantCollector.GetVariantByAssetPath(label);
- if (string.IsNullOrEmpty(variant))
- {
- variant = PatchDefine.AssetBundleDefaultVariant;
- }
- else
- {
- label = label.Replace(variant, "");
- variant = variant.Substring(1);
- }
- if (IsNameByHash)
- assetInfo.AssetBundleLabel = HashUtility.BytesMD5(Encoding.UTF8.GetBytes(label));
- else
- assetInfo.AssetBundleLabel = label;
-
- assetInfo.ReadableLabel = label;
- assetInfo.AssetBundleVariant = variant;
- assetInfo.bundlePos = CollectionSettingData.GetAssetBundlePos(assetInfo.AssetPath);
- // assetInfo.sizeKB = EditorTools.GetFileSize(assetInfo.AssetPath);
- }
下面是AssetInfo的代码
- public class AssetInfo
- {
- public string AssetPath { private set; get; }
- public bool IsCollectAsset { private set; get; }
- public bool IsSceneAsset { private set; get; }
- public bool IsVideoAsset { private set; get; }
-
- /// <summary>
- /// 被依赖次数
- /// </summary>
- public int DependCount = 0;
-
- /// <summary>
- /// AssetBundle标签
- /// </summary>
- public string AssetBundleLabel = null;
-
- /// <summary>
- /// AssetBundle变体
- /// </summary>
- public string AssetBundleVariant = null;
-
- /// <summary>
- /// AssetBundle存放位置
- /// </summary>
- public EBundlePos bundlePos = EBundlePos.buildin;
-
- public string ReadableLabel = "undefined";
-
- public EEncryptMethod EncryptMethod;
-
- public AssetInfo(string assetPath)
- {
- AssetPath = assetPath;
- IsCollectAsset = CollectionSettingData.IsCollectAsset(assetPath);
- IsSceneAsset = AssetDatabase.GetMainAssetTypeAtPath(assetPath) == typeof(SceneAsset);
- IsVideoAsset = AssetDatabase.GetMainAssetTypeAtPath(assetPath) == typeof(UnityEngine.Video.VideoClip);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。