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

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