全面讲解CocosCreator热更新

前言

本文主要引用cocos关于热更的官方文档,并在此基础上,总结sprout当前热更流程。

什么是热更

热更(新)本质上是从服务器下载需要的资源到本地,并且可以执行新的游戏逻辑,让新资源可以被游戏所使用,它可以使开发者在不发布新版本的情况下,修复 BUG 和发布功能,让开发者得以绕开苹果的审核机制,避免长时间的审核等待以及多次被拒造成的成本。

Cocos 默认的热更新机制并不是基于补丁包更新的机制,传统的热更新经常对多个版本之间分别生成补丁包,按顺序下载补丁包并更新到最新版本。Cocos 的热更新机制通过直接比较最新版本和本地版本的差异来生成差异列表并更新。

cocos热更概述

manifest

了解cocos热更之前,先要了解manifest。在cocos中,manifest是一种文件格式,其对应的文件简称资源描述文件,是用来描述本地或远程包含的资源列表及资源版本。

manifest格式是仿照json格式,其关键字段的含义如下 :

{
    "packageUrl" :          远程资源的本地缓存根路径
    "remoteVersionUrl" :    [可选项] 远程版本文件的路径,用来判断服务器端是否有新版本的资源
    "remoteManifestUrl" :   远程资源 Manifest 文件的路径,包含版本信息以及所有资源信息
    "version" :             资源的版本
    "engineVersion" :       引擎版本
    "assets" :              所有资源列表
        "key" :             资源的相对路径(相对于资源根目录)
        "md5" :             md5 值代表资源文件的版本信息
        "compressed" :      [可选项] 如果值为 true,文件被下载后会自动被解压,目前仅支持 zip 压缩格式
        "size" :            [可选项] 文件的字节尺寸,用于快速获取进度信息
    "searchPaths" :         需要添加到 FileUtils 中的搜索路径列表
}

Manifest 文件可以通过 Cocos Creator 热更新范例中的 Version Generator脚本 来自动生成。

工程资源和游戏包内资源的区别

大家在创建一个 Cocos Creator 工程的时候,可以看到它的目录下有 assets 目录,里面保存了你的场景、脚本、prefab 等,对应编辑器中的 assets 面板。但是这些工程资源并不等同于打包后的资源,在使用构建面板构建原生版本时,我们会在构建目录下找到 res 和 src 文件夹,这两个文件夹内保存的才是真正让游戏运行起来的游戏包内资源。其中 src 包含所有脚本,res 包含所有资源。

所以我们的资源热更新自然应该更新构建出来的资源,而不是工程的 assets 目录。

在creator2.4.3中,重构了资源管理模块,采用bundle模块化管理资源。这里分享一个通过uuid来获取资源路径的API

cc.assetmanager.utils.getUrlWithUuid  //转换 uuid 为 url,这里返回的url是运行时游戏包内的资源路径

searchPaths搜索路径

在谈到热更之前,关于searchPaths的概念,有必要先了解一下。在大多数的时候,我们描述一个文件的路径,都会基于一个”根目录“去给到对应的”相对路径“,并不会直接写死成”绝对路径“,这样更利于维护、迁移。在游戏开发中,其实我们”根目录“也是很难保证其确定性、唯一性。就拿热更功能而言,我们有一个图片,假设其对应bundle目录(默认是resources)的相对路径是 ”./png/icon1.png“,当我们游戏版本更新,需要更新该图片的时候,由于包内的资源是不可写的,那我们只能让其从另外一个地方读取到新的图片,为了保证代码的一致性,如果我们可以改变其对应的”根目录“,那代码中之前的相对路径都不需要修改,就能找到新的图片。

在creator中,其维护勒一套搜索路径的策略。对应的API可以查阅jsb.fileUtils.getSearchPaths、jsb.fileUtils.fullPathForFilename等。这里简述其原理。FileUtils中保存勒一个”根目录“数组,index越低的优先级越高,在查找资源的时候,我们如果指定的是”相对路径“,则其会按照searchPaths里面的”根目录“的优先级,去拼接成”绝对路径“去查找资源,如果路径有效,找到勒文件,则会停止继续寻找。

在游戏包的安装目录,肯定有一个目录是存放我们打包后的各种脚本、资源,我们这里称之为”游戏包目录“,在热更逻辑中,我们需要指定一个”热更目录“来存放我们热更的内容,这两个目录都应该设为搜索路径,并且需要控制版本,使优先级更高的目录,对应的搜索路径优先级也要越高,这样,我们才能找到最新的文件。一般而言,”热更目录“的优先级需要高于”游戏包目录“。

