Unity对网络资源更新加载管理设计

一、诉求

对于一些文件资源(图片、word、Excel、PPT、视频等),放再程序里会增加包体的大小,所以需要把资源放在服务器。

实现的需求有:

1)从网加载资源,并保存到本地,后面就从本地加载

2)有更新机制,当网络上的资源更新后,要从新下载替换本地资源

二、思路分析

1.文件经常是分几个层级保存起来的,所以要知道某个文件夹或模块下有哪些资源文件的话,我们就需要一个配置文本,把每个层级对应的文件记录在文本中。

2.为了校验是否有更新,可以把每个文件记录一个MD5值一并保存起来。

3.加载时的大致流程如下:

三、实现

1.生成校验脚本

示例案例文件层级结构大致如下

以此做一个对象来存储文件结构信息

public class OperationFileDatas {
    public List<OperationFileData> chineseDataList = new List<OperationFileData>();
    public List<OperationFileData> englistDataList = new List<OperationFileData>();
}

public class OperationFileData
{
    public string operationName = string.Empty;
    public List<DataInfo> dataInfos = new List<DataInfo>();
}

public class DataInfo
{
    public string fileName = string.Empty;
    public string md5Str = string.Empty;
}

通过对文件夹的遍历得到数据对象,这里生成的校验码生成使用了文件大小和文件名

OperationFileDatas operationFileDatas = new OperationFileDatas();
        string[] language = new string[] { "Chinese", "English" };
        for (int m = 0; m < language.Length; m++)
        {
            DirectoryInfo operationInfo = new DirectoryInfo(GMConfig.streamAssetFilePath + language[m]);
            DirectoryInfo[] operationDirList = operationInfo.GetDirectories();
            for (int i = 0; i < operationDirList.Length; i++)
            {
                OperationFileData operationFileData = new OperationFileData();
                operationFileData.operationName = operationDirList[i].Name;

                Debug.Log(operationDirList[i].Name);
                string[] filePathList = Directory.GetFiles(operationDirList[i].FullName);

                if (filePathList.Length > 0)
                {
                    for (int j = 0; j < filePathList.Length; j++)
                    {
                        DataInfo dataInfo = new DataInfo();
                        string fileName = filePathList[j].Substring(filePathList[j].LastIndexOf("\\") + 1);
                        if (Path.GetExtension(fileName).Equals(".meta"))
                        {
                            continue;
                        }
                        dataInfo.fileName = fileName;
                        byte[] fuleByt = File.ReadAllBytes(filePathList[m]);
                        Debug.Log(fileName + "    " + fuleByt.Length);
                        dataInfo.md5Str = GMMD5Creater.EncryptDES(fileName + fuleByt.Length.ToString());
                        
                        operationFileData.dataInfos.Add(dataInfo);
                    }
                }

                if (language[m].Equals("Chinese"))
                {
                    operationFileDatas.chineseDataList.Add(operationFileData);
                }
                else
                {
                    operationFileDatas.englistDataList.Add(operationFileData);
                }
            }
        }

把对象数据转为文本

JsonConvert.SerializeObject(operationFileDatas)

这个使用到了Newtonsoft.Json    下载链接:https://download.csdn.net/download/YasinXin/12533117

最后把文本保存起来

    static void ExportIndexFile(string json, string fileName, string savepath)
    {
        if (!json.Equals(string.Empty))
        {
            if (!Directory.Exists(savepath))
            {
                Directory.CreateDirectory(savepath);
            }
            savepath += fileName;
            FileStream fs = new FileStream(savepath, FileMode.Create);
            byte[] bytes = new UTF8Encoding().GetBytes(json);
            //写入会把文本清空写入bytes内容
            fs.Write(bytes, 0, bytes.Length);

            fs.Close();
        }
        else
            MessageBoxes.NoAssetsFound();
        AssetDatabase.Refresh();
    }

这样校验文本就生成好了,局部效果如下

2.加载资源

通过配置文本的到每个模块下有哪些资源,再拼成路径逐个加载,加载的方法参上面的流程图。

网络加载及进度显示

 UnityWebRequest request = UnityWebRequest.Get(webPath);

        request.SendWebRequest();//开始请求
        while (!request.isDone)
        {
            Debug.Log(Math.Floor(request.downloadProgress * 100) + "%");
            yield return 1;
        }
        if (request.isDone)
        {
            Debug.Log(100 + "%");
        }

        if (request.isNetworkError || request.isHttpError)
        {
            UnityEngine.Debug.LogError(webPath);
            UnityEngine.Debug.LogError(request.error);

        }
        else
        {
            var file = request.downloadHandler.data;
            //加载成功的逻辑处理
            ...

            yield break;
        }

这里的几种文件都可以先下载到本地再读取,视频也可以直接用流媒体方式播放。

在Unity中打开其它文件,如:Excel、Word、PPT等可以使用

Process.Start(url);

由于每次遇到的文件资源都不一样,所以具体的细节就不展开讲了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章