7. 热更新
7-1. 热更新流程
热更新方案:
- 整包:
- 策略:完整更新资源放在包内
- 优点:首次更新少
- 缺点:安装包下载时间长,首次安装久
- 分包:
- 策略:包内放商量或者不放更新资源
- 优点:安装包小,下载快,安装急速
- 缺点:首次更新时间久
整包就是一开始安装既包含了热更新内容又包含了框架,,,分包就只包含了框架,,因此整包首次安装更新少,分包从商店下载快但是后续更新内容久,主要是下载热更新包,,说白了就是一个安装前包含在下载包里了,一个是安装后下载,,,,分包主要是google等海外商店限制安装包尺寸,,,所以海外用分包,国内用整包
如果是整包模式多了绿色框内的部分,,如果是初次安装,就素要把资源从Application.streamingAssets释放到Application.persistentDataPath
:::info
整包:为了减少逻辑复杂性,避免判断两个路径哪一个路径有所需要的文件,因此直接把资源从Application.streamingAssets释放到Application.persistentDataPath,所有资源的读取都在persistentDataPath去寻找,没有的资源从服务器下载。
:::
分包模式,直接从服务器下载热更资源,去可读写路径下读取文件
这个Application.persistentDataPath,是PathUtil里定义的BuildResourcesPath,就是Bundle文件和版本信息文件的路径。
public static string BundleResourcePath
{
get
{
if (AppConst.GameMode == GameMode.UpdateMode)
return Application.persistentDataPath;
return Application.streamingAssetsPath;
}
}
7-2. 热更新细节分析
整个流程就需要这三个流程,下载文件、写入文件、解析filelist
检测初次安装:
- 只读目录有热更新
- 可读写目录没有热更新资源
- 只需判断filelist文件是否存在即可
注意:最后写入filelist
:::info
整包模式下:初次安装,只读目录必然有filelist,如果可读写目录没有filelist需要释放,进行初次安装,filelist必须最后写入,,因为如果释放到一半,filelist写入了,下次再打开游戏没有释放完资源,有问题,,,最后写入即便中途退出,下次启动也会重新释放资源
:::
检查更新:
- 下载资源服务器的filelist文件
- 对比文件信息和本地是否一致
7-3. 热更新需要做哪些事
- 下载文件(HotUpdate)
- 写入文件(FileUtil)
- 解析filelist(HotUpdate)
//只读目录
public static readonly string ReadPath = Application.streamingAssetsPath;
//可读写目录
public static readonly string ReadWritePath = Application.persistentDataPath;
//热更新资源链接地址
public const string ResourcesUrl = "http://127.0.0.1/AssetBundles/";
创建热更新脚本。
句柄一般是指获取另一个对象的方法——一个广义的指针,它的具体形式可能是一个整数、一个对象或就是一个真实的指针,而它的目的就是建立起与被访问对象之间的唯一的联系 。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class HotUpdate : MonoBehaviour
{
internal class DownFileInfo
{
public string url;
//bundle名
public string fileName;
public DownloadHandler fileData;
}
//协程方法下载文件
/// <summary>
/// 下载单个文件
/// </summary>
/// <param name="url"></param>
/// <param name="">返回一个下载句柄的Action</param>
/// <returns></returns>
IEnumerator DownLoadFile(DownFileInfo info, Action<DownFileInfo> Complete)
{
//老版本用WWW,现在已经弃用
//新版需要使用UnityWebRequest,,,,,引入UnityEngine.Networking
UnityWebRequest webRequest = UnityWebRequest.Get(info.url);
//下载一个文件,等待,下载完继续执行
yield return webRequest.SendWebRequest();
//if(webRequest.isHttpError || webRequest.isNetworkError)
if (webRequest.result == UnityWebRequest.Result.ProtocolError || webRequest.result == UnityWebRequest.Result.ConnectionError)
{
Debug.Log("下载文件出错:" + info.url);
yield break;
//下载失败,重试,有次数限制
}
//下载完成后,给info赋值
info.fileData = webRequest.downloadHandler;
//如果下载的是filelist,直接解析,用webRequest.downloadHandler.text.
//如果是bundle,可以写入,用webRequest.downloadHandler.data
Complete?.Invoke(info);
//下载完成后释放掉。
webRequest.Dispose();
}
//下载多个文件的接口,不可能再一个循环中下载1000个文件
/// <summary>
/// 下载多个文件
/// </summary>
/// <param name="infos">多个文件列表</param>
/// <param name="Complete">下载一个文件完成的回调,然后写入</param>
/// <param name="DownLoadAllComplete">所有文件下载完回调,通知用户释放资源、更新</param>
/// <returns></returns>
IEnumera