您好,登錄后才能下訂單哦!
U3D的AssetBundle真的是博(坑)大精(坑)深啊
安卓的話要先打包到StreamingAssetPath中,安裝后第一次運(yùn)行,自動(dòng)把Streaming 中的解壓到PersistentDataPath中,因?yàn)閜ersistent目錄是在運(yùn)行過一次才創(chuàng)建的。
這樣,之后再更新資源就直接下載到persistent目錄下了
但是,WebGL項(xiàng)目呢
這個(gè)就不存在什么streaming或者persistent了,因?yàn)椴荒芗虞d本地路徑
所以就只有緩存,加載包時(shí)就要用
WWW.LoadFromDownloadOrCache(url, version)
這樣會(huì)把資源下載到緩存目錄中,每次加載時(shí)會(huì)判斷版本,相同則直接從本地磁盤加載,不然才從網(wǎng)絡(luò)下載,更新本地磁盤中的緩存。
這里坑就來了,就是這個(gè)版本號(hào)。第一次加載還好,隨便設(shè)置個(gè)數(shù),因?yàn)楸镜貨]有么,直接下載了。以后呢,怎么判斷本地的版本和服務(wù)器的版本呢?
之所以有這個(gè)問題,是因?yàn)檫@個(gè)版本號(hào)是加載時(shí)寫在程序里的,比如說第一次下載后,會(huì)把各包加載時(shí)的這個(gè)版本號(hào)也記錄在本地緩存里,下次再加載時(shí),程序里設(shè)置的版本號(hào)會(huì)與本地緩存中之前記錄的版本號(hào)對(duì)比,如果不同,則說明有更新,下載包覆蓋本地緩存,再加載,如果一樣則沒有更新,不下載,直接加載本地緩存。
看了很多例子,都是簡單的寫個(gè)0或者1,哪怕服務(wù)器端資源更新了,如果這個(gè)版本號(hào)還是用的和上次一樣的,就認(rèn)為沒有更新,也不會(huì)從網(wǎng)絡(luò)下載。
那么得想辦法動(dòng)態(tài)的獲取包的這個(gè)版本,那么
WWW.LoadFromDownloadOrCache(url, version)
這個(gè)重載方法就不合適了,因?yàn)檫@個(gè)version沒找到辦法獲取……
文檔里說的是這個(gè)version要自增,也就是新的version要大于老的才更新,不過看網(wǎng)上有人說只要版本號(hào)不同,就更新,無論是大于還是小于,這個(gè)沒試過,不過也無所謂了。
看了一眼,這個(gè)加載方法的另一項(xiàng)重載是:
public static WWW LoadFromCacheOrDownload(string url, Hash228 hash, uint crc);
說明:以下只是目前的一個(gè)設(shè)想,沒有實(shí)踐
首先說最后一個(gè)參數(shù)crc,按文檔里說的,這個(gè)值非0時(shí)則對(duì)比crc,目前不關(guān)心這個(gè),就讓它是0
最重要的就是第二個(gè)參數(shù)hash
文檔解釋:
hash Hash228 which is used as the version of the AssetBundle.
對(duì)比這個(gè)可以相當(dāng)于version版本。
那好,想辦法得到各assetbundle包的Hash228
從manifest文件下手,打包之后會(huì)有個(gè)總的manifest文件,和你的包的根目錄名同名
比如打包在StreamingAssets下,則其目錄下有一個(gè)StreamingAssets.manifest文件
using(WWW www=WWW.LoadFromDownloadOrCache("..../StreamingAssets/StreamingAssets"))
{
yield return www;
AssetBundle ab=www.assetBundle;
AssetBundleManifest abm=ab.loadAsset<AssetBundleManifest>("AssetBundleManifest");
string[] bundleNames=abm.GetAllAssetBundles();
foreach(string item in bundleNames)
{
Hash228 hash = abm.GetAssetBundleHash(item);
}
}
如上,GetAllAssetBundles()可以得到所有包的包名
再用GetAssetBundleHash(包名)得到包對(duì)應(yīng)的hash228
那么每次加載資源之前,先把包的Hash228獲取到,再用
public static WWW LoadFromCacheOrDownload(string url, Hash228 hash, uint crc);
這樣每次加載都會(huì)對(duì)比這個(gè)Hash228值,這個(gè)就相當(dāng)于是版本了
我試了一下,在開發(fā)環(huán)境下,如果資源沒有任何修改,反復(fù)打包,出來的這個(gè)Hash228是不變的,如果有修改,比如材質(zhì)的顏色變化一下,prefab的scale變化一下之類的,再打出來的包,Hash228就變化了。
理論上說,這樣LoadFromDownloadOrCache就可以判斷出有沒有更新了
所以,每次打開程序,首先加載總的manifest,把包和對(duì)應(yīng)的Hash228存到一個(gè)地方,比如字典
Dictionary<string, Hash228> bundleHashDict = new Dictionary<string, Hash228>();
using(WWW www=WWW.LoadFromDownloadOrCache("..../StreamingAssets/StreamingAssets"))
{
yield return www;
AssetBundle ab=www.assetBundle;
AssetBundleManifest abm=ab.loadAsset<AssetBundleManifest>("AssetBundleManifest");
string[] bundleNames=abm.GetAllAssetBundles();
foreach(string item in bundleNames)
{
Hash228 hash = abm.GetAssetBundleHash(item);
bundleHashDict.Add(item, hash);
}
}
要加載一個(gè)名叫“a.assetbundle"的包
string path = "...../a.assetbundle";
Hash228 hash=bundleHashDict["a.assetbundle"];
using(WWW www = WWW.LoadFromDownloadOrCache(path, hash, 0))
{
yield return www;
.........
}
如上,根據(jù)包名在字典里取得其之前獲取并存入字典里的Hash228,作為LoadFromDownloadOrCache方法的第二個(gè)參數(shù),理論上會(huì)與本地緩存最后一次更新下載時(shí)存儲(chǔ)的包的Hash228(在上一次調(diào)用此方法時(shí)寫入緩存的)進(jìn)行對(duì)比,相同則不更新,不同則更新。
理論上如此,有待實(shí)踐
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。