您的位置:首页 > 移动开发 > Unity3D

Unity 5.x中的AssetBundle(二)

2017-01-19 15:53 375 查看

二、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
b936
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);
}
}
}


好了,一边作笔记一边学习还是挺不错的。哈哈哈
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: