zoukankan      html  css  js  c++  java
  • 【Unity优化】资源管理系列03:AssetBundle 基本原理

    定义:将一个或多个文件,按照一种归档格式,存在一个文件中,Unity可以索引并序列化其中的文件

    操作:加载/卸载AB自身、加载卸载AB中某个资源

    作用:在游戏安装后,继续分发和更新非代码资源

    1)减小游戏包体

    2)减小运行时内存压力

    3)针对不同设备/平台,加载不同资源

    AB结构

    1)数据头:identifier、压缩类型、manifest

    manifest:查找表,key是对象名,value中包含一个字节索引,定位数据段中对象位置

    2)数据段:资源系列化后的原始数据

    三种压缩类型

    1)LZMA:所有资源的序列化数据,被压缩进同一个字节数组

    2)LZ4:每个资源的序列化数据,单独被压缩为字节数据

    3)不压缩:原始字节数据

    压缩类型对比

    1)LZMA:

    优点:原始AB小

    缺点:想要加载其中一个资源,需要解压整个AB;运行时占用内存大

    2)LZ4(推荐):

    优点:想要加载其中一个资源,只需要解压相关数据块;运行时占用内存小

    缺点:原始AB大

    加载AB

    1)AssetBundle.LoadFromMemory

    说明:不推荐,两倍AB内存占用,三倍资源内存占用

    2)AssetBundle.LoadFromFile

    说明:推荐,只加载数据头,之后按需加载资源

    补充:在Editor模式下,异步方法会加载整个AB,会出现内存峰值;真机中没有

    3)UnityWebRequest 的 DownloadHandlerAssetBundle

    ① 可以使用 UnityWebRequest.GetAssetBundle,也可使用 DownloadHandler

    ② DownloadHandler 使用工作线程,流式下载,存入固定大小buffer,然后传给临时存储或 AB cache。这些操作都有原生代码实现,不会产生堆分配。且不会额外保存下载字节数据的拷贝,减少内存占用。

    ③ 如果AB是LZMA压缩格式,在下载的时候会被解压缩,并以LZ4格式缓存。

    ④ AB下载完成后,通过 DownloadHandler 的 assetBundle 获取AB。

    ⑤ 如果AB之前已被加载,且在缓存中,则会立即返回,此时和 LoadFromFile 功能类似

    4)WWW.LoadFromCacheOrDownload

    说明:Unity5.6之前使用,已废弃

    5)建议

    ① LoadFromFile,建议在任何可用的场景使用,无论是加载速度、硬盘占用、运行时内存占用,该API都是最高效的。

    ② UnityWebRequest,需要下载AB时使用;记得调用 Dispose 或 Using。

    ③ 如果自研下载器,需要适配 LoadFromFile 方法。

    加载AB中资源

    1)三种API

    ① LoadAsset(Async)

    ② LoadAllAssets(Async)

    ③ LoadAssetWithSubAssets(Async)

    2)同步与异步对比

    ① 同步方法:至少比异步快一帧;缺点是在资源加载完毕前,会阻塞主线程

    ② 异步方法:可以在一帧内加载多个资源,不阻塞主线程

    3)LoadAllAssets(Async)

    适用场景:从一个AB中加载大部分资源,且这些资源相互独立。

    优点:比多次调用 LoadAsset 快

    AB策略:如果一个AB中,超过66%的资源需要同时加载,则建议将这部分分离出来单独打包

    4)LoadAssetWithSubAssets(Async)

    适用场景:当需要加载一个由多个小资源组合而成的大资源时

    举例:FBX模型及其动画、精灵图集及其精灵

    5)资源加载的一些细节

    ① 从存储中加载对象数据,发生在工作线程上。

    ② 多个工作线程,使得多个对象可以同时被反序列化、处理、整合。

    ③ 当一个对象被加载完毕,Awake方法被调用,从下一帧开始,该对象可被引擎使用。

    ④ 对象加载在一帧中的时间不超过 time-slice,该值由 ThreadPriority 决定。

    ⑤ 发起异步调用,和对象被引擎可用,这两步间至少需要一帧,因此相同条件下,同步方法要比异步方法快一帧。

    6)AB依赖

    ① AB间的相互依赖可以通过 AssetDatabase 和 AssetBundleManifest 获取

    ② 在加载一个对象前,要先加载它依赖的所有AB。Unity不会帮忙自动加载,要自己实现

    7)AssetBundle manifests

    ① 被包含在一个以父文件夹命名的AB中

    ② 包含了AB中对象之间的引用信息

    ③ manifest AB 和其他 AB 一样,可以被加载、缓存、卸载

    ④ 使用 GetAllAssetBundles 方法获取所有包含 AB 列表

    ⑤ 使用 GetAllDependencies 方法返回该AB的所有依赖

    ⑥ 使用 GetDirectDependencies 方法返回该AB的直接依赖

    ⑦ 上面两个方法都会分配 string 数组,不要在性能敏感处使用

    8)建议

    ① 在性能敏感的代码之前,尽可能预加载需要的资源

  • 相关阅读:
    centos7.6 使用yum安装mysql5.7
    解决hadoop本地库问题
    docker-compose 启动警告
    docker 安装zabbix5.0 界面乱码问题解决
    docker 部署zabbix问题
    zookeeper 超时问题
    hbase regionserver异常宕机
    (转载)hadoop 滚动升级
    hadoop Requested data length 86483783 is longer than maximum configured RPC length
    zkfc 异常退出问题,报错Received stat error from Zookeeper. code:CONNECTIONLOSS
  • 原文地址:https://www.cnblogs.com/hearthstone/p/13357862.html
Copyright © 2011-2022 走看看