通過把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