Unity AssetBundle 设置名称优化
2017-08-31 19:09
375 查看
原因
在大部分的 Unity 分析打包 AssetBundle 过程中,是采用对资源设置 AssetBundle 名称标签的方式来进行打包,类似如下:public static void SetBundleName(string assetPath, string bundleName) { var importer = AssetImporter.GetAtPath(assetPath); if (importer && importer.assetBundleName != bundleName) { importer.assetBundleName = bundleName; } } private static void BuildAssetBundlesInter(string outputPath, AssetBundleBuildOptions options) { AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(outputPath, BuildAssetBundleOptions.UncompressedAssetBundle, GetBuildTarget()); }
每设置一个资源的 AssetBundle 名称,都会导致 Unity 写入其 .meta 文件,这样在分析的过程耗费不少时间。而且在打包完毕,又得重新设置所有资源的 AssetBundle 名称为空,否则仓库会提示有文件变化。
思路
修改流程,改成传入 AssetBundleBuild[] 的方式进行打包,这样就无需设置资源的 AssetBundle 名称。但是不能简单的把结果保存为 AssetBundleBuild[] 数组对象,因为打包工具支持当次不再分析资源,直接使用上一次的分析结果。所以要把 AssetBundleBuild[] 结果存为临时文件,方便下次使用,正常来说,这个临时文件一般只对当天的资源有效即可,当更新了资源,肯定得重新分析资源,不能再使用上次的结果。所以,只需要把这临时文件放在 Temp 目录下即可。解决
创建一个独立类,来管理分析的 AssetBundle 构建信息:using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Serialization.Formatters.Binary; using UnityEditor; /// <summary> /// AssetBundle 分析映射 /// </summary> public static class AssetBundleBuildMap { private static AssetBundleMap assetBundleMap; public static void Clear() { if (assetBundleMap != null) { assetBundleMap = null; } } /// <summary> /// 普通资源设置 AssetBundle 名称接口 /// </summary> /// <param name="assetPath"></param> /// <param name="assetBundleName"></param> public static void SetAssetPathAssetBundleName(string assetPath, string assetBundleName) { if (assetBundleMap == null) { assetBundleMap = new AssetBundleMap(); } assetBundleMap.AddMap(assetPath, assetBundleName); } public static bool IsAssetPathHasAssetBundleName(string assetPath) { if (assetBundleMap == null) { return false; } return assetBundleMap.assetPathSet.Contains(assetPath); } public static List<string> GetAllAssetBundleNames() { if (assetBundleMap == null) { return null; } List<string> allAssetBundleNames = assetBundleMap.assetBundleDict.Keys.ToList(); allAssetBundleNames.Sort(EditorUtility.NaturalCompare); return allAssetBundleNames; } public static List<string> GetAssetPathsFromAssetBundle(string assetBundleName) { if (assetBundleMap == null) { return null; } List<string> assetPaths; if (assetBundleMap.assetBundleDict.TryGetValue(assetBundleName, out assetPaths)) { assetPaths.Sort(EditorUtility.NaturalCompare); return assetPaths; } return null; } /// <summary> /// 最终需要进行打包的资产构建列表 /// </summary> /// <returns></returns> public static AssetBundleBuild[] GetAssetBundleBuilds() { List<AssetBundleBuild> assetBundleBuilds = new List<AssetBundleBuild>(); string tempPath = "Temp/AssetBundleBuildAnalyze"; if (assetBundleMap == null) { assetBundleMap = AssetBundleMap.MakeByLoad(tempPath); } else { assetBundleMap.Save(tempPath); } assetBundleBuilds.AddRange(assetBundleMap.GetBuilds()); return assetBundleBuilds.ToArray(); } private class AssetBundleMap { public readonly HashSet<string> assetPathSet = new HashSet<string>(); public Dictionary<string, List<string>> assetBundleDict = new Dictionary<string, List<string>>(); public void AddMap(string assetPath, string assetBundleName) { if (string.IsNullOrEmpty(assetPath) || string.IsNullOrEmpty(assetBundleName)) { return; } if (assetPathSet.Contains(assetPath)) { return; } assetPathSet.Add(assetPath); List<string> assetPaths; if (assetBundleDict.TryGetValue(assetBundleName, out assetPaths)) { assetPaths.Add(assetPath); } else { assetPaths = new List<string> { assetPath }; assetBundleDict.Add(assetBundleName, assetPaths); } } public List<AssetBundleBuild> GetBuilds() { List<AssetBundleBuild> assetBundleBuilds = new List<AssetBundleBuild>(); foreach (var kv in assetBundleDict) { assetBundleBuilds.Add(new AssetBundleBuild() { assetBundleName = kv.Key, assetNames = kv.Value.ToArray() }); } return assetBundleBuilds; } public void Save(string tempPath) { using (MemoryStream stream = new MemoryStream()) { new BinaryFormatter().Serialize(stream, assetBundleDict); File.WriteAllBytes(tempPath, stream.ToArray()); } } public static AssetBundleMap MakeByLoad(string tempPath) { AssetBundleMap map = new AssetBundleMap(); if (File.Exists(tempPath)) { byte[] bytes = File.ReadAllBytes(tempPath); using (MemoryStream stream = new MemoryStream(bytes)) { map.assetBundleDict = new BinaryFormatter().Deserialize(stream) as Dictionary<string, List<string>>; } } return map; } } }
最终调用的方式如下:
private static void BuildAssetBundlesInter(string outputPath, AssetBundleBuildOptions options) { AssetBundleBuild[] assetBundleBuilds = AssetBundleBuildMap.GetAssetBundleBuilds(); AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(outputPath, assetBundleBuilds, BuildAssetBundleOptions.UncompressedAssetBundle, GetBuildTarget()); AssetBundleBuildMap.Clear(); }
相关文章推荐
- unity自动设置Assetbundle包名
- Unity5.X批清理AssetBundle的名称
- Unity热更新系列之AssetBundle(1) ——详述如何设置AssetBundle Name
- 5.x中批量设置选定文件夹对应的AssetBundle名称
- unity 代码设置要打包的AssetBundle
- 浅尝Unity 3D的Asset Bundle知识(五)-----缓存利用篇
- Unity5.4打包AssetBundle
- <Unity> AssetBundle
- [Unity]AssetBundle资源更新以及多线程下载
- Unity之AssetBundle自动打包工具
- Unity 5:使用 Asset Bundle 和 Asset Bundle Manager (2)
- 【unity】Assetbundle的原理
- unity5.4.3p2里面的AssetBundle打包流程
- Unity 资源打包Assetbundle
- 【Unity3D技术文档翻译】第1.9篇 使用 Unity AssetBundle Browser tool (AssetBundle系列完结)
- Unity AssetBundle爬坑手记
- 能解开assetbundle格式资源的UnityStudio工具
- Unity资源热更之AssetBundle(1)———基本介绍
- Unity4.x AssetBundle内存管理 依赖打包逻辑 全套
- Unity5.4 Assetbundles官方说明七(在AssetBundle中存储和加载二进制数据)