Unity资源热更新知识梳理及工作流介绍

简介: 研究了大半年的热更,才做出了一套相对完善的热更架构。不得不说,这块的知识点还是多而杂的,值得专门开篇博文来记录梳理。

知识梳理

AssetBundle

定义

AssetBundle,也就是俗称的AB包,是Unity中使用的一种文件类型,是一种可以存在硬盘上的文件,简单来说,就是“资源压缩包”,Unity中的资源,包括场景、预制体、贴图、模型等任何资源,都可以打包进AB包内,以字节的形式存储在文件中,在游戏运行过程中可以通过特定的函数一模一样的加载出来。

优势

  • 所有的资源都可以在游戏运行时通过代码从AB包中动态读取,可以不改变源代码,仅通过外部更新AB包文件来实现资源的更新。
  • 可以将游戏中的某些资源压缩进AB包,从外部读取,减少安装包的大小,方便引流下载。
  • AB包会自动保存资源依赖,比如材质球与预制体,分别打包成两个AB包:甲、乙,当AB包甲加载完毕后再加载AB包乙中的预制体,将会自动读取AB包甲中依赖的材质球资源。
  • AB包中可以采用LZMA、LZ4的压缩算法,可以减少资源大小,加快网络传输速率。

压缩算法

  • LZMA:默认压缩算法,包体最小,加载速度慢,加载时需要先解压整个包
  • LZ4:主流压缩算法,包体中等,加载速度中等,加载时只需要解压需要的模块
  • 不压缩:包体最大,加载速度最快,加载时无需解压

综合考虑包体与加载速度,通常都是通过LZ4的算法压缩。

打包方式

  • AssetBundlesBrowser:一款用于处理AssetBundle的U3D插件,提供了可视化界面,适合新手上手打包
  • BuildPipeline.BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform):U3D编辑器AB包打包函数,可以自己选择导出根目录、打包算法及使用平台,通过自行编写打包逻辑,可以一键完成AB包打包、加密、压缩等逻辑,参数详解如下:

    • outputPath:打包出的AB包文件存放的目录
    • assetBundleOptions:AB包压缩算法

      • BuildAssetBundleOptions.None:LZMA算法
      • BuildAssetBundleOptions.UncompressedAssetBundle:不使用压缩算法
      • BuildAssetBundleOptions.ChunkBasedCompression:LZ4算法
    • targetPlatform:打包出AB包使用的目标平台

      • BuildTarget.Android:Android平台
      • BuildTarget.StandaloneWindows64:Windows64位系统
      • BuildTarget.iOS:iOS平台

加载/卸载

加载AB包

  • AssetBundle.LoadFromFile(string filePath):通过AB包文件路径加载资源
  • AssetBundle.LoadFromFileAsync(string filePath):通过AB包文件路径异步加载资源
  • AssetBundle.LoadFromMemory(string filePath):通过字节集加载资源
  • AssetBundle.LoadFromMemoryAsync(string filePath):通过字节集异步加载资源

卸载AB包

  • assetBundle.Unload(bool unloadAllLoadedObjects):卸载AB包

    • unloadAllLoadedObjects: 是否清理所有加载出来的资源,这里需要注意预制体资源实例化的物体不会清理掉,但所有引用类型的资源,比如物体上的材质球,都会清理掉造成丢失

加载AB包中的资源

  • assetBundle.LoadAsset(string name):从AB包中加载T类型的资源name
  • assetBundle.LoadAsset(string name,Type type):从AB包中加载type类型的资源name

分包策略

AB包的尺寸会影响到加载速度,测试发现,AB包大小控制在1MB左右,可以保证较高的加载效率,同时,较小的包体细度,也可以避免玩家每次热更下载AB包,过多的浪费资源下载AB包中捆绑未更新的其他资源,因此,AB包的分包策略十分重要,这里举例几种:

  • 根据类别分类:资源类别相同的打包到一起,如图片资源打包到一起、材质球打包到一起,若单种资源过多,则分成多个包,如p1、p2、mat1、mat2

    • 优点:最为通用,不需要考虑资源用途,只需要考虑每种资源拆分出AB子包的尺寸
    • 缺点:加载包含复杂依赖的资源时,可能需要加载多个AB包中的依赖资源,导致加载速度变慢、内存占用高。
  • 根据用途分类:业务逻辑需要同时加载的资源打包到一起,如一个UI中所有的预制体、图片、材质球等都放到一起

    • 优点:加载速度快,使用时不需要加载太多的依赖包;玩家热更下载的AB包大部分是需要更新的资源;
    • 缺点:公用资源较难处理,每种资源放入前都要规划好用途,一旦公用,还得提出至公用资源AB包;单个AB包尺寸容易超过限制。
  • 根据更新频率分类:更新频率差不多的资源打包到一起

    • 优点:避免玩家热更时下载过多未更新的资源
    • 缺点:具体分组策略仍需要参考上面两种

