Unity5.x新的AssetBundle機制03——下載與使用

前言

unity_cover.png

書接上文。本節我們來講講AssetBundle的下載與使用。在第一節Unity5.x新的AssetBundle機制01——構建中,我們已經準備好了需要的AssetBundles。本節我們就來使用這些保存好的資源。

實踐

有兩種方法可以下載AssetBundles:

非緩存式。

new一個WWW對象的方式,AssetBundles不會保留在本地設備的unity緩存文件夾中。
我們使用這種方式來實踐一下。打開第一節中已經準備好的工程。新建Scripts文件夾,并在其中新建腳本:
NonCacheBundle.cs

using System;
using UnityEngine;
using System.Collections;
class NonCacheBundle : MonoBehaviour
{
    //根據平臺,得到相應的路徑
    public static readonly string BundleURL =
#if UNITY_ANDROID
        "jar:file://" + Application.dataPath + "!/assets/MyAssetBundles/shape/cube";
#elif UNITY_IPHONE
        Application.dataPath + "/Raw/MyAssetBundles/shape/cube";
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR
        //我們將加載以前打包好的cube
 "file://" + Application.dataPath + "/MyAssetBundles/shape/cube";//由于是編輯器下,我們使用這個路徑。
#else
        string.Empty;
#endif

    //還記得嗎?在cube這個AssetBundle中有兩個資源,Cube1和Cube2
    private string AssetName = "Cube1";

    IEnumerator Start()
    {
        // 從URL中下載文件,不會存儲在緩存中。
        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;
            GameObject cube = Instantiate(bundle.LoadAsset(AssetName)) as GameObject;
            cube.transform.position = new Vector3(0f, 0f, 0f);
            // 卸載加載完之后的AssetBundle,節省內存。
            bundle.Unload(false);

        }//由于使用using語法,www.Dispose將在加載完成后調用,釋放內存
    }
}

將代碼多拽到Hierarchy視口中的MainCamera物體中,運行游戲,可以看到cube1被加載到場景中。

緩存方式

使用WWW.LoadFromCacheOrDownload接口。AssetBundles將保存在本地設備的Unity的緩存文件夾中。WebPlayer 有50MB的緩存上限,PC/Mac/Android/IOS應有有4 GB的緩存上限。這種方式也是加載AssetBundle推薦的方式。我們使用這種方式來實踐一下。在Scripts文件夾中新建腳本:
CacheBundle.cs

using System;
using UnityEngine;
using System.Collections;

public class CacheBundle : MonoBehaviour
{
    public static readonly string BundleURL =
#if UNITY_ANDROID
        "jar:file://" + Application.dataPath + "!/assets/MyAssetBundles/shape/cube";
#elif UNITY_IPHONE
        Application.dataPath + "/Raw/MyAssetBundles/shape/cube";
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR
        //我們將加載以前打包好的cube
 "file://" + Application.dataPath + "/MyAssetBundles/shape/cube";//由于是編輯器下,我們使用這個路徑。
#else
        string.Empty;
#endif

    //還記得嗎?在cube這個AssetBundle中有兩個資源,Cube1和Cube2
    private string AssetName = "Cube2";

    //版本號
    public int version;

    void Start()
    {
        StartCoroutine(DownloadAndCache());
    }

    IEnumerator DownloadAndCache()
    {
        // 需要等待緩存準備好
        while (!Caching.ready)
            yield return null;

        // 有相同版本號的AssetBundle就從緩存中獲取,否則下載進緩存。
        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;
            GameObject cube = Instantiate(bundle.LoadAsset(AssetName)) as GameObject;
            cube.transform.position = new Vector3(1.5f, 0f, 0f);
            // 卸載加載完之后的AssetBundle,節省內存。
            bundle.Unload(false);

        } //由于使用using語法,www.Dispose將在加載完成后調用,釋放內存
    }
}

同樣將該腳本拖動到MainCamera中,運行游戲,可以看到Cube2被加載進場景中。這是最終運行效果:

run_assetbundle.png

當我們訪問www對象的.assetBundle屬性時,下載好的數據被解壓并創建了AssetBundle對象。此時就可以加載該AssetBundle中的所有資源。

使用異步方法

前兩個例子中,我們都使用了AssetBundle類中的LoadAsset接口,這是一個同步的方法。這里提供一個異步的示例:
LoadAsyncBundle.cs

using UnityEngine;
using System;
using System.Collections;

public class LoadAsyncBundle : MonoBehaviour
{

    //根據平臺,得到相應的路徑
    public static readonly string BundleURL =
#if UNITY_ANDROID
        "jar:file://" + Application.dataPath + "!/assets/MyAssetBundles/shape/cube";
#elif UNITY_IPHONE
        Application.dataPath + "/Raw/MyAssetBundles/shape/cube";
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR
 "file://" + Application.dataPath + "/MyAssetBundles/shape/sphere";
#else
        string.Empty;
#endif

    private string AssetName = "Sphere1";

    IEnumerator Start()
    {
        while (!Caching.ready)
            yield return null;
        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;

            // 異步加載
            AssetBundleRequest request = bundle.LoadAssetAsync(AssetName, typeof(GameObject));

            // 等待加載完成
            yield return request;

            // 獲取加載好的對象引用
            GameObject prefab = request.asset as GameObject;
            GameObject sphere = Instantiate(prefab);
            sphere.transform.position = new Vector3(0f, 1.5f, 0f);
            // 卸載加載完之后的AssetBundle,節省內存。
            bundle.Unload(false);

        }//由于使用using語法,www.Dispose將在加載完成后調用,釋放內存
    }
}

至此,Unity5中新的AssetBundle機制的使用已經大致講完啦。當然還有許多細節無法贅述,大家可以通過查看官方文檔繼續了解。有問題歡迎和我一起討論。我已經將本工程上傳到我的github,以供大家參考。請使用assetbundle這個分支。

[參考鏈接][1]http://docs.unity3d.com/Manual/DownloadingAssetBundles.html
[參考鏈接][2]http://docs.unity3d.com/Manual/LoadingAssetBundles.html


上一篇:Unity5.x新的AssetBundle機制02——壓縮

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容