Unity之更新资源(手动造轮子)

19 篇文章 0 订阅
10 篇文章 0 订阅

流程如下,直接上图
更新流程图
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();
        }
    }

    /// <summary>

    /// 下载并保存资源到本地

    /// </summary>

    /// <param name="url"></param>

    /// <param name="name"></param>

    /// <returns></returns>

    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));

    }

    /// <summary>

    /// 保存资源到本地

    /// </summary>

    /// <param name="path"></param>

    /// <param name="name"></param>

    /// <param name="info"></param>

    /// <param name="length"></param>

    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地址自己改下。
下载下来之后就可以加载了。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值