Unity 5.x中的AssetBundle(二)

来源:互联网 发布:java点击标签监听 编辑:程序博客网 时间:2024/04/29 19:26

二、AssetBundle下载

Unity 5.x中的AssetBundle(一)

一、Downloading AssetBundles(下载资源包)
这里有两种方式下载AssetBundles:
1、非缓存方式下载:通过创建一个WWW类对象来下载(WWW www = new WWW(url)),这种方式不会缓存到本地存储的文件中。
2、缓存方式下载:通过使用WWW.LoadFromCacheOrDownload()进行下载,这种方式会自动缓存在本地存储设备的Unity缓存文件夹中。PC/MAC独立应用程序以及IOS/Android应用程序都有4GB的大小限制。对于其他平台,可以查看相关的脚本文档。

这边直接看官方给的例子(非缓存方式下载):

using System;using UnityEngine;using System.Collections;class NonCachingLoadExample : MonoBehaviour{    public string BundleURL;    public string AssetName;    IEnumerator Start()    {        BundleURL = "file://"+Application.dataPath + "/StreamingAssets/cube";        // Download the file from the URL. It will not be saved in the Cache        using (WWW www = new WWW(BundleURL))        {            yield return www;            if (www.error != null)                throw new Exception("WWW download had an error:" + www.error);            AssetBundle bundle = www.assetBundle;            if (AssetName == "")                Instantiate(bundle.mainAsset);            else                Instantiate(bundle.LoadAsset(AssetName));            // 实例化完需要从缓存中卸载。            bundle.Unload(false);        } // 自动从Web流中释放内存(使用using()会隐式WWW.Dispose()进行释放)    }}
BundleURL = "file://"+Application.dataPath + "/StreamingAssets/cube";

这句代码是我自己添加的,这是在pc下的路径,注意要在路径前缀增加”file://”,切记。

缓存方式下载(官方推荐的使用方式)
当您访问.assetBundle属性时,将下载的数据提取并创建AssetBundle对象。 此时,您可以加载包中包含的对象。 LoadFromCacheOrDownload的第二个参数指定要下载哪个版本的AssetBundle。 如果AssetBundle不存在于缓存中或者版本低于请求,LoadFromCacheOrDownload将下载AssetBundle。 否则,AssetBundle将从缓存加载。举个例子,上一次的AssetBundle的版本号为1.0,这次的版本号为1.1,则会进行下载。

using System;using UnityEngine;using System.Collections;public class CachingLoadExample : MonoBehaviour {    public string BundleURL;    public string AssetName;    public int version;    void Start() {        BundleURL = "file://" + Application.dataPath + "/StreamingAssets/cube";        StartCoroutine (DownloadAndCache());    }    IEnumerator DownloadAndCache (){        // Wait for the Caching system to be ready        while (!Caching.ready)            yield return null;        // Load the AssetBundle file from Cache if it exists with the same version or download and store it in the cache        using(WWW www = WWW.LoadFromCacheOrDownload (BundleURL, version)){            yield return www;            if (www.error != null)                throw new Exception("WWW download had an error:" + www.error);            AssetBundle bundle = www.assetBundle;            if (AssetName == "")                Instantiate(bundle.mainAsset);            else                Instantiate(bundle.LoadAsset(AssetName));                    // Unload the AssetBundles compressed contents to conserve memory                    bundle.Unload(false);        } // memory is freed from the web stream (www.Dispose() gets called implicitly)    }}

Note:当使用WWW.LoadFromCacheOrDownload下载时,每一帧最多只有一个Assetbundle完成下载。

Assetbundle加载

AssetBundle资源包中读取资源对象,官方提供了以下三种方法:
1、Object LoadAsset(string name):这种方式是使用资源名称作为参数来加载需要的资源,还有一种重载的方法是Object LoadAsset(string name, Type type),使用type作为参数指定特定类型对象的加载。

2、Object AssetBundle.LoadAssetAsync(string name):这种方式与上述的加载方式基本一致,但是这种加载资源的方式是异步的,不会阻塞主线程。一般用在加载较大的资源或者一次性加载较多的资源时,这样会避免应用程序的卡顿。同样有一种重载方法来指定特定类型对象的加载:Object LoadAssetAsync(string name, Type type)。

3、Object[] AssetBundle.LoadAllAssets:将加载AssetBundle中包含的所有对象,也可以用重载的方法来指定特定类型的对象:Object[] LoadAllAssets(Type type)。

要从AssetBundle中卸载资源(即释放内存中资源),需要使用AssetBundle.Unload(bool unloadAllLoadedObjects)方法。这个方法包含一个bool类型的参数,告诉Unity是否卸载所有资源数据(包括从Assetbundle中加载的资源)还是只卸载从下载的Assetbundle资源包中压缩的数据。如果目前正在使用从这个AssetBundle中加载的资源,那么用AssetBundle.Unload(false)方法来卸载没用的资源数据,从而释放一定的内存;如果想要释放这个AssetBundle中所有的资源,那么可以使用AssetBundle.Unload(true)方法来销毁这个Assetbundle中所有的资源。

这个内容其实上面例子已经出现,我们可以使用LoadAssetAsync来加载资源:

    IEnumerator LoadAssetAsync()    {        while (!Caching.ready)            yield return null;        using (WWW www = WWW.LoadFromCacheOrDownload(BundleURL, 1))        {            // Wait for download to complete            yield return www;            // Load and retrieve the AssetBundle            AssetBundle bundle = www.assetBundle;            // Load the object asynchronously            AssetBundleRequest request = bundle.LoadAssetAsync("cube", typeof(GameObject));            // Wait for completion            yield return request;            // Get the reference to the loaded object            GameObject obj = request.asset as GameObject;            Instantiate(obj);            // Unload the AssetBundles compressed contents to conserve memory            bundle.Unload(false);        }    }

以上是官方文档的说明,下面是关于AssetBundle加载资源的过程:

    IEnumerator LoadAsset()    {        //首先加载总Manifest文件;            WWW wwwAll = new WWW(BundleURL+ "StreamingAssets");        yield return wwwAll;        if (!string.IsNullOrEmpty(wwwAll.error))        {            Debug.LogError(wwwAll.error);        }        else        {            AssetBundle ab = wwwAll.assetBundle;            AssetBundleManifest manifest = (AssetBundleManifest)ab.LoadAsset("AssetBundleManifest");            ab.Unload(false);            //获取依赖文件列表;                string[] depends = manifest.GetAllDependencies("cube.unity3d");            AssetBundle[] dependsAssetBundle = new AssetBundle[depends.Length];            for (int index = 0; index < depends.Length; index++)            {                //加载所有的依赖文件;                    WWW dwww = WWW.LoadFromCacheOrDownload(BundleURL + depends[index], 0);                yield return dwww;                dependsAssetBundle[index] = dwww.assetBundle;            }            //加载我们需要的文件;                WWW www = new WWW(BundleURL + "cube.unity3d");            yield return www;            if (!string.IsNullOrEmpty(www.error))            {                Debug.LogError(www.error);            }            else            {                AssetBundle assetBundle = www.assetBundle;                AssetBundleRequest request = assetBundle.LoadAssetAsync("cube", typeof(GameObject));                // Wait for completion                yield return request;                // Get the reference to the loaded object                GameObject obj = request.asset as GameObject;                Instantiate(obj);                assetBundle.Unload(false);            }            //卸载依赖文件的包                for (int index = 0; index < depends.Length; index++)            {                dependsAssetBundle[index].Unload(false);            }        }    }

好了,一边作笔记一边学习还是挺不错的。哈哈哈

0 0
原创粉丝点击