Unity的AB包详解

关注公—众—号“游戏内圈”,更多免费资料和教程等着你

1.什么是资源?

在Unity的Assets目录下的文件,在游戏运行过程中需要从此目录加载并显示到屏幕上的都可以称之为Unity资源,例如模型、材质、纹理、预制体、脚本、声音、数据文档、动画切片、控制器、着色器、场景等。

2.如何管理资源?

在Unity中如果希望能非常良好地管理这些游戏资源,就必须考虑以下几点因素:

统一资源格式

制作一个Unity的资源格式标准,所有资源都采用这个相同的格式进行处理。传统格式如XML、JSON可以实现此功能,但是其安全性低、无任何加密并且打包加载速度非常慢因此并不是理想选择。

统一资源处理流程

制作(打包)资源:将游戏中的任何一类资源打包成统一的资源包格式。

使用(加载)资源:解析这个资源包并将其所包含的具体资源加载到内存中使用。

释放(卸载)资源:将不再使用的资源释放掉以节约内存空间。

Unity官方决定采用一套自主研发的完整资源解决方案称为AssetBundle,又简称AB包。

什么是AssetBundle?

AssetBundle是将资源用Unity的一种用于存储资源的压缩格式打包后的集合。它可以存储任意一种Unity引擎可以识别的资源。

Unity中的AssetBundle系统是对资源管理的一种扩展,可以动态地加载和卸载,并且大大节约了游戏包体所占空间并提高了加载效率。


创建AssetBundle

目前Unity提供了4.x与5.x两种AssetBundle资源包的创建方式。其中4.x是老版方式,相对比较麻烦,只能在打包脚本中通过纯代码的方式手工指定AB包与资源列表依赖关系。而5.x的方式做了很大改进,提供了AssetBundle创建工具,开发者可以通过该工具非常简单方便的进行编辑器操作指定AB包与资源依赖关系,可以大大提高开发效率。

然而无论使用哪种方式,开发者都需要在Unity编辑器中编写脚本来创建AB包,由于打包操作是在游戏非运行时,因此这个脚本一定能够在不运行游戏的前提下执行,Unity提供了编辑器扩展的功能来帮助开发者实现这个目的。

1.什么是编辑器扩展?

Unity编辑器扩展其实主要是指开发者通过编写C#脚本从而在Unity编辑器中添加一个新的工具菜单项来对现在的编辑器功能进行扩展或更为简单的实现管理资源的功能。这个C#脚本称之为编辑器扩展脚本。在使用编辑器扩展时需要注意以下3点:

必须在编辑器脚本中使用@MenuItem特性声明编辑器菜单项函数以用来实现相应的菜单功能。

编辑器脚本必须放在名为Editor的文件夹下。

在编辑器的菜单回调函数中实现菜单点击功能(不能是游戏运行时的功能)。


2.Unity5.x打包

(1)给每一个资源通过AB打包工具指定AB包名称(编辑器中)

(2)在打包脚本中调用public static AssetBundleManifest BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform)将标记的资源全部打入对应的AB包。

outputPath:AB包的输出路径,必须预先创建否则会打包时报错。

assetBundleOptions:为AB包构建选项,默认情况下只要选择None就可以了。

targetPlatform:为AB包的目标平台,游戏发布不同的平台此选项不同。

特别注意:

一个AB包对应两个文件,其中一个只包含资源内容本身,无后缀是一个二进制压缩文件,另外一个后缀为.manifest是对这个AB包的描述文件,其中描述了AB包中的资源列表以及依赖关系。

而在打包目录会额外生成一个与输出路径名称一样的全局AB包,它的描述文件中表示了此目录下的AB包列表以及依赖关系。

加载AssetBundle

1.加载AB包大致可以分为两个步骤:

读取AB包资源数据到程序内存。

使用AssetBundle.LoadFromFile(path),其中path是AB的路径,返回AssetBundle对象。