具体项目,可以综合考虑以上几种情况,根据项目特点,来制定分包策略。

使用性能优化建议

AB包大概能分为三个方面的优化:下载速度、加载速度、内存管理,建议如下:

  • 下载速度:

    • 通过多线程下载
    • AB包文件压缩成压缩包,下载到本地后解压
  • 加载速度

    • AB包大小控制在1MB
    • 通过进度条界面,预加载或者初始化对象池,加载较大资源
  • 内存管理

    • 如无必须进行资源加密的需求,建议使用LoadFromFile的方式加载AB包
    • AB包与资源加载使用后及时卸载
    • AB包中依赖相关包不宜太多、太大

热更新

热更类型

U3D的热更新可以分为资源热更逻辑热更

热更原理

  • 资源热更

资源热更主要基于AssetBundle技术实现,项目中所有需要热更的资源均读取自AB包文件,通过在线更新外部的资源文件,来实现整个项目资源的热更新。

  • 逻辑热更

逻辑热更有C#与Lua两种语言的实现方案,目前我还没接触过C#热更,暂且只讲基于Lua语言的热更方案,其原理是通过基于U3D的Lua语言解释架构,可以将脚本语言Lua变成可执行的代码,而Lua属于脚本语言,其本质是一个Txt文本,在U3D里属于TextAsset资源,逻辑热更的本质,就是资源热更,通过资源热更获取最新的TextAsset资源中的Lua文本,然后通过架构转换成可执行的代码,目前比较流行的lua架构有xlua、tolua,各有各的优点,打算到时候开一篇专门的博文介绍逻辑热更时再说,这里就简单的提一下。

热更相关路径

  • Application.streamingAssetsPath:可读不可写,打包时不会压缩,可以在外部直接得到,一般用于存放跟随包体的默认资源AB包,值得注意的是,在Android平台下,无法通过IO操作读取,只能通过Unity自带的WWW方式读取到数据
  • Application.persistentDataPath:可读可写,不会跟随包体打包,一般用于存放下载来的最新AB包
  • Resources:不可读不可写,跟随包体打包,仅可通过Resources.Load加载资源,一般用于存放架构中不涉及热更的资源,如UI架构的UICanvas预制体
  • Application.dataPath:Android平台下不可读不可写一般仅用于编译器环境下开发使用,如导出AB包到项目的某个文件夹中。

热更工作流

这里仅阐述下我在项目中所使用的热更工作流,供以借鉴。

打包工作流

  1. 打包AB包文件至AB包导出目录
  2. 生成资源依赖文件,遍历AB包资源,动态查询依赖资源以及所属的AB包,以json形式存储,数据字段如下:

    • AB包名

      • 资源名

        • 所依赖的AB包名数组
  3. 生成版本文件,版本文件以json形式存储,数据字段如下:

    • Version:资源版本号,用于判断资源是否为最新版本
    • ClientVersion:客户端版本号,若C#底层修改需要重下客户端则修改该版本号
    • IsRestart:更新完毕是否需要重启客户端,框架部分资源已存储至缓存,更新完毕后若需要更新该部分缓存,则直接重启客户端
    • Content:更新描述,若客户端需要显示更新信息则使用该字段
    • Assets:资源文件版本信息数组

      • name:资源文件名字,用于找到对应文件
      • size:资源文件大小,用于验证资源文件是否损坏
      • hash:资源文件Hash值,用于验证资源文件是否损坏
  4. 加密上述文件,并保存至导出文件夹,注意若加密数据,上述资源文件版本信息中的size、hash值需要通过加密后的数据获得。
  5. 将部分需要与包体绑定携带的资源文件,放置在streamingAssetsPath目录,这里需要注意,当热更工作流中需要用到的资源,如lua文件、热更界面、版本文件、资源依赖文件等资源,必须与包体绑定携带
  6. 将导出文件夹中所有的资源文件,都放置在下载服务器上

