Unity 5.x中的AssetBundle(二)

二、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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值