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