cocos的基础热更流程

这是cocos官网资料的流程图,注意,当前流程是用户安装好 app 后,第一次检查到服务端的版本更新的情况,完整的热更流程会更为复杂一些,后面我们再慢慢补充。

本文主要帮助大家理解热更本身的流程逻辑,其各个细节,如断点续传、下载进度、并发下载、错误检测、解压缩、错误恢复等细节问题,暂不讨论。所以,把上诉流程图,可简单概况为:

根据当前包内的manifest的remoteVersionUrl字段,去下载其当前的版本描述文件,然后根据与本地的版本对比,若需要更新则更新到对应最新版本,不然就不需要更新,继续后续流程。

这里需要对其几个关键点,再细化剖析一下:

_localManifest:当前包内的manifest

首先,”游戏包目录“内应该有一个默认的manifest文件,描述当前游戏版本("version"字段),这个manifest一般随游戏包卸载、安装来更新。然后在”热更目录“也会有一个manifest文件,描述当前热更目录下的版本信息。我们每次启动游戏的时候都应该判断一下,当前环境下,到底是”游戏包目录“,还是”热更目录“才是最新的版本,来调整其对应在searchPaths的优先级,较新的manifest也就称为当前包内的manifest,代码中用_localManifest来记录。
注意,上述cocos基础热更流程中,并没有这一步,是因为其表示流程是包第一次安装的情况,热更目录下是没有manifest文件,所以_localManifest就是”游戏包目录“,完整的热更流程是需要做这一步判断的。
上诉逻辑对应的代码,请参阅:AssetsManagerEx的init、loadLocalManifest等函数。

先请求远端版本manifest

在manifest的”remoteVersionUrl“字段中,其对应的是远端服务器的版本文件,下面给到官方demo的一个version.manifest,便于大家理解

{
    "packageUrl":"http://192.168.50.220:5555/tutorial-hot-update/remote-assets/",
    "remoteManifestUrl":"http://192.168.50.220:5555/tutorial-hot-update/remote-assets/project.manifest",
    "remoteVersionUrl":"http://192.168.50.220:5555/tutorial-hot-update/remote-assets/version.manifest",
    "version":"2.0"
}

从上面可以看到,version.manifest有一个“version”字段,这也是我们快速进行版本对比的依据。下载version.manifest,然后再与本地_localManifest的版本对比,来检测当前包是否需要更新,这个过程代码上一般命名为checkUpdate。

临时文件夹的必要性

在热更过程中,因为我们是多个资源依次下载的,这期间很可能出现各种问题,所有,我们需要一个临时文件夹来暂存我们的下载,等到全部文件下载结束后,还需要检测文件是否完整,才能去替换“热更目录”下的旧资源,不要直接在“热更目录”上下载,一旦出现问题,自己也搞不清那部分是新的,那部分是还是旧的。这种思路在程序设计中也可以借鉴体会,我们负责的一些数据、字段的维护,尽量能做到整体的替换更新,而不是到处随意的去修改、赋值。

热更是热更差异化文件,是怎么做到这点的

在manifest文件中,"assets"字段下,记录每个资源的key和md5信息,只需要远端的_remoteManifest下记录的资源进行对比,新的key则是新增资源,没有的key则是需要删除的资源,md5不同的就是需要更新的文件。
对应的代码,请参阅:Manifest的genDiff等函数。

热更好之后,怎么让其生效

当我们热更好了新的资源后,怎么在不需要调整代码的情况下,让其生效?哈哈,刚刚上文已经介绍过了,我们调整我们的searchPaths,让“热更目录”优先级高于“游戏包目录”即可。
上面的流程图中,cocos推荐的是用cc.sys.localStorage把_localManifest对应的路径存储起来,并在后续app启动的开始阶段,就从cc.sys.localStorage读取对应路径,设置到searchPaths中。
上诉方案固然可行,但是就一个完善的客户端框架而言,尤其是针对多子项目的大厅类游戏,个人认为这种动态存储路径、设置路径并不是比较合适的方案。在架构设计上,我们需要先确定好整个客户端的“热更目录”,并确定好优先级,即整个项目的searchPaths都是按照我们设定的逻辑固定好,而不是动态的去调整,这样的好处是,在唯一的地方确定好searchPaths逻辑,之后仅需要根据逻辑,增删对应路径下的资源即可,这样应该是更利于扩展和维护的。但同样需要注意,这种固定好searchPaths的方案,在app安装替换的时候,要维护好新的“游戏包目录”的版本与之前“热更目录”下的版本对比情况,如,app本地安装升级后的版本比之前“热更目录”的版本更高,可以考虑把之前“热更目录”下的资源都清空掉,另外一种更麻烦的逻辑是,app安装升级后的版本还是比“热更目录”版本低,这是要注意,“热更目录”存储的是相对于升级前“游戏包目录”的差异化文件,升级后“游戏包目录”下的文件发生变化,那“热更目录”下的差异化文件就不一定能兼容当前的“游戏包目录”,这种情况也可以把“热更目录”情况,让其重新去对比、热更差异化文件。

