我这里实现了3个文件来处理热更新:
Logo.cs 游戏的启动文件,里面处理下载存放资源路径的初始化。下载列表检查,下载,进入游戏
DownLoader.cs U3d的一个组件,里面包含具体的下载线程,用来处理开启多线程下载
HttpDownLoad.cs 具体的文件下载类,线程运行下载,支持断点下载
/* Logo.cs
* Created By Zhaotao On 2019-4-10
* Desc:游戏启动文件,处理更新流程,资源加载
*/
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using DigiskyUnity;
using UnityEngine;
public class Logo : MonoBehaviour
{
[SerializeField]
private bool _UseHotUpdate = false;
[SerializeField]
private string _ResServerHttp = "http://127.0.0.1:8001/";
private bool _FileListDownFinish = false;
private ResManager _ResMgr = null;
private LogoState _CurState;
private Splash _SplashCom = null;
private const string _VerFileName = "ver.txt";
private const string _FileListName = "files_list.txt";
private Dictionary<string,UpdateFileInfo> _OldDict = new Dictionary<string, UpdateFileInfo>();
private Dictionary<string,UpdateFileInfo> _ServerDict = new Dictionary<string, UpdateFileInfo>();
private long _DownByteSize = 0;
private long _FinishByteSize = 0;
private DownLoader _DownLoader;
private int _TotalDownloadCount = 0;
private string _ServerVer = "";
private bool _NeedSaveFileList = false;
private enum LogoState
{
INIT,
INIT_FINISH,
CHECK_UPDATE_LIST,
CHECK_UPDATE_LIST_FINISH,
DOWN_FILE,
DOWN_FILE_FINISH,
PRE_RES,
PRE_RES_FINISH,
ENTER_GAME,
}
// Start is called before the first frame update
void Start()
{
_CurState = LogoState.INIT;
Init();
_CurState = LogoState.INIT_FINISH;
}
// Update is called once per frame
void Update()
{
StartCoroutine(StartServer());
}
void Init()
{
//一开始就加载Resmanager ,初始化资源路径
_ResMgr = this.gameObject.AddComponent<ResManager>();
_ResMgr.SetBundleFolder(new string[]{"StreamingAssets"});
}
//检查更新列表
IEnumerator CheckUpdateFileList()
{
_CurState = LogoState.CHECK_UPDATE_LIST;
_SplashCom.SetDesc("检查文件更新...");
WWW www = new WWW(_ResServerHttp+_VerFileName);
yield return www;
_ServerVer = www.text;
_CurState = LogoState.CHECK_UPDATE_LIST_FINISH;
string resRootPath = ResManager.GetResPath();
if (File.Exists(resRootPath + "/" + _VerFileName))
{
StreamReader sr = new StreamReader(resRootPath + "/" + _VerFileName);
string oldVer = sr.ReadToEnd();
sr.Close();
if (www.text != oldVer)
{
//需要检查每个文件
_SplashCom.SetDesc("整理下载文件...");
www = new WWW(_ResServerHttp+_FileListName);
yield return www;
//读取包里面的资源版本信息
sr = new StreamReader(resRootPath + "/" + _FileListName);
string line = sr.ReadLine();
while (line != null)
{
string[] patt = line.Split('|');
if (patt.Length < 3)
{
continue;
}
UpdateFileInfo info = new UpdateFileInfo(patt[0].Trim(),patt[1].Trim(),int.Parse(patt[2]));
_OldDict.Add(patt[0].Trim(),info);
line = sr.ReadLine();
}
sr.Close();
yield return new WaitForEndOfFrame();
//解析服务器上的最新资源信息
string[] fileInfos = www.text.Split('\n');
foreach (var it in fileInfos)
{
string[] patt = it.Split('|');
if (patt.Length < 3)
{
continue;
}
UpdateFileInfo info = new UpdateFileInfo(patt[0].Trim(),patt[1].Trim(),int.Parse(patt[2]));
_ServerDict.Add(patt[0].Trim(),info);
}
yield return new WaitForEndOfFrame();
//做比对
Dictionary<