Unity中关于AssetBundle和Resources的教程笔记

教程地址:https://learn.unity.com/tutorial/assets-resources-and-assetbundles#5c7f8528edbc2a002053b5a9

AssetBundle和Resources的内容主要包括4个方面:

  1. Assets(资产),Objects(对象)和serialization(序列化),主要包含Unity如何序列化Assets并处理Assets间的相互引用;
  2. Resources目录,内置的Resources的API;
  3. AssetBundle基础,如何操作AssetBundle,如何加载AssetBundle以及从AssetBundle中加载Assets;
  4. AssetBundle的使用模式,分配Assets到AssetBundle,如何管理加载的Assets。
  • Assets(资产),Objects(对象)和serialization(序列化)
    适当的Asset管理对快速加载和内存的少量使用非常重要,首先要先区分Assets和Objects
  1. Assets和Objects内部
    弄懂Unity标识和序列化数据的首要关键点是区分Assets和UnityEngine.Objects

    • Asset是硬盘中的文件,存储在Unity工程中的Assets目录下。比如Textures(纹理),3D模型,或者声音片段等。
    • UnityEngine.Object是一组序列化数据,共同描述特定的资源实例。如mesh(网格),sprite等。
      还有两种特殊的Object类型:ScriptableObject和MonoBehaviour
  2. 对象间引用
    所有UnityEngine.Objects都可以引用其他UnityEngine.Objects。 这些其他对象可以驻留在同一资产文件中,也可以从其他资产文件中导入。
    例如,一个材质对象通常具有一个或多个对纹理对象的引用。

    Unity使用File GUID和Local ID来辅助序列化,File GUID标识存储目标资源的资产文件,本地唯一的Local ID标识
    资产文件中的每个对象。其中File GUID存储在.meta文件中。

  3. 为什么需要File GUID和Local ID
    为了健壮性并提供灵活、平台无关的工作流程.File GUID提供了文件特定位置的抽象。 只要可以将特定的文件GUID与特定的
    文件相关联,该文件在磁盘上的位置就变得无关紧要。 可以自由移动文件,而不必更新引用该文件的所有对象。

    如果与Asset文件管理的File GUID丢失了,那么资产文件中所有对象的引用也将丢失。 这就是为什么.meta文件必须保持与其关联
    的Asset文件使用相同的文件名和相同文件夹存储的原因。

    Unity编辑器具有特定文件路径到已知文件GUID的映射。 每当加载或导入资产时,都会记录地图条目。
    映射条目将资产的特定路径链接到资产的文件GUID。

  4. 复杂Asset和导入
    Unity可以支持导入非本地资源,如FBX等,这些可以通过AssetImporter的API来处理。导入过程会将源Asset转换
    为适合目标平台的格式。此过程适用于所有资产,而不仅仅是非本地资产。本地资产不需要冗长的转换过程或重新序列化。

  5. 序列化和实例
    尽管File GUID和Local ID是健壮的,但GUID比较缓慢,并且在运行时需要性能更高的系统。 Unity在内部维护一个高速缓存,
    该高速缓存将File GUID和Local ID转换为简单的,会话唯一的整数。这些整数称为Instance ID,并以简单的,
    单调递增的顺序分配在缓存中注册新对象时。

    高速缓存维护给定实例ID,File GUID和Local ID之间的映射,这些映射定义了对象的源数据的位置以及对象在内存中的实例
    (如果有)。这使UnityEngine.Objects能够可靠地维护彼此之间的引用。解析实例ID引用可以快速返回由实例ID表示的已加载对象。
    如果尚未加载目标对象,则可以将File GUID和Local ID解析为对象的源数据,从而允许Unity即时加载对象。

  6. 加载大层次结构
    当序列化Unity GameObjects的层次结构时,例如在预制序列化过程中,重要的是要记住整个层次结构将被完全序列化。
    也就是说,层次结构中的每个GameObject和Component将在序列化数据中单独表示。这对加载和实例化GameObjects层次结构所需的
    时间产生了有趣的影响。
    创建任何GameObject层次结构时,CPU时间会以几种不同的方式花费:
    a. 读取源数据(从存储,从AssetBundle,从另一个GameObject等)
    b. 在新的变换之间设置父子关系
    c. 实例化新的GameObjects和组件
    d. 在主线程上唤醒新的GameObjects和Components

    从内存中读取数据要比从存储设备加载数据快的多,从存储设备加载数据的I/O操作就很费时。所以预制件的大小就需要把握好,因为
    整个对象都被序列化,加载速度就很受影响了。所以一定要使用多层次结构的prefab,可以将其分块,然后运行时缝合起来。

  • 资源目录
  1. 最佳实践
    最好是不使用,因为:
    a. 使用Resources文件夹会使更细粒度的内存管理更加困难
    b. 资源文件夹使用不当会增加应用程序的启动时间和构建时间,随着“资源”文件夹的数量增加,在这些文件夹中管理资产变得非常困难
    c. 资源系统降低了项目向特定平台交付自定义内容的能力,并消除了增量内容升级的可能性,AssetBundle Variants是Unity的主要工具,用于按设备调整内容

  2. 适当的使用
    某些情况下,还是需要使用Resource的,比如需要三方配置数据等,不需要patch的内容等

  3. Resource的序列化
    项目构建时,Resources中的Assets和Objects会合并到一个序列化文件中,包含元数据和索引信息,类似于AssetBundle。这样,在内部就
    需要构建查找结构,内部使用平衡搜索树,在splash播放的时候发生,这就需要消耗了。

  • AssetBundle基础
  1. 布局
    AssetBundle包含两个部分:头部和数据段。

  2. 加载AssetBundle
    通过提供的API加载:
    AssetBundle.LoadFromMemory(Async optional) - Unity不推荐该方式,因为需要使用3倍的字节数据的内存
    AssetBundle.LoadFromFile(Async optional) - 最高效的加载没压缩的数据。
    UnityWebRequest's DownloadHandlerAssetBundle
    WWW.LoadFromCacheOrDownload (on Unity 5.6 or older)

  3. 从AssetBundle加载Assets
    LoadAsset (LoadAssetAsync)
    LoadAllAssets (LoadAllAssetsAsync)
    LoadAssetWithSubAssets (LoadAssetWithSubAssetsAsync)

  4. AssetBundle的依赖
    Unity根据运行时环境使用两个不同的API来自动跟踪AssetBundle间的依赖。Editor下使用AssetDatabase的API查询依赖。
    AssetImporter的API可以访问和修改AssetBundle的分配和依赖。在运行时,Unity提供了一个可选API,
    以通过基于ScriptableObject的AssetBundleManifest API加载在AssetBundle构建期间生成的依赖项信息。

    当执行BuilePipeline.BuildAssetBundles的时候,Unity会序列化包含依赖信息的对象,然后单独存储,依据
    AssetBundleManifest类型。文件名与文件夹名相同。

  • AssetBundle使用模式
  1. 管理加载的Asset
    对于内存敏感的环境下,小心控制加载对象的大小和数量就非常重要了。Unity并不会在对象被移除的时候自动卸载它们。
    Asset的清理在特定时间触发,也可以手动触发。AssetBundle卸载如果不正确,会造成在对象在内存中的重复。

    AssetBundle的卸载通过AssetBundle.Unload(ture/false),当参数为true时会强制卸载所有,即便还有引用。参数为false时,
    只是将AssetBundle与Object(对象)的引用链接断开,下次加载时,不会重新建立链接,这样就造成了内存中的重复对象。

  2. 分发
    将项目的AssetBundle分发给客户端有两种基本方法:与项目同时安装它们或在安装后下载它们。

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