unity3d AssetBundle 资源热更专题

在这里插入图片描述

在这里插入图片描述

这是unity3d资源管理和热更新的教学课堂.

视频演讲稿:B站链接
https://www.bilibili.com/video/BV1354y1n7Kj

unity3d AssetBundle 资源管理和更新

市场上流通的手游几乎包都含热更新功能,已经是商业产品的标准配置。
这就意味着unity中高级或以上的岗位 需要具备 资源更新和管理的能力。

在中大型手游产品中,为什么都会集成热更新功能?

在发布新版本时,绕过平台审核所需要的手续和大量的时间。
玩家不需要重新下载安装包,减少用户流失。
方便游戏内容拓展或修改。

本课程会借鉴商业手游《天地劫》的热更功能.
目的是为了保证我们学到的技能和理论具有实用性。
而非纸上谈兵.

课程流程安排如下,
分析产品需求,定制解决方案,资源规划管理,代码框架实现.

或见思维导图

其中资源规划是个重要部分,资源如何打包,优化,划分,这都会对项目的后期的加密,体积大小,加载效率,更新效率,有着重要的影响。

项目需求:
     为战棋项目增加资源热更功能:
     更新包小,减少用户下载时长
     资源包支持加密,防止资源被破解
     加载效率高,容错性高
     资源内存占用无重复

资源管理规划
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

课程之所以定制了多个维度的标准,
目的是打造商用级别热更系统。
保证我们花费的学习时间具有实用价值。

感谢观看本期视频,我们下期再见.
在这里插入图片描述

正式内容会持续更新通过博客文章和视频配套更新,感谢观看本期视频

unity3d AssetBundle 资源热更专题《天地劫》

第一节:天地劫为什么要使用热更?




  




  

第二节:打包工具的使用,资源加载

打包工具的使用
加载资源包的方法

独立包和依赖包的区别

  

第三节:资源管理和包优化

详情见视频讲解

封装资源加载框架 提升开发效率

游戏采用了ab包的加载方式之后,资源的修改都需要重新打包
所以我们需要封装加载AB包的过程,他可以兼容编辑器加载模式

UNITY3D底层限制了包文件不能被重复加载,框架需使用字典缓存做兼容处理
在这里插入图片描述

asset bundle包的内存管理

产品质量的好坏和内存管理有着很大的联系。

手机系统为程序分配的可用内存是有限的,
程序占用内存一旦超过了系统分配的上限,游戏会出现闪退。

在这里插入图片描述

内存测试详情
//读取角色包
var asset= AssetBundle.LoadFromFile(c:/charater)

会把文件反序列化到内存,序列化内存占用从95kb增加到249kb
在这里插入图片描述

asset.LoadAsset(“131”);
在这里插入图片描述
asset 资源被加载到内存,贴图,模型,纹理
asset 内存从3.7mb 上升到 12.7mb
在这里插入图片描述

assetBundle.Unload(false);
卸载包体的序列化内存和asset内存

内存得到彻底释放

第二种情况:
MonoBehaviour.Instantiate(asset.LoadAsset(“131”));
对象被实例化到场景,这时候再去assetBundle.Unload(false);

只释放了 序列化内存,asset 内存占用不变,因为他不会释放正在被使用的资源

在这里插入图片描述

第三种情况:
MonoBehaviour.Instantiate(asset.LoadAsset(“131”));
对象被实例化到场景,这时候再去assetBundle.Unload(true);

释放了 序列化内存和 asset 内存,包体全部占用内存被清空
场景对象也看不见了
在这里插入图片描述

第4种情况
SceneManager.LoadScene(“empty”, LoadSceneMode.Single);
切换场景
asset 内存被释放,序列化内存有残留
在这里插入图片描述

第5种情况
assetBundle.Unload(false);
SceneManager.LoadScene(“empty”, LoadSceneMode.Single);

切换场景

内存被释放完毕无残留
在这里插入图片描述
总结 要完整的释放一个包的内存

assetBundle.Unload(true);

assetBundle.Unload(false);
SceneManager.LoadScene(“empty”, LoadSceneMode.Single);

ab包 序列化文件的作用是什么?
避免每次加载ab包 从硬盘读取,直接从内存读取

内存的读取性能是远超硬盘的

是空间换时间的一种策略

最终怎么定制ab包的加载策略,我们通过战棋游戏去详细讲解

读取ab的包方式和加载页设计

在首页进入游戏页的时候需要加载各种资源包,
在资源加载中会显示资源加载页面。

那么我们有两个选择
采用异步加载,可以计算加载进度
同步加载, 不可以计算加载进度

在《天地劫》里是采用了加载性能最大的方案

LoadFromFile>LoadFromFileAsync
资源加密之后
LoadFromMemory>LoadFromMemoryAsync
//加载效率 同步加载>异步加载
https://blog.csdn.net/u012112975/article/details/83789376