旧的版本资源怎么处理

cocos的热更的虽然是差异化文件,但是其manifest脚本是记录勒对应bundle所有的资源,我们是能知道哪些资源已经不需要的,上文genDiff函数也提到过,但是个人认为,旧资源的删除需要谨慎,至少也是确保新资源更新好后,再去删除旧资源。

总结

如果读者在消化勒上诉的一些知识后,利用cocos提供的基础功能函数,是完全可以彻底定制自己的热更流程的。热更,一言以蔽之,下载最新的远端资源替换当前包体内的就资源而已。比如一些小项目,完全可以整包的下载、替换,可以忽略其中版本对比、searchPath调整、文件校验等细节。

以上就是全面讲解CocosCreator热更新的详细内容,更多关于CocosCreator热更新的资料请关注我们其它相关文章!

(0)

相关推荐

  • 怎样在CocosCreator中使用游戏手柄

    一.场景布置 二. 添加手柄监听器 1.监听事件的变化 由原先的mouse系列的转换为touch系列的 touchstart 触摸按下,相当于 mousedown touchmove 触摸移动,相当于 mousemove touchend 触摸抬起,相当于 mouseup touchcancel 触摸取消,被其他事件终止,相当于按下了ESC键 2.坐标设定 当触摸按下随推动位置变化(要用世界坐标转换),触摸抬起后回归原位(直接设定0,0坐标默认相对坐标). setPosition()设定的为相对

  • CocosCreator通用框架设计之网络

    前言 在 Cocos Creator 中发起一个 http 请求是比较简单的,但很多游戏希望能够和服务器之间保持长连接,以便服务端能够主动向客户端推送消息,而非总是由客户端发起请求,对于实时性要求较高的游戏更是如此.这里我们会设计一个通用的网络框架,可以方便地应用于我们的项目中. 使用websocket 在实现这个网络框架之前,我们先了解一下 websocket.websocket 是一种基于 tcp 的全双工网络协议,可以让网页创建持久性的连接,进行双向的通讯.在 Cocos Creator

  • 如何在CocosCreator中利用常驻节点做图层管理

    CocosCreator版本:2.3.4 一般游戏都有图层管理,比如 sceneLayer 场景层 panelLayer 弹框层 tipLayer   提示框层 cocos里的场景不是持久化的,每次切换都会自动destroy,如果在场景上放这些图层,那么每个scene都要放一遍?然后再获取,这样很麻烦. 加载场景使用的是cc.director.loadScene,scene的容器node貌似是director上的一个nodeActivator 现在如果不考虑scene的容器或者cocos的顶层容

  • 整理CocosCreator常用知识点

    一.场景加载 cc.director.loadScene('场景名称');//场景跳转 cc.director.preloadScene('场景名称');//预加载场景 cc.director.getScene();//获取当前场景 二.查找节点 1,节点查找 node = cc.find("Canvas/bg");//路径访问节点 性能消耗相对较大 this.node.getChildByName('name');//名称获取子节点 性能消耗较小 node.getComponent(

  • 详解CocosCreator项目结构机制

     一.项目文件夹结构 初次创建并打开一个 Cocos Creator 项目后,开发者的项目文件夹将会包括以下结构: 下面我们将会介绍每个文件夹的功能. 1.资源文件夹(assets) assets 将会用来放置游戏中所有的本地资源.脚本和第三方库文件.只有在 assets 目录下的内容才能显示在 资源管理器 中.assets 中的每个文件在导入项目后都会生成一个相同名字的 .meta 文件,用于存储对应的资源配置和索引信息..meta 文件需要一并提交到版本控制系统,详见 资源管理注意事项 --

  • 如何使用CocosCreator对象池

    前言: 在运行时进行节点的创建( cc.instantiate )和销毁( node.destroy )操作是非常耗费性能的,因此我们在比较复杂的场景中,通常只有在场景初始化逻辑( onLoad )中才会进行节点的创建,在切换场景时才会进行节点的销毁.如果制作有大量敌人或子弹需要反复生成和被消灭的动作类游戏,我们要如何在游戏进行过程中随时创建和销毁节点呢?这里就需要对象池的帮助了. 对象池就是一组可回收的节点对象,我们通过创建cc.NodePool的实例来初始化一种节点的对象池.通常当我们有多个

  • 如何用CocosCreator实现射击小游戏

    分析下制作步骤: 1. 准备好资源,搭建场景 资源的话可以自己到网上找,也可以直接用我的也行:创建好相应文件夹,把资源放到res文件夹下: 搭建场景: 第一步:创建一个单色精灵(Script) bg 背景, 设置好颜色,加一个Widget组件,使其充满屏幕: 第二步: 在bg节点下创建top和button空节点作为顶与底部,然后在两个空节点加入带刺的节点(直接将图片拖到top层级管理器就可以),现在我们需要给top与button节点添加一个Layout组件,属性设置如图,这样可以看到屏幕上下都有

  • 游戏开发中如何使用CocosCreator进行音效处理

    在游戏开发中,我们经常需要使用音效来营造游戏氛围,因此本文给大家总结下 Cocos Creator 游戏开发中音效组件的封装和使用. 一. Cocos Creator 中音频播放基础 1. 基础知识 [1]AudioSource 组件官方文档:http://docs.cocos.com/creator/manual/zh/audio/audio.html [2]cc.audioEngine官方文档:http://docs.cocos.com/creator/manual/zh/audio/aud

  • CocosCreator如何实现划过的位置显示纹理

    1.项目需求 项目需要有一个功能:是当一个光点走过的路径,这个路径的位置就都亮起来的功能. 2.资料内容 功能类似这位大神的橡皮擦功能:https://forum.cocos.org/t/2-0-8/74246 但是,项目的需求还要经过的路径周围有模糊的外边--也就是从中心到边缘越来越暗. 所以对于借鉴了网上大神的shader例子,类似以下的示例: 在大神的肩膀上做了一些改动,来实现项目的需求. 3.项目示例 以下是我自己的测试项目的示例: (请忽略这渣渣的画质,懒得装录屏软件了) 4.项目代码

  • CocosCreator ScrollView优化系列之分帧加载

    一. 前言 JS是单线程的,也就意味着所有任务需要排队,只有当前一个任务结束了,后一个任务才会执行.如果前一个任务耗时很长,后一个任务就不得不一直等着. Cocos Creator 是采用 Java Script/Type Script语言开发,本质上是JS,同样会拥有以上特征.特别地,如果使用不当,极有可能导致界面卡顿. 比如:在为一个ScrollView的Content创建500个节点的的时候,可能就会出现下面界面卡死的问题 PS:本来加载过程中有一个loading对话框,因为卡死了,就感觉

  • 详解cocoscreater预制体prefab

    预制体prefab 什么是预制体,字面意思,还未使用前预先制作好的节点资源,属性等同于普通节点,可以看做一个预先制作还没展示出来的普通的节点 怎么创建预制体 1.在层级管理器处先创建普通的节点,然后把这个节点拖拽到资源管理器的assets文件夹下,出于方便管理会统一建立一个Prefab文件夹下统一存放预制体 双击预制体节点可以看到它呈现蓝色,这时候就可以删除还留在场景场景里的节点,需要使用该节点时,通过预制体创建 这时候可以看到属性检查器里的属性,和普通节点一致 预制体的作用 1.批量创建相同类

  • CocosCreator经典入门项目之flappybird

    开发环境 CocosCreator v2.3.1 node.js v10.16.0 vscode 1.46.1 游戏引擎概念 可以理解为一套已经编写好的代码,它封装了对底层接口的使用,是游戏开发的核心功能提供者. 一般分为6各部分: 图像渲染:控制电脑对游戏绘画的绘画操作,直接影响游戏质量 音频UI:提供音频特效,以及游戏UI部分,让游戏与用户交互更好 设备输入:键盘.鼠标.陀螺仪等 脚本引擎:提供脚本接口,为游戏开发者提供"笔墨" 网络引擎:数据交互模块,用服务器为客户端提供交互 物

随机推荐