Unity3D热更新

载在这个时代实在是太平常了,每个人都深刻的理解着下载到底是什么。

这一篇文字只是把下载的代码分享并介绍,而已。

首先,下载系统担负着几个使命。

第一、是保持客户端版本库的最新。

第二、是下载要能够比对并最少下载

第三、是要尽量快一些。

其实我们并没有写一个下载系统,因为实在没有几行代码。我们这里介绍的是一个

Http下载并保存缓存,首包从StreamingAssets读取,加载资源,三个功能在一起的模块

源码位置https://github.com/lightszero/easydown

保持最新

为了解决第一第二的问题,我们要尽量让下载的资源零散一些。

这样就可以以文件单位进行下载,本地已经有的文件就不下载。

为了实现这个目标我们得在下载之前就决定一个文件是否要更新,因为下载之后流量已经浪费了。

需要知道一个文件是否应该更新,一种简单的办法就是给每个文件提供一个简单的特征信息,先将特征信息下载,然后决定是否下载整个文件。

去一个大文件的特征信息,这是摘要算法的工作,Hash、CRC32、MD5、Sha1,我们这里选择最优秀的Sha1算法来做我们文件的特征信息。

首先我们得为我们打算下载的文件生成特征信息,这些测试文件和工具源码你都可以从GITHUB上下载到。

点击检查,会显示出如上的情况,告诉你版本和你上次的版本发生了什么变化。

请勿删除生成的allver.ver.txt文件,他会记录总的版本,每次检查都会基于上一个版本

然后点击生成版本,会更新所有的版本文件

这里我们加了个group的设计

版本生成工具会把自己路径下的文件夹作为group

在客户端下载时是以group为单位的,方便处理

比如我可以 把高分辨率资源和低分辨率资源分别放在两个group里

只要客户端简单的切换group名字,就可以实现资源切换。

比如这里就生成了两个Group,每个Group有自己的Ver文件

<ignore_js_op>

我们看看Ver文件

文件名,中间怪怪的就是sha1特征串,哪怕文件只改了一个字节,生成的特征串就会不一样。最后是文件尺寸,这样我们只要取得了ver文件,下载之前就知道文件有多大了。

这样我们就有了让文件版本保持最新的机制了

只要先下载ver文件,然后再判断每个group的文件有没有变化,有变化的有多少,然后下载他们。

把这些测试文件找个Http服务器放上去,然后我们继续

<ignore_js_op>

客户端下载

客户端如何下载?直接看代码说明

<ignore_js_op>

先一行代码初始化资源管理系统

第一个参数是下载服务器地址,就是对应allver.ver.txt文件的http地址

第二个参数是一个回调函数,由于初始化资源系统会去网络下载ver文件,需要时间,所以是用回调函数来通知的

第三个参数是一个List<string>,用来告知资源管理器,要检查哪几个Group。

你也许会疑问,怎么会有不检查的Group呢?比如我们的游戏要做好几个平台,有一些平台不通用的资源,我们把他们放在不同平台,这样在一个平台就不会去检查别的平台的资源。

注意Resmgr需要一直Update,因为不管是下载还是加载都不是立即完成的,Resmgr要一直监控情况

<ignore_js_op>

利用宏你就可以取到每个平台一个特殊的字符串,把他们混到group名字,就可以自动选取平台专用group下载了

还有第四个默认参数:并发下载数,默认1,要想充分利用下载带宽,你可以改成2,改更多的并发意义并不大,3并发和2并发效果不会有很大差异。

<ignore_js_op>

taskState是资源管理器提供的一个简单统计工具,用来得到有几个任务在执行,完成了几个。

GetNeedDownloadRes 就是比对出那些需要下载的资源

然后循环,下载,下载每个资源都可以提供一个独立的通知回调,但我们这里演示的是一个开始批量下载的用法,就不单独处理了。

最后WaitForTaskFinish函数,会一直等到所有任务完成再回调给我们,

这就完成了整个下载过程