第六节:资源更新

在这里插入图片描述
我们接下来要做的事情就是为游戏架构资源更新系统:

文件服务器:
它存放着最新版本的资源文件和配置文件
配置文件记录了每个资源包的MD5校验码,版本号,大小

客户端
启动游戏时对比本地和服务器的资源差异
如果有差别,就下载到本地

那么怎么对比?
一般会有两种方案:
严谨模式
对比文件的md5码,优点:安全性高,缺点:性能消耗大

简易模式
对比配置文件,优点:速度快,缺点:安全指低

缺点:假如被软件当做垃圾清理后,游戏会因为缺少文件产生加载异常
但这种问题出现的概率是极低的
(具体演示看视频)

所以天地劫会在首页里加个修复按钮
就是为了应对少概率事件设计的

所以综合考虑对比配置文件的方案收益是最大的







实操:
制作资源版本比较功能

生成资源配置文件
放到文件服务器
测试:
客户端下载配置文件和本地作比较,提示需要更新包大小








文件下载功能:

断点续传,网络中断恢复下载

本地配置和服务器配置比较,得到文件 更新清单
下载完毕后,更新本地配置文件
完成

如何得到更新包大小?
计算下载清单里每个文件大小总和

断点续传
假如程序更新进度时50%,然后中途关掉
那么断点续传,可以恢复上次的下载进度

原理:请求下载文件时:请求要下载的开始和结束位置
每次得到数据增量写进文件

假如
当前下载的2.0版本的文件,进度到50的时候关掉了
服务器发布了3.0的版本
这就导致
就会出现文件的前一半的2.0的版本,后一半是3.0版本,文件就会无法被正常读取

为了避免这种情况
恢复下载前,判断恢复下载的文件md5是否和服务器一致
不一致就要先把本地文件删除

还需考虑
在恢复下载前,剔除掉已经失效的文件
比如服务器已经删除了该文件

下载完毕后,更新本地配置文件

网络中断恢复下载
检查网络有异常->UI通知->重新运行下载流程



游戏首包体积管理

在构建发布时,StreamingAssets目录下的资源会和游戏绑定发布

这就意味着,StreamingAssets体积越大游戏包体也就越大

所以,控制了StreamingAssets目录就意味着控制了游戏首包体积

游戏首包内置多少资源,不同的游戏有不同的方案

页游1~2%,天地劫100%, MMORPG 30-50%(核心资源)

我们接下来会演示怎么灵活分配首包资源

选择需要保留的资源->生成配置->拷贝到StreamingAssets



  

内置资源的变更和加载

资源内置在StreamingAssets下,手机平台不可修改
如果服务器ab包有版本更新,且对应客户端的内置资源如何应对?

我们需要一个配置文件,记录所有更新过的文件

在读取ab包时,我们要先判断该文件是否存在更新记录,
如果没有更新记录,从StreamingAssets加载
有更新记录 从 下载目录加载

经过以上处理之后,就为内置资源提供了更新和加载方案



资源加密和解密

通过assetStudio直接提取ab包资源
资源加密就是为了防止资源被工具提取

流程->加密ab包文件->运行时先解密后加载

解密文件的加载:读内存(LoadFromMemory),读文件流(LoadFromStream)

内存占用 LoadFromStream< LoadFromMemory
无加密和LoadFromStream 内存开辟峰值是520m ,LoadFromMemory580m

所以用文件流的加载方案会更节省内存

因为天地劫里采用了大量的StreamingAssets资源
解密方案根据平台分为2种

WINDOWS:
全部采用文件流解密

安卓:
在移动平台上在读取StreamingAssets资源的不能使用.net 的文件读取api
只能使用安卓特定的读取方式,UnityWebRequest

这就意味着StreamingAssets不能采用文件流解密

如果想采用文件流解密,必须要先解压资源包到持久化目录
目的是为了能用.net的文件api加载
但是对于天地劫来说,这种方案弊大于利,因为资源包太大,解压过程太久

所以:
StreamingAssets目录,采用 LoadFromMemory,
持久化目录采用LoadFromStream

实操部分

总结:ab的解密读取,优先使用内存占用最少的读文件流
windows平台 读文件流

安卓平台:因为受平台限制
StreamingAssets内的使用 读内存
持久化目录使用读文件流

依赖包的卸载和管理

当前项目ab包遵循无依赖设计,所以无需考虑卸载依赖包

对于ab包有过多的依赖的项目,怎么设计加载和卸载流程?

为ab设计引用计数,加载一次+1,卸载一次-1

在每次卸载后,如果引用计数为0则把包卸载

开发者根据实际情况选用加载和卸载方案

猜你喜欢

转载自blog.csdn.net/koljy111/article/details/117950793