项目中没有使用lua脚本,所以热更只能资源更新,一旦逻辑代码上有改变,需要玩家自行更新游戏客户端.
本人把公司项目中的更新模块精简了下,还是画张流程图解释:
一般资源打入安装包有3种情况:
1.安装包没有资源,进入游戏后资源全部从资源服务器下载.
(包体最小 ,但第一次进入游戏耗时最长)
2.安装包有部分资源,剩余的资源还是从服务器下载.
(包体介于1-3之间,耗时也介于1-3之间)
3.安装包包含所有资源.
(包体最大,耗时最短)
所以在资源更新前先判断了是否第一次进入游戏,是否需要做解压缩的操作.
另外为了让逻辑更清晰版本对比和资源更新分开写成了2个单例类.
不扯淡直接干 ̄へ ̄:
1.版本对比管理器逻辑:
服务器有一份版本号文件version.txt 像这样:
获取该文件使用get方式,unity自带有类UnityWebRequest,他专门操作web请求.当然用www也是可以的,不过貌似官方要逐渐舍弃掉www?
(只要能取下文件就行方法不重要,小哥写代码从来都是复制粘贴稳得很 ✧(≖ ◡ ≖✿ )
客户端版本号在这里设置:
获取直接使用Application.version
版本号对比也不用傻不拉几的手写实现,c#库中已经提供了这玩意儿(System.Version类)为什么不用呢?
版本管理器类
UpdateVersionManager.cs
public class UpdateVersionManager:MonoSingleton<UpdateVersionManager>
{
private System.Version curVersion;
private System.Version onlineVersion;
public bool IsNeedUpdate;
public void CheckVersion(UnityAction<bool> onComplate = null) {
IsNeedUpdate = false;
StartCoroutine(progress(onComplate));
}
IEnumerator progress(UnityAction<bool> onComplate) {
//拉取服务器版本
MsgDispatcher.GetInstance().Fire(GameEvents.Msg_ShowLoadingContent, "检测版本号...");
UnityWebRequest req = UnityWebRequest.Get(GameConfigs.ServerVersionUrl);
yield return req.SendWebRequest();
if(req.isHttpError || req.isNetworkError) {
Debug.LogError(req.error);
yield break;
}
onlineVersion = new System.Version(req.downloadHandler.text);
curVersion = new System.Version( Application.version);
if(onlineVersion != curVersion) {
Debug.LogFormat("当前版本不是最新版本({0}),请及时更新到最新版本({1})",curVersion,onlineVersion);
IsNeedUpdate = true;
}
Debug.Log("版本检测完成!");
if (onComplate != null) {
onComplate(IsNeedUpdate);
}
yield return null;
}
}
2.资源更新逻辑:
解压缩安装包数据(第一次) -> 加载本地ab根目录下的manifest文件,该文件包含所有资源的信息和hash值 ->通过UnityWebRequest获取资源服务器上ab根目录的manifest文件,并加载他
->对比本地和资源的每个文件hash值,只要有hash不同的或者本地没有的统统放入下载列表中 -> 根据下载列表下载资源 ->全部下载完成,更新本地manifset文件.