Unity5.4 Assetbundles官方说明六(保留下载的AssetBundle)

转载请注明出处!

  Unity只允许AssetBundle在程序中实例化一次,如果之前一个AssetBundle从WWW加载出来并没有释放(Unload),那么就不能再次加载同一个AssetBundle,例如我们已经通过以下脚本获取了AssetBundle资源包对象:
AssetBundle bundle = www.assetBundle;

然后在这个资源包没有释放的情况下,又通过这个脚本获取同一个资源包对象,那么第二次返回的bundle值会是null,而且将会抛出以下错误:
Cannot load cached AssetBundle. A file of the same name is already loaded from another AssetBundle

这就要求当我们加载了一次资源包,在卸载前就不能再次加载。在此建议:一旦资源包中需要的资源被加载完成,就立马卸释放掉AssetBundle。
注意:在Unity5之前的版本中,任何AssetBundle资源包被卸载前需要完成资源包的加载才行,即只有加载完资源包才能对其释放。因此当某些资源包正在加载的时候调用AssetBundle.Unload()方法释放资源,这样会阻塞下面脚本代码的执行,直到所有的资源包加载完为止,这样会导致程序运行时卡顿。不过在Unity5的版本中,这个问题已被修改。

如果想保持下载的AssetBundle资源包,可以用如下的类来管理下载的数据,可直接复制到项目中:
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

static public class AssetBundleManager
{
/// <summary>
/// 保存AssetBundle资源包引用的容器,其中key值是下载地址+版本号的组合,value值是AssetBundleRef类数据
/// </summary>
static private Dictionary<string, AssetBundleRef> dictAssetBundleRefs;
static AssetBundleManager()
{
dictAssetBundleRefs = new Dictionary<string, AssetBundleRef>();
}

/// <summary>
/// 包含AssetBundle引用的类,其中包括url地址和version版本号
/// </summary>
private class AssetBundleRef
{
public AssetBundle assetBundle = null; //资源包
public int version; //版本号
public string url; //下载地址
public AssetBundleRef(string strUrlIn, int intVersionIn)
{
url = strUrlIn;
version = intVersionIn;
}
};
/// <summary>
/// 从保存的容器中获取资源包
/// </summary>
/// <param name="url">下载地址</param>
/// <param name="version">版本号</param>
/// <returns>返回获取的资源包</returns>
public static AssetBundle getAssetBundle(string url, int version)
{
string keyName = url + version.ToString();
AssetBundleRef abRef;
if (dictAssetBundleRefs.TryGetValue(keyName, out abRef)) //将空的abRef传递进去
return abRef.assetBundle;
else
return null;
}
/// <summary>
/// 下载AssetBundle资源包
/// </summary>
/// <param name="url">下载地址</param>
/// <param name="version">版本号</param>
/// <returns>返回下载的资源包</returns>
public static IEnumerator downloadAssetBundle(string url, int version)
{
string keyName = url + version.ToString();
if (dictAssetBundleRefs.ContainsKey(keyName))
yield return null;
else
{
while (!Caching.ready)
yield return null;

using (WWW www = WWW.LoadFromCacheOrDownload(url, version)) //异步方式加载
{
yield return www;
if (www.error != null)
throw new Exception("WWW download:" + www.error);
AssetBundleRef abRef = new AssetBundleRef(url, version);
abRef.assetBundle = www.assetBundle;
dictAssetBundleRefs.Add(keyName, abRef);
}
}
}
/// <summary>
/// 删除容器中保存的资源数据
/// </summary>
/// <param name="url">路径地址</param>
/// <param name="version">版本号</param>
/// <param name="allObjects">表示是否删除资源包的所有资源</param>
public static void Unload(string url, int version, bool allObjects)
{
string keyName = url + version.ToString();
AssetBundleRef abRef;
if (dictAssetBundleRefs.TryGetValue(keyName, out abRef))
{
abRef.assetBundle.Unload(allObjects);
abRef.assetBundle = null;
dictAssetBundleRefs.Remove(keyName);
}
}
}


在此列举一个例子来使用上面管理Assetbundle的类:
using UnityEditor;

class ManagedAssetBundleExample : MonoBehaviour {
public string url;    //地址路径
public int version;    //版本号
AssetBundle bundle; 
void OnGUI (){
if (GUILayout.Label ("Download bundle"){
bundle = AssetBundleManager.getAssetBundle (url, version);
if(!bundle)
StartCoroutine (DownloadAB());
}
}
IEnumerator DownloadAB (){
yield return StartCoroutine(AssetBundleManager.downloadAssetBundle (url, version));
bundle = AssetBundleManager.getAssetBundle (url, version);
}
void OnDisable (){    //当脚本执行时调用
AssetBundleManager.Unload (url, version, true);
}
}

注意:上面例子中的AssetBundleManager类是静态的,当加载一个新的场景时,引用的类中任何资源包信息都不会被销毁。
  我将在第十一篇中给出完整的项目源码(包括资源的打包、下载资源包、加载资源包、获取资源几依赖资源、使用资源等)。下一篇将讲解关于AssetBundle中存储和加载二进制数据。
--------------------- 
作者:IQ007伟哥 
来源:CSDN 
原文:https://blog.csdn.net/u010377179/article/details/52922716 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值