校验工作流

  1. 从下载服务器中读取到版本文件并解密
  2. 通过加载工作流获得本地版本文件,与云端进行以下对比

    • 本地版本文件不存在,则提示第一次打开应用,需要下载资源文件
    • 对比本地资源文件的Size、Hash值,若发现不匹配,则对比资源版本号判断更新原因:

      • 若资源版本号相同,则提示资源损坏
      • 若资源版本号不同,则提示资源需要更新
    • 对比自身客户端版本号,若发现不匹配,则提示前往下载最新客户端

下载工作流

  1. 从下载服务器中下载需要更新的资源文件persistentDataPath目录中的Temp文件夹
  2. 当所有资源文件下载完毕后,前往Temp文件夹进行校验,所有资源文件校验通过,则移动至persistentDataPath目录中的Asset文件夹
  3. 所有资源文件下载完毕后,更新版本文件,保存至persistentDataPath目录

加载工作流

所有资源均放置在Resources目录中,目录包含一个AssetBundles文件夹若干自定义key文件夹

  1. 加载资源,需要传入key、assetName值
  2. 尝试通过AB包形式加载资源,若不存在,则进入下一步

    • 开发环境下,通过IO流查找AssetBundles文件夹中的具体资源文件路径,并通过Resources.Load加载
    • 发布环境下,读取AB包字节集,并通过AssetBundle.LoadFromMemory加载AB包,字节集读取方式如下:

      • 查询缓存内是否存在字节集,若不存在则进入下一步。
      • 通过persistentDataPath目录尝试读取,若存在,则解密存储进缓存,防止多次加载解密造成多余的时间损耗;若不存在则进入下一步。
      • 通过streamingAssetsPath目录尝试读取,由于上述打包工作流第五点规则,一定能读取到对应资源文件的字节集,解密存储进缓存。

    发布环境加载AB包资源时,注意需要通过资源依赖文件获取相关依赖,提前加载依赖AB包。

  3. 尝试通过Resources.Load([key]/[assetName])加载,一些框架固定不会更新的资源,比如UI架构的UICanvas预制体,可通过这种方式加载

Tip:版本文件资源依赖文件的资源加载单独处理,通过上述工作流中获取字节集的步骤,获得字节集并解密转为字符串,序列化为Json对象。

开源项目

放上一个开源的Unity热更架构,工作流如上,以供参考

https://github.com/GrayGuardian/HotUpdate
相关文章
|
4月前
|
存储 图形学 Android开发
Unity 数据读取|(一)宏的定义和资源路径
Unity 数据读取|(一)宏的定义和资源路径
|
5月前
|
算法 安全 C#
Unity——热更新浅析
Unity——热更新浅析
|
5月前
|
缓存 API 开发工具
Unity——工程与资源
Unity——工程与资源
|
11月前
|
API 网络安全 图形学
【unity细节】关于资源商店(Package Maneger)无法下载资源问题的解决
【unity细节】关于资源商店(Package Maneger)无法下载资源问题的解决
342 0
|
图形学
Unity热更新——lua语言
Unity热更新——lua语言
98 0
|
图形学
Unity热更新——AB包的基本操作
Unity热更新——AB包的基本操作
394 1
|
图形学 Windows
Unity热更新——AB包
Unity热更新——AB包
260 0
|
数据库 图形学
Unity3D MMORPG源码+资源+服务端+数据库(Unity3D)
本文转自:GameRes游资网 原文作者:zhihudaye 原文链接:bbs.gameres.com/forum.php?m…
【Unity 资源分享】☀️ | Unity 华丽炫酷特效资源分享!万年魂环拿到手软,让你直达封号斗罗~
目录 📢前言 🎄Unity特效展示 🏳️‍🌈魂环系列特效 🏳️‍🌈光剑特效 🏳️‍🌈球形特效 🏳️‍🌈爆炸特效 🎁资源下载
【Unity 资源分享】☀️ | Unity 华丽炫酷特效资源分享!万年魂环拿到手软,让你直达封号斗罗~
|
开发者 图形学 容器
Unity3D模型AAA级别Serekh塞拉赫资源制作技术
此项目致力于创作AAA级作品所需的高端资源。我们希望激励创作者拓展自己的领域,观察,分析和学习行业资深人士的技术与创作方法。
Unity3D模型AAA级别Serekh塞拉赫资源制作技术