前言
書接上文。本節我們來講講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被加載進場景中。這是最終運行效果:
當我們訪問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