Unity AssetBundle加载和内存管理

AssetBundle资源加载

一个AssetBundle中包含两部分:数据头和数据段。

通过AssetBundle加载游戏资源,分为三步:

  1. 加载AssetBundle对象。

  2. 通过AssetBundle对象加载需要的资源。

  3. 对于非引用类型的资源,还需通过GameObject.Instantiate()创建clone。

1. 加载AssetBundle对象方式

  • AssetBundle.LoadFromMemory(可选择异步模式)
  • AssetBundle.LoadFromFile(可选择异步模式)
  • AssetBundle.LoadFromStream(可选择异步模式)
  • UnityWebRequest的DownloadHandlerAssetBundle (异步模式)
  • WWW.LoadFromCacheOrDownload (Unity 5.6以及更低版本)(异步模式) 
  • WWW(异步模式)

1.1 WWW.LoadFromCacheOrDownload(异步-缓存机制),2017以后被废弃。

Unity5.2之前推荐使用 WWW.LoadFromCacheOrDownload(),从2017开始被整合到UnityWebRequest中。以下适用于5.6以前版本。(异步加载,每次打包都需要更新资源版本,保存的路径无法更改,也没有接口去获取此路径)

  • 可以从远程服务器加载Object,也可以从本地存储加载Object。可以通过 file:// URL从本地存储加载文件。
  • 每次下载时候,都会创建一个线程,每个线程会在托管堆中缓存一份解压后的AssetBundle,这可能导致内存飙升。
  • 如果本地没有缓存,使用WWW网络下载文件。从网络下载的AssetBundle如果没有压缩,通过固定大小的缓冲区直接并写入本地缓存,如果有压缩还需要在固定大小的缓冲区中解压缩后,才能写入本地缓存。但是WWW对象将在托管堆中保留解压缩后的AssetBundle字节的完整副本。保留AssetBundle的额外副本以支持www.bytes等属性。一旦解压缩后的AssetBundle被缓存到本地,LoadFromCacheOrDownload将从本地缓存的解压缩AssetBundle加载数据头。
  • 如果本地已有缓存,调用LoadFromCacheOrDownload,和调用LoadFromFile一样,由于本地缓存中是未压缩的AssetBundle,因此只会加载AssetBundle数据头。
public class LoadFromCacheOrDownloadExample : MonoBehaviour
{
    IEnumerator Start()
    {
        while (!Caching.ready)
            yield return null;

        using (var www =             
        WWW.LoadFromCacheOrDownload("http://myserver.com/myassetBundle.unity3d", 5))
        {
            yield return www;
            if (!string.IsNullOrEmpty(www.error))
            {
                Debug.Log(www.error);
                yield return null;
            }
            var myLoadedAssetBundle = www.assetBundle;

            var asset = myLoadedAssetBundle.mainAsset;
        }
    }
}


1.2 WWW (异步-无缓存机制)

WWW是一个Unity封装的网络下载模块,支持Http以及file两种URL协议。

直接使用LoadFromCacheOrDownload和WWW不同的是,读取不会再走WWW这一套 WWW进行读取或者下载时候,都会创建一个线程,托管堆中缓存一份下载后的AssetBundle,同时开启多个下载,这可能导致内存飙升。使用WWW.Dispose将终止仍在加载过程中的进程,并释放掉托管堆中的AssetBundle。 

通过www下载资源,然后释放托管堆内存。代码如下:

/// <summary>
///从服务器下载到本地
/// </summary>
/// <param name="AssetsHost">服务器路径</param>
/// <param name="AssetName">请求资源名称</param>
/// <param name="saveLocalPath">保存到本地路径,一般存在Application.persistentDataPath</param>
/// <returns></returns>
IEnumerator DownLoadAssetsWithDependencies2Local(string AssetsHost, string AssetName, string saveLocalPath)
{
    WWW tempWwwAsset = new WWW(AssetsHost + "/" + AssetName);
    //获取加载进度
    yield return tempWwwAsset;

    //直接读取AssetBundle
    AssetBundle temp = tempWwwAsset.assetBundle;

    //保存到本地
    Stream tempStream = null;
    FileInfo fileInfo = new FileInfo(saveLocalPath + "/" + AssetName);
    if (fileInfo.Exists)
    {
        fileInfo.Delete();
    }
    //如果此文件不存在则创建
    tempStream = fileInfo.Create();
    //写入
    tempStream.Write(tempWwwAsset.bytes, 0, tempWwwAsset.bytes.Length);
    tempStream.Flush();
    //关闭流
    tempStream.Close();
    //销毁流
    tempStream.Dispose();
    Debug.Log(name + "成功保存到本地~");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值