Unity|Unity AssetBundle打包工具示例详解
目录
- Unity批量打AB包
- 1.PathTool
- 2.CreateAB
- 3.ClearABLable
- 4.拓展
Unity批量打AB包 为了资源热更新,Unity支持将所有资源打包成AssetBundle资源,存放在SteamingAssets文件夹中;
在项目发布之前,需要将所有资源打包成.ab文件,动态加载;
在项目更新时,替换.ab资源文件,即可完成热更新;
ab文件在加载时,会多一步解压缩的过程,会增加性能消耗;
打包操作属于编辑器拓展,所有脚本放在Eidtor文件夹下;
1.PathTool
根据不同平台,获取ab输出和输入路径;
不同平台的输入输出路径不相同,ios,android,windows;《Unity资源文件夹介绍》
public class PathTools{// 打包AB包根路径public const string AB_RESOURCES = "StreamingAssets"; // 得到 AB 资源的输入目录public static string GetABResourcesPath(){return Application.dataPath + "/" + AB_RESOURCES; }// 获得 AB 包输出路径public static string GetABOutPath(){return GetPlatformPath() + "/" + GetPlatformName(); }//获得平台路径private static string GetPlatformPath(){string strReturenPlatformPath = string.Empty; #if UNITY_STANDALONE_WINstrReturenPlatformPath = Application.streamingAssetsPath; #elif UNITY_IPHONEstrReturenPlatformPath = Application.persistentDataPath; #elif UNITY_ANDROIDstrReturenPlatformPath = Application.persistentDataPath; #endifreturn strReturenPlatformPath; }// 获得平台名称public static string GetPlatformName(){string strReturenPlatformName = string.Empty; #if UNITY_STANDALONE_WINstrReturenPlatformName = "Windows"; #elif UNITY_IPHONEstrReturenPlatformName = "IPhone"; #elif UNITY_ANDROIDstrReturenPlatformName = "Android"; #endifreturn strReturenPlatformName; }// 返回 WWW 下载 AB 包加载路径public static string GetWWWAssetBundlePath(){string strReturnWWWPath = string.Empty; #if UNITY_STANDALONE_WINstrReturnWWWPath = "file://" + GetABOutPath(); #elif UNITY_IPHONEstrReturnWWWPath = GetABOutPath() + "/Raw/"; #elif UNITY_ANDROIDstrReturnWWWPath = "jar:file://" + GetABOutPath(); #endifreturn strReturnWWWPath; }}
2.CreateAB
功能:选中一个文件夹,将该文件夹中所有资源文件打包成AB文件;
主要逻辑:遍历文件夹中所有文件,是文件的生成AssetBundleBuild存在链表中统一打包,是文件夹的递归上一步操作,将所有资源文件都放在listassets链表中;
官方Api:BuildPipeline.BuildAssetBundles统一打包所有资源;
public class CreateAB : MonoBehaviour{private static string abOutPath; private static List listassets = new List(); private static Listlistfileinfo = new List (); private static bool isover = false; //是否检查完成,可以打包static private string selectPath; public static bool GetState(){return isover; }public static AssetBundleBuild[] GetAssetBundleBuilds(){return listassets.ToArray(); }[MenuItem("ABTools/CreatAB &_Q", false)]public static void CreateModelAB(){abOutPath = Application.streamingAssetsPath; if (!Directory.Exists(abOutPath))Directory.CreateDirectory(abOutPath); UnityEngine.Object obj = Selection.activeObject; selectPath = AssetDatabase.GetAssetPath(obj); SearchFileAssetBundleBuild(selectPath); BuildPipeline.BuildAssetBundles(abOutPath,CreateAB.GetAssetBundleBuilds(), BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget); Debug.Log("AssetBundle打包完毕"); }[MenuItem("ABTools/CreatAB &_Q", true)]public static bool CanCreatAB(){if (Selection.objects.Length > 0){return true; }elsereturn false; }
这里为什么会红我也不知道...
//是文件,继续向下public static void SearchFileAssetBundleBuild(string path) {DirectoryInfo directory = new DirectoryInfo(@path); FileSystemInfo[] fileSystemInfos = directory.GetFileSystemInfos(); listfileinfo.Clear(); //遍历所有文件夹中所有文件foreach (var item in fileSystemInfos){int idx = item.ToString().LastIndexOf(@"\"); string name = item.ToString().Substring(idx + 1); //item为文件夹,添加进listfileinfo,递归调用if ((item as DirectoryInfo) != null)listfileinfo.Add(item as DirectoryInfo); //剔除meta文件,其他文件都创建AssetBundleBuild,添加进listassets;if (!name.Contains(".meta")){CheckFileOrDirectoryReturnBundleName(item, path + "/" + name); }}if (listfileinfo.Count == 0)isover = true; else{Debug.LogError(listfileinfo.Count); }}//判断是文件还是文件夹public static string CheckFileOrDirectoryReturnBundleName(FileSystemInfo fileSystemInfo, string path) {FileInfo fileInfo = fileSystemInfo as FileInfo; if (fileInfo != null){string[] strs = path.Split('.'); string[] dictors = strs[0].Split('/'); string name = ""; for (int i = 1; i < dictors.Length; i++){if (i < dictors.Length - 1){name += dictors[i] + "/"; }else{name += dictors[i]; }}string[] strName = selectPath.Split('/'); AssetBundleBuild assetBundleBuild = new AssetBundleBuild(); assetBundleBuild.assetBundleName = strName[strName.Length - 1]; assetBundleBuild.assetBundleVariant = "ab"; assetBundleBuild.assetNames = new string[] {path}; listassets.Add(assetBundleBuild); return name; }else{//递归调用SearchFileAssetBundleBuild(path); return null; }}}
3.ClearABLable
打包时每个资源会添加一个标签,如果重复打包,需要清空才可再次打包,否则会失败;
使用官方API:AssetDatabase.RemoveUnusedAssetBundleNames();
因为注释写的很详细,就不赘述了;
public class ClearABLable{[MenuItem("ABTools/Remove AB Label")]public static void RemoveABLabel(){// 需要移除标记的根目录string strNeedRemoveLabelRoot = string.Empty; // 目录信息(场景目录信息数组,表示所有根目录下场景目录)DirectoryInfo[] directoryDIRArray = null; // 定义需要移除AB标签的资源的文件夹根目录strNeedRemoveLabelRoot = PathTools.GetABResourcesPath(); DirectoryInfo dirTempInfo = new DirectoryInfo(strNeedRemoveLabelRoot); directoryDIRArray = dirTempInfo.GetDirectories(); // 遍历本场景目录下所有的目录或者文件foreach (DirectoryInfo currentDir in directoryDIRArray){// 递归调用方法,找到文件,则使用 AssetImporter 类,标记“包名”与 “后缀名”JudgeDirOrFileByRecursive(currentDir); }// 清空无用的 AB 标记AssetDatabase.RemoveUnusedAssetBundleNames(); // 刷新AssetDatabase.Refresh(); // 提示信息,标记包名完成Debug.Log("AssetBundle 本次操作移除标记完成"); }/// /// 递归判断判断是否是目录或文件/// 是文件,修改 Asset Bundle 标记/// 是目录,则继续递归/// /// 【Unity|Unity AssetBundle打包工具示例详解】当前文件信息(文件信息与目录信息可以相互转换)private static void JudgeDirOrFileByRecursive(FileSystemInfo fileSystemInfo){// 参数检查if (fileSystemInfo.Exists == false){Debug.LogError("文件或者目录名称:" + fileSystemInfo + " 不存在,请检查"); return; }// 得到当前目录下一级的文件信息集合DirectoryInfo directoryInfoObj = fileSystemInfo as DirectoryInfo; // 文件信息转为目录信息FileSystemInfo[] fileSystemInfoArray = directoryInfoObj.GetFileSystemInfos(); foreach (FileSystemInfo fileInfo in fileSystemInfoArray){FileInfo fileInfoObj = fileInfo as FileInfo; // 文件类型if (fileInfoObj != null){// 修改此文件的 AssetBundle 标签RemoveFileABLabel(fileInfoObj); }// 目录类型else{// 如果是目录,则递归调用JudgeDirOrFileByRecursive(fileInfo); }}}/// /// 给文件移除 Asset Bundle 标记/// /// 文件(文件信息)static void RemoveFileABLabel(FileInfo fileInfoObj){// AssetBundle 包名称string strABName = string.Empty; // 文件路径(相对路径)string strAssetFilePath = string.Empty; // 参数检查(*.meta 文件不做处理)if (fileInfoObj.Extension == ".meta"){return; }// 得到 AB 包名称strABName = string.Empty; // 获取资源文件的相对路径int tmpIndex = fileInfoObj.FullName.IndexOf("Assets"); // 得到文件相对路径strAssetFilePath = fileInfoObj.FullName.Substring(tmpIndex); // 给资源文件移除 AB 名称AssetImporter tmpImportObj = AssetImporter.GetAtPath(strAssetFilePath); tmpImportObj.assetBundleName = strABName; }}
4.拓展
更多的时候,我们打包需要一键打包,也可能需要多个文件打成一个ab包,只需要修改一下文件逻辑即可;
打ab包本身并不复杂,对文件路径字符串的处理比较多,多Debug调试;
到此这篇关于Unity AssetBundle打包工具的文章就介绍到这了,更多相关Unity AssetBundle打包内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- Beego打包部署到Linux
- Unity和Android通信系列文章2——扩展UnityPlayerActivity
- unity探究UGUI的Image中sprite和overrideSprite的区别
- jar|springboot项目打成jar包和war包,并部署(快速打包部署)
- unity|unity 在iOS平台跳转appstore
- Android|Android gradle打包涉及task源码解析(五)
- OpenCV|OpenCV for Unity 通过WebCamTextureToMatHelper帮助类来获取摄像头的画面
- pyinstaller解决闪退问题
- iOS|iOS 高效开发必备技巧之自动化打包(shell xcode11 上传App Store 蒲公英等平台)
- 美味蛋糕|美味蛋糕 低价出水彩视频课程打包出