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_WIN
strReturenPlatformPath = Application.streamingAssetsPath;
#elif UNITY_IPHONE
strReturenPlatformPath = Application.persistentDataPath;
#elif UNITY_ANDROID
strReturenPlatformPath = Application.persistentDataPath;
#endif return strReturenPlatformPath;
} // 获得平台名称
public static string GetPlatformName()
{
string strReturenPlatformName = string.Empty; #if UNITY_STANDALONE_WIN
strReturenPlatformName = "Windows";
#elif UNITY_IPHONE
strReturenPlatformName = "IPhone";
#elif UNITY_ANDROID
strReturenPlatformName = "Android";
#endif return strReturenPlatformName;
} // 返回 WWW 下载 AB 包加载路径
public static string GetWWWAssetBundlePath()
{
string strReturnWWWPath = string.Empty; #if UNITY_STANDALONE_WIN
strReturnWWWPath = "file://" + GetABOutPath();
#elif UNITY_IPHONE
strReturnWWWPath = GetABOutPath() + "/Raw/";
#elif UNITY_ANDROID
strReturnWWWPath = "jar:file://" + GetABOutPath();
#endif return strReturnWWWPath;
}
}

2.CreateAB

功能:选中一个文件夹,将该文件夹中所有资源文件打包成AB文件;

主要逻辑:遍历文件夹中所有文件,是文件的生成AssetBundleBuild存在链表中统一打包,是文件夹的递归上一步操作,将所有资源文件都放在listassets链表中;

官方Api:BuildPipeline.BuildAssetBundles统一打包所有资源;

public class CreateAB : MonoBehaviour
{
private static string abOutPath;
private static List<AssetBundleBuild> listassets = new List<AssetBundleBuild>();
private static List<DirectoryInfo> listfileinfo = new List<DirectoryInfo>();
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;
}
else
return 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 本次操作移除标记完成");
} /// <summary>
/// 递归判断判断是否是目录或文件
/// 是文件,修改 Asset Bundle 标记
/// 是目录,则继续递归
/// </summary>
/// <param name="fileSystemInfo">当前文件信息(文件信息与目录信息可以相互转换)</param>
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);
}
}
} /// <summary>
/// 给文件移除 Asset Bundle 标记
/// </summary>
/// <param name="fileInfoObj">文件(文件信息)</param>
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打包工具的更多相关文章

  1. 一个灵活的AssetBundle打包工具

      尼尔:机械纪元 上周介绍了Unity项目中的资源配置,今天和大家分享一个AssetBundle打包工具.相信从事Unity开发或多或少都了解过AssetBundle,但简单的接口以及众多的细碎问题 ...

  2. Unity自动打包工具

    转载 https://blog.csdn.net/ynnmnm/article/details/36774715 最开始有写打包工具的想法,是因为看到<啪啪三国>王伟峰分享的一张图,他们有 ...

  3. Unity 游戏框架搭建 (十一) 简易AssetBundle打包工具(一)

    最近在看Unity官方的AssetBundle(以下简称AB)的教程,也照着做了一遍,不过做出来的AssetBundleManager的API设计得有些不太习惯.目前想到了一个可行的解决方案.AB相关 ...

  4. Unity AssetBundle打包资源工具

    using UnityEngine;using System.Collections;using UnityEditor; /// <summary>/// 简单资源打包Editor/// ...

  5. Unity 游戏框架搭建 (十二) 简易AssetBundle打包工具(二)

    上篇文章中实现了基本的打包功能,在这篇我们来解决不同平台打AB包的问题. 本篇文章的核心api还是: BuildPipeline.BuildAssetBundles (outPath, 0, Edit ...

  6. Unity资源打包之Assetbundle

    转  Unity资源打包之Assetbundle 本文原创版权归 csdn janeky 所有,转载请详细注明原创作者及出处,以示尊重! 作者:janeky 原文:http://blog.csdn.n ...

  7. Unity自己主动打包工具

    最開始有写打包工具的想法,是由于看到<啪啪三国>王伟峰分享的一张图,他们有一个专门的"工具程序猿"开发各种工具. (ps:说起来这个王伟峰和他的创始团队成员,曾经跟我是 ...

  8. Unity资源打包学习笔记(一)、详解AssetBundle的流程

    转载请标明出处:http://www.cnblogs.com/zblade/ 本文参照unity官网上对于assetBundle的一系列讲解,主要针对assetbundle的知识点做一个梳理笔记,也为 ...

  9. [Unity] unity5.3 assetbundle打包及加载

    Unity5.3更新了assetbundle的打包和加载api,下面简单介绍使用方法及示例代码. 在Unity中选中一个prefab查看Inspector窗口,有两个位置可以进行assetbundle ...

  10. [Unity3D] 5.0 图集合并扩展工具,用于解决UGUI与AssetBundle打包造成资源包过大的问题

    [Unity3D] 5.0 图集合并扩展工具,用于解决UGUI与AssetBundle打包造成资源包过大的问题 2017年07月05日 15:57:44 阅读数:1494 http://www.cpp ...

随机推荐

  1. 深入理解BFC

    定义 在解释BFC之前,先说一下文档流.我们常说的文档流其实分为定位流.浮动流和普通流三种.而普通流其实就是指BFC中的FC.FC是formatting context的首字母缩写,直译过来是格式化上 ...

  2. gitlab基本维护和使用

    基本介绍 GitLab是一个自托管的Git项目仓库,可以自己搭建个人代码管理的仓库,功能与github类似. 安装 下载 gitlab下载地址: https://about.gitlab.com/do ...

  3. er

    电子锁管理 设备管理 设备管理 信息编辑;回收 电子锁发放 电子锁初始化,发放 记录车辆在发车时使用的电子锁 电子锁开锁联系人管理 电子锁开锁联系人管理 根据订单路线中的投点,设置每个投递点的开锁联系 ...

  4. Log4j的ConversionPattern无缝适配到Logback

    为了能将log4j的ConversionPattern无缝应用到logback上来,需要对两个Conversion做适配,具体可以参考:Log4j 与 Logback的ConversionPatter ...

  5. JSP表单处理

    当需要通过从浏览器获取一些信息,在许多情况下,最终给到Web服务器后台程序.浏览器使用两种方法将这些信息传递给Web服务器.这些方法是GET方法和POST方法. GET 方法: GET方法将追加到页面 ...

  6. Unity AssetBundles and Resources指引 (二) Resources文件夹

    本文内容主要翻译自下面这篇文章 https://unity3d.com/cn/learn/tutorials/topics/best-practices/guide-assetbundles-and- ...

  7. Mac系统Finder访问资源库文件夹

    Mac在Lion版本之后,默认隐藏了“资源库”文件夹,如果有时我们又需要访问它,该怎么办呢? 方法一 打开“Finder”,打开“前往”菜单时按住“Option”键. 方法二 我们也可设置Finder ...

  8. HTTP的一些基础知识

    HTTP是计算机通过网络进行通信的规则.http是一种无状态协议:不建立持久的连接,服务端不保留连接信息. 一个完整的HTTP请示,通常用7个步骤:1.建立TCP连接2.Web浏览器向Web服务器发送 ...

  9. C++中的句柄类

    初次在<C++ Primer>看到句柄,不是特别理解.在搜索相关资料后,终于有了点头绪. 首先明白句柄要解决什么问题.参考文章<C++ 沉思录>阅读笔记——代理类 场景: 我们 ...

  10. nginx 编译参数

    jrhnpt01:/root# nginx -V nginx version: nginx/1.7.7 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (G ...