加载AB包中存储的具体资源对象并使用。

2.加载AB包中具体资源对象

(1)AssetBundle.LoadAsset方法,参数传递具体资源名称,不带后缀。使用泛型的方法可以自动加载并返回相应资源类型,使用不带泛型方法会返回Object,需要手动转换。

(2)AssetBundle.LoadAllAssets方法,无参一口气加载所有包中的资源到内存。使用泛型的方法那么返回的是一个特性类型的数组(前提是包中的资源都是相同数据类型),使用不带泛型的方法会返回Object数组(可以是不同类型对象)。

卸载AssetBundle

正确的做法是对于程序中确定不再使用的AssetBundle资源包,我们要及时卸载调优化内存空间来保证可以顺利加载新的资源。

Unity中只有一个负责卸载AssetBundle的方法,需要传入一个布尔类型参数,取true和false两个值含义完全不同,具体如下:

1.AssetBundle.Unload(false)

释放AssetBundle文件的内存镜像,不包含已经被加载到内存中的资源对象。

2.AssetBundle.Unload(true)

释放AssetBundle文件的内存镜像,并销毁所有资源对象,无论是否加载。



特殊资源处理

绝大多数AssetBundle资源使用上述流程和方法都可以正确处理,但是实际开发中仍然存在两类资源需要进行特殊处理。

1.脚本资源

脚本资源是一种特殊资源,脚本本身代码内容不会被打入AB包,而是只会在AB包中维护一个脚本的引用,其直接指向Assets目录下的某一个具体名称脚本,加载AB包的时候就要求在Assets目录下必须存在所有此包中资源依赖的同名脚本,否则造成所有资源的脚本丢失(物体行为逻辑丢失)。

2.场景资源

同脚本一样,场景资源也是一类极为特殊的游戏资源。在Unity中场景资源不能和其他普通资源混合打入同一个AssetBundle,必须单独打入AB包。而是当我们加载并使用AB包中的场景时(一般情况下是切换场景操作),不再需要预先将场景添加到Scens In Build场景构建列表,直接使用就可以了。

Unity4.x打包流程

不同于Unity5.x,Unity4.x没有方便的AssetBundle打包工具,只能通过在脚本中纯代码方式指定资源列表和依赖关系。

资源依赖打包与依赖加载

总结就是:如果是需要多个资源依赖的资源,建议放入公共包

1.资源的依赖打包

AssetBundle中不同的bundle的许多资源可能会同一时间依赖于相同的某个资源,例如不同模型可能会引用相同的材质,这称为AssetBundle资源之间的依赖。如果不考虑依赖关系,将两个资源分别打包到两个不同AB包中,那么它们共享的材质资源就会被打包两次,这就造成了资源的浪费。

为了避免这种浪费,需要使用AssetBundle的包依赖关系来处理。正确做法是将共享的材质资源单独打包到一个独立的AssetBundle中,让两个模型所隶属的AB包分别依赖于该独立材质AB包,这样材质资源仅会被打包一次,节省了游戏资源空间。从Unity5.x开始,系统会自动判断所有AB包的资源之间的依赖关系,不需要开发者手动处理。

2.资源的依赖加载

如果要加载一个带依赖关系的AB包,那么必须首先加载它所依赖的所有其他AB包,否则此AB包中使用Load加载的对象将会丢失依赖的资源关联。

还存在另外一种情况,当尝试加载N个带有依赖关系的AB包时,其实很难预先知道每一个AB包所依赖的其他资源列表,因此这部分依赖关系信息就需要在程序运行时动态获取。AssetBundle提供了一个名为GetAllDependencies的方法专门用于获取当前AB包所以来的资源列表,这样就可以在程序中预先加载所有依赖的AB包了。

————————————————

版权声明:本文为CSDN博主「heliocentricism」的原创文章,遵循CC 4.0 BY-SA版权协议,

原文链接:https://blog.csdn.net/heliocentricism/article/details/109209801

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容