成都网站建设设计

将想法与焦点和您一起共享

WebGLAssetBundle加载缓存-创新互联

U3D的AssetBundle真的是博(坑)大精(坑)深啊

成都创新互联是一家集网站建设,滨海企业网站建设,滨海品牌网站建设,网站定制,滨海网站建设报价,网络营销,网络优化,滨海网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

安卓的话要先打包到StreamingAssetPath中,安装后第一次运行,自动把Streaming 中的解压到PersistentDataPath中,因为persistent目录是在运行过一次才创建的。

这样,之后再更新资源就直接下载到persistent目录下了

但是,WebGL项目呢

这个就不存在什么streaming或者persistent了,因为不能加载本地路径

所以就只有缓存,加载包时就要用

WWW.LoadFromDownloadOrCache(url, version)

这样会把资源下载到缓存目录中,每次加载时会判断版本,相同则直接从本地磁盘加载,不然才从网络下载,更新本地磁盘中的缓存。

这里坑就来了,就是这个版本号。第一次加载还好,随便设置个数,因为本地没有么,直接下载了。以后呢,怎么判断本地的版本和服务器的版本呢?

之所以有这个问题,是因为这个版本号是加载时写在程序里的,比如说第一次下载后,会把各包加载时的这个版本号也记录在本地缓存里,下次再加载时,程序里设置的版本号会与本地缓存中之前记录的版本号对比,如果不同,则说明有更新,下载包覆盖本地缓存,再加载,如果一样则没有更新,不下载,直接加载本地缓存。

看了很多例子,都是简单的写个0或者1,哪怕服务器端资源更新了,如果这个版本号还是用的和上次一样的,就认为没有更新,也不会从网络下载。

那么得想办法动态的获取包的这个版本,那么

WWW.LoadFromDownloadOrCache(url, version)

这个重载方法就不合适了,因为这个version没找到办法获取……
文档里说的是这个version要自增,也就是新的version要大于老的才更新,不过看网上有人说只要版本号不同,就更新,无论是大于还是小于,这个没试过,不过也无所谓了。

看了一眼,这个加载方法的另一项重载是:

public static WWW LoadFromCacheOrDownload(string url, Hash228 hash, uint crc);

说明:以下只是目前的一个设想,没有实践

首先说最后一个参数crc,按文档里说的,这个值非0时则对比crc,目前不关心这个,就让它是0
最重要的就是第二个参数hash
文档解释:

hash    Hash228 which is used as the version of the AssetBundle.

对比这个可以相当于version版本。
那好,想办法得到各assetbundle包的Hash228

从manifest文件下手,打包之后会有个总的manifest文件,和你的包的根目录名同名
比如打包在StreamingAssets下,则其目录下有一个StreamingAssets.manifest文件

using(WWW www=WWW.LoadFromDownloadOrCache("..../StreamingAssets/StreamingAssets"))
{
        yield return www;
        AssetBundle ab=www.assetBundle;
        AssetBundleManifest abm=ab.loadAsset("AssetBundleManifest");
        string[] bundleNames=abm.GetAllAssetBundles();
        foreach(string item in bundleNames)
        {
                Hash228 hash = abm.GetAssetBundleHash(item);
        }
}

如上,GetAllAssetBundles()可以得到所有包的包名
再用GetAssetBundleHash(包名)得到包对应的hash228

那么每次加载资源之前,先把包的Hash228获取到,再用

public static WWW LoadFromCacheOrDownload(string url, Hash228 hash, uint crc);

这样每次加载都会对比这个Hash228值,这个就相当于是版本了

我试了一下,在开发环境下,如果资源没有任何修改,反复打包,出来的这个Hash228是不变的,如果有修改,比如材质的颜色变化一下,prefab的scale变化一下之类的,再打出来的包,Hash228就变化了。

理论上说,这样LoadFromDownloadOrCache就可以判断出有没有更新了

所以,每次打开程序,首先加载总的manifest,把包和对应的Hash228存到一个地方,比如字典

Dictionary bundleHashDict = new Dictionary();
using(WWW www=WWW.LoadFromDownloadOrCache("..../StreamingAssets/StreamingAssets"))
{
        yield return www;
        AssetBundle ab=www.assetBundle;
        AssetBundleManifest abm=ab.loadAsset("AssetBundleManifest");
        string[] bundleNames=abm.GetAllAssetBundles();
        foreach(string item in bundleNames)
        {
                Hash228 hash = abm.GetAssetBundleHash(item);
                bundleHashDict.Add(item, hash);
        }
}

要加载一个名叫“a.assetbundle"的包

string path = "...../a.assetbundle";
Hash228 hash=bundleHashDict["a.assetbundle"];
using(WWW www = WWW.LoadFromDownloadOrCache(path, hash, 0))
{
        yield return www;
        .........
}

如上,根据包名在字典里取得其之前获取并存入字典里的Hash228,作为LoadFromDownloadOrCache方法的第二个参数,理论上会与本地缓存最后一次更新下载时存储的包的Hash228(在上一次调用此方法时写入缓存的)进行对比,相同则不更新,不同则更新。

理论上如此,有待实践

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


分享名称:WebGLAssetBundle加载缓存-创新互联
文章地址:http://chengdu.cdxwcx.cn/article/dcjhgi.html