Unity资源热更新

通过把StreamingAssets文件夹下的本地的资源MD5列表文件复制到persistentDataPath文件夹下和服务器上的进行对比,把有变化的资源更新替换到本地persistentDataPath文件夹,游戏在开始的时候,直接检查更新加载相应的资源。

StreamingAssets文件夹,可读,不可写,通过使用UnityWebRequest加载该文件夹下资源,其他方式无法加载里面的资源。

1.首先将StreamingAssets文件夹下资源复制到持久化路径里面。先加载出来,再通过FileStream类将数据写进去。

 UnityWebRequest www = UnityWebRequest.Get(path);
        yield return www.SendWebRequest();
        
            FileStream stream = new FileStream(newPath, FileMode.Create);

            stream.Write(www.downloadHandler.data, 0, www.downloadHandler.data.Length);
            //释放相关资源
            stream.Flush();
            stream.Close();
        }

2.游戏开始的时候,加载本地配置表和服务器上的作对比

public void CheckUpdate()
    {
        LOCAL_RES_PATH = "file:///" + Application.persistentDataPath + "/AssetBundles";
        LOCAL_RES_URL = "file:///" + Application.persistentDataPath + "/AssetBundles";
        Debug.Log("Checking Version Update......");     
        LocalResVersion = new Dictionary<string, string>();
        ServerResVersion = new Dictionary<string, string>();
        NeedDownFiles = new List<string>();

        StartCoroutine(LoadFile(LOCAL_RES_URL + VERSION_FILE, delegate (UnityWebRequest localVersion)
        {
            Debug.Log("Loading Local VersionFile...");
            ParseVersionFile(localVersion.downloadHandler.text, LocalResVersion);
            StartCoroutine(this.LoadFile(SERVER_RES_URL + VERSION_FILE, delegate (UnityWebRequest serverVersion)
            {
                Debug.Log("Loading Server VersionFile...");
                ParseVersionFile(serverVersion.downloadHandler.text, ServerResVersion);
                Debug.Log("File Comparison...");
                CompareVersion();
                DownLoadRes();
            }));

        }));
    }

这里在访问本地持久化路径的时候,一定要加上file前缀,不然不能正确的加载。

2.通过对比,分析需要从服务器更新的资源。

 foreach (var version in ServerResVersion)
        {
            string fileName = version.Key;
            string serverMd5 = version.Value;           
            if (!LocalResVersion.ContainsKey(fileName))
            {
                NeedDownFiles.Add(fileName);
            }
            else
            {              
                string localMd5;
                LocalResVersion.TryGetValue(fileName, out localMd5);
                if (!serverMd5.Equals(localMd5))
                {
                    NeedDownFiles.Add(fileName);
                }
            }
        }
        NeedUpdateLocalVersionFile = NeedDownFiles.Count > 0;

3.依次加载服务器上的资源,同时替换本地资源

 private void DownLoadRes()
    {
        if (NeedDownFiles.Count == 0)
        {
            Debug.Log("Version Update Finish!!!");
            UpdateLocalVersionFile();
            UpdateComplete = true;
            return;
        }
        Debug.Log("DownLoading need Update File...");
        string file = NeedDownFiles[0];
        NeedDownFiles.RemoveAt(0);

        StartCoroutine(this.LoadFile(SERVER_RES_URL + file, delegate (UnityWebRequest w)
        {
            //替换本地的资源
            ReplaceLocalRes(file, w.downloadHandler.data);
            DownLoadRes();
        }));
    }


 private void ReplaceLocalRes(string fileName, byte[] data)
    {
        string filePath = LOCAL_RES_PATH + fileName;
        FileStream stream = new FileStream(Application.persistentDataPath+"/AssetBundles"+fileName, FileMode.Create);

        stream.Write(data, 0, data.Length);
        stream.Flush();
        stream.Close();
    }

4.等资源更新完毕,更新本地资源配置表,方便下次更新与服务器对比

  FileStream stream = new FileStream(Application.persistentDataPath+"/AssetBundles" + VERSION_FILE, FileMode.Create);
            byte[] data = Encoding.UTF8.GetBytes(versions.ToString());
            stream.Write(data, 0, data.Length);
            stream.Flush();
            stream.Close();
            Debug.Log("LocalFile Update  Finished!!!");

到这一步,基本上资源的更新就完毕了。

打包测试:遇到各种坑,因为在模拟器上测试,localhost 、127.0.0.1无法使用,出现UnknownError

后来有人说把地址换成10.0.2.2,就行了,但是因为使用的是夜神模拟器,换过之后还是不行,又换成了蓝叠,腾讯手游,网易mumu,测试通过,可以访问本地localhost,真的是恶心啊。

打AB的时候,demo之前在pc上测试是没有问题的,打包选项选的是Windows,然而我个笨蛋,在安卓模拟器上测试的时候,打包选项忘记改了,测试的时候,一直加载的是空的AB包,困扰了两天,路径也对,PC测试也没问题,咋就是NULLAB包,最后准备再次在PC上测试的时候,才发现打包选项忘记更改了。。。。WTF!!!

更改打包选项之后,测试正常。

之后再写一个代码逻辑的更新,使用XLua

发布了76 篇原创文章 · 获赞 43 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/hnzmdlhc/article/details/89436716