在实际项目中,我们不可能每次启动程序都从服务端获取AssetBundle文件。一般都是将获取到的AssetBundle文件存放在本地,方便以后调用。 这两篇博客,都是属于AssetBundle比较核心一部分东西,用到的API也比较多,但是我基本都加了注释,要想熟练掌握还需要多练习的。之所以写下来,大致是为了当作自己的学习笔记,方便日后回头看,可以说是是查漏补缺吧。 这篇主要是写了如何用WWW下载资源,以及用IO系统来存放我们下载的资源。 代码如下:

using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
//引入UnityEngine.Networking用来执行网络操作

public class load : MonoBehaviour
{
//根目录的文件夹产生的AssetBundless文件地址
private string rootAssetBundle = @”http://www.wjgbaby.com/unityModel/AssetBundless/AssetBundless";
//根目录地址
private string assetBundleRoot = @”http://www.wjgbaby.com/unityModel/AssetBundless/";

void Start ()
{
    //开启协程
    StartCoroutine("DownloadAssetBundless");
}

/// <summary>
/// 下载根目录AssetBundle文件
/// </summary>
/// <returns></returns>
IEnumerator DownloadAssetBundless()
{
    //创建一个获取AssetBundle 文件的web 请求.
    UnityWebRequest request = UnityWebRequest.GetAssetBundle(rootAssetBundle);

    //发送web请求
    yield return request.SendWebRequest();

    //从web获取内容,返回一个AssetBundle类型的数据
    AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);

    //获取AssetBundless.manifest的manifest文件
    AssetBundleManifest manifest = ab.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

    //获取AssetBundless.manifest文件中的所有AssetBundle的名称信息
    string\[\] assets= manifest.GetAllAssetBundles();
    for (int i = 0; i <assets.Length;i++)
    {
        Debug.Log(assetBundleRoot+assets\[i\]);
        //开启协程
        //StartCoroutine(DownLoadSingleAssetBundel(assetBundleRoot + assets\[i\]));

        StartCoroutine(DownloadAssetBundleAndSave(assetBundleRoot + assets\[i\]));
    }
}

/\*
/// <summary>
/// 下载模型单个的AssetBundle文件
/// </summary>
/// <returns></returns>
IEnumerator DownLoadSingleAssetBundel(string str)
{
    UnityWebRequest request = UnityWebRequest.GetAssetBundle(str);
    yield return request.SendWebRequest();
    AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);

    //通过获取AssetBundle对象获取内部所有资源的名称,返回在一个数组
    string\[\] names= ab.GetAllAssetNames();

    //遍历数组,服务端下载所有文件
    for (int i= 0;i< names.Length;i++)
    {
        //截取路径地址中的文件名,且无后缀名. 需要引入System.IO 命名空间.
        string shortName = Path.GetFileNameWithoutExtension(names\[i\]);
        GameObject go = ab.LoadAsset<GameObject>(shortName);
        GameObject.Instantiate<GameObject>(go, Vector3.zero, Quaternion.identity);
    }
}
\*/

/// <summary>
/// 下载AssetBundle文件并保存在本地
/// </summary>
/// <returns></returns>
IEnumerator DownloadAssetBundleAndSave(string url)
{
    //通过WWW 类创建一个web 请求,参数填写AssetBundle 的url 下载地址.
    WWW www = new WWW(url);

    //将对象作为数据返回,这个www 对象就是请求(下载)来的数据
    yield return www;

    //www.isDone,一个属性,表示下载状态是否完毕
    if (www.isDone)
    {
        ////使用IO技术将www对象存储到本地.
        SaveAssetBundle(Path.GetFileName(url), www.bytes, www.bytes.Length);
    }
}

/// <summary>
/// 保存AssetBundle文件到本地
/// </summary>
private void SaveAssetBundle(string fileName,byte\[\] bytes,int count)
{
    FileInfo fileInfo = new FileInfo(Application.dataPath+"//"+fileName);
    FileStream fs = fileInfo.Create();

    //fs.Write(字节数组, 开始位置, 数据长度);
    fs.Write(bytes, 0, count);

    fs.Flush();     //文件写入存储到硬盘
    fs.Close();     //关闭文件流对象
    fs.Dispose();   //销毁文件对象
}        

}

结果如下,可以看到player.ab和plane.ab已经从我的web服务器被下载到了Assets目录下。 [

](http://www.wjgbaby.com/wp-content/uploads/2017/10/17102201-300x145.png)
](http://www.wjgbaby.com/wp-content/uploads/2017/10/17102201-300x145.png)