流程如下,直接上图
1,我们首先要知道我们需要是否第一次安装,如果是那则直接从服务器下载配置文件和本地配置文件对比,进行资源更新。第一次安装本地是没有配置文件的,所以就相当于把服务器所列出的所有资源全部下载。
生成配置文件
using System.IO;
using System.Security.Cryptography;
using System.Text;
using UnityEditor;
using UnityEngine;
public class MD5ConfigurationFileGeneration : Editor
{
[MenuItem("QFramework/生成配置文件,位于StreamingAssets")]
public static void CreateResFileMd5()
{
MD5InfoData fmd5 = new MD5InfoData();
DirectoryInfo root = new DirectoryInfo(Application.streamingAssetsPath);
FileInfo[] files = root.GetFiles("*", SearchOption.AllDirectories);
foreach (var f in files)
{
//排除.meta文件
if (f.Name.EndsWith(".meta"))
{
continue;
}
// if (f.Name.Contains("翻译静态数据"))
// {
//Debug.Log(f.DirectoryName);
string md5 = GetMd5HashFromFile(f.DirectoryName + "/" + f.Name);
//Debug.Log(f.Name + "的Md5 = " + md5);
Md5Info info = new Md5Info(f.Name, md5);
fmd5.md5Info.Add(info);
// }
}
//存储Json到本地
MD5InfoData.SaveData(Application.streamingAssetsPath + "/md5.json", fmd5);
AssetDatabase.Refresh();
}
static string GetMd5HashFromFile(string filePath)
{
FileStream fs = new FileStream(filePath, FileMode.Open);
MD5 md5 = new MD5CryptoServiceProvider();
byte[] hash = md5.ComputeHash(fs);
fs.Close();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("x2"));
}
return sb.ToString().ToUpper();
}
}
2,对比配置文件并保存需要下载的文件列表,启动下载器,下载全部完成再更新配置文件,不要提前更新配置文件,避免文件更新完缺导致我们要下载的东西没下载完。
这是一个下载的管理器
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class UnityWebMgr
{
private static UnityWebMgr minstance;
public static UnityWebMgr Instance
{
get
{
if (minstance == null)
{
minstance = new UnityWebMgr();
}
return minstance;
}
}
public UnityWebMgr()
{
}
private List<UnityWeb> unityWebs = new List<UnityWeb>();
public void AddLoadFile(string songId,string url)
{
CreateWeb(songId, url);
}
private void CreateWeb(string songId, string url)
{
UnityWeb unityWeb = new UnityWeb(songId, url);
unityWebs.Add(unityWeb);
}
public UnityWeb ToLoadFile()
{
if (unityWebs.Count <= 0)
{
return null;
}
UnityWeb uw = unityWebs[0];
unityWebs.RemoveAt(0);
return uw;
}
}
public class UnityWeb
{
public UnityWebRequest request;
public string SongId { get; private set; }
public string Url { get; private set; }
public UnityWeb(string songId,string url){
request = UnityWebRequest.Get(url);
SongId = songId;
Url = url;
}
public float GetDownloadProgress()
{
if (request == null)
{
return 0;
}
if (request.isDone)
{
return 1;
}
else if (request.isNetworkError)
{
return 0;
}
else
{
return request.downloadProgress;
}
}
}
启动下载
using LXLModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using static System.Collections.Specialized.BitVector32;
public class DownAB
{
#if UNITY_EDITOR_WIN
string path = Application.streamingAssetsPath;
string serverPath = "http://192.168.17.6:8888/AssetBundles/iOS/";
#elif UNITY_EDITOR
string path = Application.streamingAssetsPath;
string serverPath = "http://192.168.17.6:8888/AssetBundles/iOS/";
#else
string path = Application.persistentDataPath;
string serverPath = "http://192.168.17.6:8888/AssetBundles/iOS/";
#endif
// Start is called before the first frame update
public DownAB()
{
EventCenter.AddListener<Action>(EventTable.StartDownAB, StartDownAB);
}
void StartDownAB(Action action) {
Debug.LogError("执行下载");
new Task(DownloadAndSave("http://192.168.17.6:8888", "md5.txt", (string str,string newJson,string oldJson,byte[] be)=> {
Debug.LogError(str+"下载成功");
if (newJson.Equals(oldJson))
{
Debug.LogError("无需更新");
action();
}
else
{
MD5InfoData nmi = JsonUtility.FromJson<MD5InfoData>(newJson);
MD5InfoData omi;
if (string.IsNullOrEmpty(oldJson))
{
omi = new MD5InfoData();
omi.md5Info = new List<Md5Info>();
}
else
{
omi = JsonUtility.FromJson<MD5InfoData>(oldJson);
}
Dictionary<string, string> ndi = new Dictionary<string, string>();
Dictionary<string,string> odi = new Dictionary<string,string>();
foreach (var v in nmi.md5Info)
{
ndi.Add(v.name,v.md5);
}
foreach (var v in omi.md5Info)
{
odi.Add(v.name,v.md5);
}
foreach(var v in ndi)
{
int num = 1;
if (odi.ContainsKey(v.Key))
{
if (odi[v.Key].Equals(v.Value))
{
continue;
}
else
{
UnityWebMgr.Instance.AddLoadFile(v.Key,serverPath + v.Key);
}
}
else
{
UnityWebMgr.Instance.AddLoadFile(v.Key, serverPath + v.Key);
}
}
//开始下载
new Task(DownloadAndSave(()=> { SaveAssets(path, "md5.txt", be);action(); }));
}
}));
}
public IEnumerator DownloadAndSave(string str,string name,Action<string,string,string,byte[]> action)
{
UnityWebRequest www = UnityWebRequest.Get(str+"/"+name);
//StartCoroutine(ShowDownProgress(www));
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
yield break;
}
Debug.Log("下载成功:"+www.isDone+www.downloadHandler.text);
bool b = false;
byte[] bytes = www.downloadHandler.data;
Debug.Log("是否有配置文件:" + www.isDone + www.downloadHandler.text);
yield return new WaitForFixedUpdate();
Debug.Log("是否有文件:"+ new FileInfo(path + "/" + name).Exists);
if (new FileInfo(path + "/" + name).Exists)
{
Debug.Log("是有文件:");
string st = "";
#if UNITY_IOS
st = "file:///";
#endif
//Debug.Log("文件链接:"+ st + path + "/" + name);
//UnityWebRequest w = UnityWebRequest.Get(st+path + "/" + name);
// new Task(ShowDownProgress(w));
//w.SendWebRequest();
//if (w.downloadHandler.isDone)//是否读取完数据
//{
// action("配置文件", www.downloadHandler.text, w.downloadHandler.text, bytes);
//}
Debug.Log("文件链接:" + path + "/" + name);
// UnityWebRequest w = UnityWebRequest.Get(st+path + "/" + name);
// new Task(ShowDownProgress(w));
//w.SendWebRequest();
FileStream fs = new FileStream( path + "/" + name, FileMode.Open, FileAccess.Read, FileShare.Read);//找到指定路径的文件,打开,读取;using自动释放资源并且关闭
StreamReader sr = new StreamReader(fs, Encoding.Default);
//Console.WriteLine(sr.ReadLine());//读取指定路径下文件的一行字符
//Console.WriteLine(sr.ReadToEnd());//读取指定路径下文件中所有内容
action("配置文件", www.downloadHandler.text, sr.ReadToEnd(), bytes);
}
else
{
action("配置文件", www.downloadHandler.text,"", bytes);
}
}
static IEnumerator ShowDownProgress(UnityWebRequest www)
{
while (!www.downloadHandler.isDone)
{
Debug.Log(www.downloadProgress);
yield return new WaitForEndOfFrame();
}
}
///
/// 下载并保存资源到本地
///
///
///
///
public IEnumerator DownloadAndSave(Action action)
{
UnityWeb uwb = UnityWebMgr.Instance.ToLoadFile();
if (uwb == null)
{
if (action != null)
{
action();
}
Debug.Log("下载完成");
yield break;
}
UnityWebRequest www = uwb.request;
if (www == null)
{
Debug.Log("下载完成");
yield break;
}
www.downloadHandler = new DownloadHandlerBuffer();
new Task(ShowDownProgress(www));
yield return www.SendWebRequest();
Debug.Log("执行下载进度?");
if (www.isHttpError || www.isNetworkError)
{
yield break;
}
while (!www.isDone)
{
yield return 0;
}
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
yield break;
}
string Loading = string.Empty;
Debug.Log(www.downloadHandler.isDone);
bool b = false;
Loading = "100%";
byte[] bytes = www.downloadHandler.data;
b = SaveAssets(path+ "/AssetBundles/IOS", uwb.SongId, bytes);
yield return new WaitForFixedUpdate();
new Task(DownloadAndSave(action));
}
///
/// 保存资源到本地
///
///
///
///
///
public static bool SaveAssets(string path, string name, byte[] bytes)
{
Stream sw;
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
FileInfo t = new FileInfo(path + "/" + name);
Debug.Log(t.Exists+t.FullName);
if (!t.Exists)
{
try
{
sw = t.Create();
sw.Write(bytes, 0, bytes.Length);
sw.Close();
sw.Dispose();
return true;
}
catch
{
return false;
}
}
else
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
else
{
File.Delete(path + "/" + name);
}
SaveAssets(path, name, bytes);
return true;
}
}
//md5加密
private static string CalcMD5(string str)
{
byte[] buffer = Encoding.UTF8.GetBytes(str);
using (MD5 md5 = MD5.Create())
{
byte[] md5Bytes = md5.ComputeHash(buffer);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < md5Bytes.Length; i++)
{
sb.Append(md5Bytes[i].ToString("x2"));//X2时,生成字母大写MD5
}
return sb.ToString();
}
}
//获取文件大小
private static long AbLength(string path, string name)
{
DirectoryInfo di = new DirectoryInfo(path);
FileInfo[] fiArr = di.GetFiles();
for (int i = 0; i < fiArr.Length; i++)
{
if (fiArr[i].Name.Equals(name))
{
return fiArr[i].Length;
}
}
return 0;
}
}
下载需要自己搭建个本地服务器,ip地址自己改下。
下载下来之后就可以加载了。