git地址:https://github.com/stallboy/unityresupdater
基本流程作者在git上都写了,但是写的有点简洁也没有个使用的例子然后自己根据作者的描述画了一下流程图:
使用:
1.需要实现一下ResUpdater这个接口
2.创建一个Mono测试
3.编写res.md5生成器来生成.md5文件来验证资源
//Reporter接口实现类
using System;
using System.Collections.Generic;
using System.Diagnostics;
using ResUpdater;
using Debug = UnityEngine.Debug;
namespace Assets
{
public class ReporterImpl:Reporter
{
public void DownloadLatestVersionErr(Exception err)
{
Debug.Log($"err :{err}");
/*
$"{}"需要unity2017版本,5.x,4.x不支持
还需要在unity2017中把Scripting Backend修改为.Net4.6
*/
}
public void ReadVersionErr(Loc loc, string wwwErr, Exception parseErr)
{
Debug.Log($" wwwErr{wwwErr}, parseErr{parseErr}");
}
public void CheckVersionDone(State nextState, int localVersion, int latestVersion)
{
Debug.Log($"nextState :{nextState}, localVersion{localVersion}, latestVersion{latestVersion}");
}
public void DownloadLatestMd5Err(Exception err)
{
Debug.Log($"err :{err}");
}
public void ReadMd5Err(Loc loc, string wwwwErr, Exception parseErr)
{
Debug.Log($"loc :{loc}, wwwErr{wwwwErr}, parseErr{parseErr}");
}
public void CheckMd5Done(State nextState, Dictionary<string, CheckMd5State.Info> downloadList)
{
Debug.Log($" nextStatenextState{nextState}, downloadList{downloadList}");
}
public void DownloadOneResComplete(Exception err, string fn, CheckMd5State.Info info)
{
Debug.Log($"err :{err}, fn{fn}, info{info}");
}
public void DownloadResDone(State nextState, int errCount)
{
Debug.Log($"nextState :{nextState}, errCount{errCount}");
}
}
}
//测试类
using System.Collections;
using Assets;
using ResUpdater;
using UnityEngine;
public class Test : MonoBehaviour
{
public string[] HostStrings;
public int te;
private Reporter _reporter = new ReporterImpl();
// Use this for initialization
void Start()
{
var re = new ResUpdater.ResUpdater(HostStrings, te, _reporter, cor);
re.Start();
}
private Coroutine cor(IEnumerator routine)
{
Debug.Log("test");
return null;
}
// Update is called once per frame
void Update () {
}
}
上面2个有了也就可以测试了,但是还缺少了一个文件生成类.
//文件生成类
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using JetBrains.Annotations;
using ResUpdater;
using UnityEditor;
using UnityEngine;
namespace Res
{
class ResCreate : EditorWindow
{
[MenuItem("生成/Res.md5")]
///生成res.md5文件
static void Create()
{
isCreate = false;
ShowWindow();
}
#region window窗口
public static void ShowWindow()
{
EditorWindow.GetWindow(typeof(ResCreate));
}
public static void CloseWindow()
{
EditorWindow.GetWindow(typeof(ResCreate)).Close();
}
#endregion
static bool isCreate = false;
#region GUI绘制
void OnGUI()
{
if (GUI.Button(new Rect(new Vector2(2, 10), new Vector2(70, 20)), "选择需要生成的文件夹"))
{
_folderPath = EditorUtility.OpenFolderPanel("选择一个根目录", null, null);
}
GUI.Label(new Rect(new Vector2(75, 10), new Vector2(600, 30)), _folderPath);
GUI.Label(new Rect(new Vector2(2, 30), new Vector2(100, 30)), "输入根目录:");
_root = GUI.TextArea(new Rect(new Vector2(70, 30), new Vector2(100, 30)), _root);
if (GUI.Button(new Rect(new Vector2(20, 100), new Vector2(70, 20)), "生成"))
{
CreateStart();
Save();
}
if (isCreate)
{
GUI.Label(new Rect(new Vector2(2, 130), new Vector2(150, 30)), "生成成功,路径在控制台");
}
}
#endregion
#region 执行开始
void CreateStart()
{
_resSb.Remove(0,_resSb.Length);
GetFileInfo();
ListFiles(_fileInfo);
_resSb.Remove(_resSb.Length - 1, 1);
Debug.Log(_resSb.ToString());
}
#endregion
string _root = "Asses";
string _folderPath;
DirectoryInfo _fileInfo;
void GetFileInfo()
{
_fileInfo = new DirectoryInfo(_folderPath);
}
StringBuilder _resSb = new StringBuilder();
#region 遍历所选文件夹内的所有文件
void ListFiles(FileSystemInfo info)
{
DirectoryInfo dir = info as DirectoryInfo;
//不是目录
if (dir == null) return;
FileSystemInfo[] files = dir.GetFileSystemInfos();
for (int i = 0; i < files.Length; i++)
{
FileInfo file = files[i] as FileInfo;
//是文件
if (file != null)
{
Debug.Log($"文件名:{file.FullName} 文件大小:{file.Length},文件路径:{GetFile(file.ToString())}");
MD5Calculate(file);
}
else
//对于子目录,进行递归调用
ListFiles(files[i]);
}
}
#endregion
#region 文件信息生成
void MD5Calculate(FileInfo file)
{
_resSb.Append(GetFile(file.ToString())+" ");
_resSb.Append(Util.getMD5(file.ToString())+" ");
_resSb.Append(file.Length);
_resSb.Append("\n");
}
#endregion
#region 路径切割
string GetFile(string path)
{
if (path.Contains(_root))
{
// Debug.Log(path.Length);
path = path.Substring(
path.IndexOf(_root, StringComparison.Ordinal) + _root.Length+1,
path.Length - (path.IndexOf(_root, StringComparison.Ordinal) + _root.Length+1)
);
// Debug.Log (path+""+ _root.Length);
}
return path;
}
#endregion
#region 保存文件
void Save()
{
string path;
try
{
path = EditorUtility.SaveFilePanel("保存生成的文件",null, "res","md5");
Debug.Log($"保存路径:{path}");
Md5Write(path);
}
catch (System.ArgumentException e)
{
Debug.Log("取消保存:" + e);
}
catch (System.Exception e) {
Debug.Log("错误:" + e);
}
}
void Md5Write(string jsonPath)
{
StreamWriter st = new StreamWriter(jsonPath);
string json = _resSb.ToString();
st.Write(json);
st.Close();
isCreate = true;
}
#endregion
}
}
//Util类
public static string getMD5(string filePath)
{
try
{
FileStream file = new FileStream(filePath, FileMode.Open);
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
int len = (int)file.Length;
byte[] data = new byte[len];
file.Read(data, 0, len);
file.Close();
byte[] result = md5.ComputeHash(data);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
sb.Append(Convert.ToString(result[i],16));
}
return sb.ToString();
}
catch (Exception)
{
throw;
}
}
然后貌似还有一个.version文件没弄,还在研究