二、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);
}
}
}
好了,一边作笔记一边学习还是挺不错的。哈哈哈