下载进度

关于下载进度,我们可以利用taskState做简单的文件数量统计,也可以把downlist里面的每个文件的长度取出来自己计算。

演示个简单的

<ignore_js_op>

注意Resmgr需要一直Update,因为不管是下载还是加载都不是立即完成的,Resmgr要一直监控情况

加载使用

无论文件是本地最新还是刚刚下载完,无论是首包资源还是更新资源,我们的加载方式都是一样的

<ignore_js_op>

090019392251263.png (18.53 KB, 下载次数: 0)

下载附件  保存到相册

2014-8-18 16:44 上传

从Resmgr的 verLocal,本地版本管理 中取得对应的Group,然后从Group中取出File,然后调用File的BeginLoadXXX方法即可

<ignore_js_op>

我们提供了四种Load接口,其实一种Bytes就够了,其他资源全部都从Bytes中来,这个我们在加载篇中讲过。

但是考虑到常用性,我们对String Texture2D AssetBundle统一作了封装。

还有以下其他的资源是符合加载的,需要多个文件联合才能加载出来,我们把这种文件放到加载篇里去研究。

好了,你现在已经拥有热更新最重要的更新模块了,而且他完全For Free。

时间: 2024-10-20 12:42:24

Unity3D热更新的相关文章

Unity3D热更新全书-脚本(一) 初识脚本

开篇之前还是要先说明,这是一份给经验并不丰富的程序员阅读的文字. 有需求.有疑惑,往下看. 第一个问题什么是脚本?程序和脚本如何区分?我们给Unity编写的组件是程序还是脚本? 这些问题本文无意去解答,因为其中混合着太多有立场的东西,站在不同的立场会有不同的看法,这其中的矛盾不是简单可以调和的. 只要提出一个观点,就很容易陷入语言大战的泥潭. 我们不妨从另一个角度来思考,为什么要分程序和脚本,是为了找一条分界线. 这条分界线叫做灵活. 我们这个专题的出发点是探讨Unity3D客户端资源更新,已这

Unity3D热更新全书-下载 唯一的一篇

下载在这个时代实在是太平常了,每个人都深刻的理解着下载到底是什么. 这一篇文字只是把下载的代码分享并介绍,而已. 首先,下载系统担负着几个使命. 第一.是保持客户端版本库的最新. 第二.是下载要能够比对并最少下载 第三.是要尽量快一些. 其实我们并没有写一个下载系统,因为实在没有几行代码.我们这里介绍的是一个 Http下载并保存缓存,首包从StreamingAssets读取,加载资源,三个功能在一起的模块 源码位置https://github.com/lightszero/easydown 保持

Unity3D热更新全书-脚本(三) C#LightEvil语法与调试

调试,这是一个无法规避的问题 C#Light 由于有 词法解释.语法解释.运行时三种情况 所以和C#也是有类似的问题 出错大致可以分为编译错误和运行时错误 拼写出莫名的东西或者语法不正确,会在编译阶段报错,这种错误很好检查,因为 C#Light语法是C#的严格子集,所有的C#Light脚本都可以用C#的标准做语法检查 这也是C#Light基本上是用VisualStudio做编辑器的原因所在,直接作为C#代码编译,可以排除大部分的语法问题. 然后剩下的一些作为C#代码可以编译过,但是C#Light

Unity3D热更新全书-脚本(五) NGUI

让我们实际的研究一下如何将NGUI和C#LightEvil结合起来. 这里使用NGUI2.7,因为他是一个开源的版本,NGUI最新的版本未经作者的许可,是不可以带入我们的开源项目使用的. 这个例子完成的功能是从NGUI例子里找出了三个界面,按最下方的按钮依次进行切换 这是在之前的框架演示Mode1的基础上做的 由一个状态机去进行驱动,这也是我推荐各位使用脚本的方式. <=这是脚本,也是程序 Mode1的模式是定义一个接口类,然后由脚本继承此类型实现,因为随时考虑AOT的缘故(要兼容IOS),我们

Unity3d热更新全书-资源加载(一)从AssetBundle说起

Unity3D动态下载资源,有没有解?有,AssetBundle就是通用解,任何一本书都会花大幅篇章来介绍AssetBundle. 我们也来说说AssetBundle 我们试全面的分析一下Unity3D提供的资源加载机制 1.Resources//内嵌资源,使用方法Resources.Load,可以加载任意种类的资源,不能动态修改,卒. 2.StreamingAssets//随包资源,使用方法IO或WWW.Load.WWW.Load可以加载任意种类资源,IO仅限bytes 和 text. 3.W

Unity3d热更新全书-加载(二)如何在不用AssetBundle的前提下动态加载预设

Unity3D的主要构成大家都知道,首先是场景图,场景图上的节点构成一颗树. 每个节点对应一个GameObject对象 然后每个GameObject有若干个组件 有一些组件会与资源产生关系,比如MeshRenderer会关联材质,材质会关联shader和贴图 场景图的一部分可以被保存为一个预设,prefab. 有时候我们会需要用预设去复用,而预设的加载似乎只能通过AB去打包,其实不然,这里我们有一个开源的库就可以解决这个问题. 为什么不使用AB,可以见上一篇,加载(一),不使用AB一份资源全平台

Unity3D热更新全书-重头再来

之前写了Unity3D热更新全书系列Blog 提出了下载.加载.脚本三个方面的开源类库 下载方面有EasyDown加载方面有GameObjParser脚本方面有C#Light另外有一个没有独立成库,但是到处都用的Myjson. 2015,重头思考这些事情,有了不一样的感悟,于是也有了新的规划 1.首先了C#Light的语法解释问题变得臃肿低效,重头开始了L#项目.目前L#项目已经进入Beta阶段,完全可以全面替换C#Light.MyJson也独立成库2.下载方面,Easydown是基于经典的文件

Unity3D热更新全书-PageZero

由于深刻的认识到自己是个思维跳跃的人,深入浅出是个我还要努力很久的目标,为了让大家不至于在我乱七八糟的文字中迷失,特整理目录一份 无分类 <Unity3D热更新全书-何谓热更新,为何热更新,如何热更新> 这一篇是写给对热更新完全没概念的人 下载系列 还没写 加载系列 <Unity3d热更新全书-资源加载(一)从AssetBundle说起 > 这一篇是探讨使用AssetBundle来做资源更新的问题,希望能让更多人理解AssetBundle是有害的 脚本系列 <Unity3D热

Unity3D热更新全书-脚本(四) 用C#LightEvil搭建实际开发使用的脚本框架

C#LightEvil之前提供了很多和Unity结合的例子,都是采用把脚本文件放置在StreamingAssets中的方法. 这样可以利用Unity的特性,放在这个目录中的CS文件会被编译器编译,我们就利用C#编译器来对我们的脚本进行验证. 同时StreamingAssets中的文件又是直接随项目发布的,所以可以直接以文件方式取出这些脚本文件编译执行. 这是一个很巧妙的方式,但是用在实际项目中会有一些问题: 一.可能会让程序员产生混淆,哪里是脚本,哪里是程序,傻傻分不清楚 二.主程序里会有一份用

Unity3D热更新全书-脚本(二) 两级分化

上篇明确了我们探讨的脚本是什么:是写在文本文件里面的代码,可以作为资源加载,取得字符串再执行. 可是为什么世界上会有那么多的脚本?而其使用方法完全看起来不一样呢?这是因为每种脚本都有自己的定位,在不同的复杂度脚本将表现出完全不同的样貌,我们来看一下. 复杂度一:计算 执行字符串的核心函数应该是这样的 int i = Eval("1+2"); 我们有一套例子,本文最后有如何取得例子的说明. 程序里就可以通过执行字符串来执行逻辑,字符串的变更就可以得到逻辑的变更. 试想如果要做公式计算,他