Unity5.x新的AssetBundle机制03——下载与使用

书接上文。本节我们来讲讲AssetBundle的下载与使用。在第一节Unity5.x新的AssetBundle机制01——构建中,我们已经准备好了需要的AssetBundles。本节我们就来使用这些保存好的资源。

实践

有两种方法可以下载AssetBundles:

非缓存式。

new一个WWW对象的方式,AssetBundles不会保留在本地设备的unity缓存文件夹中。
我们使用这种方式来实践一下。打开第一节中已经准备好的工程。新建Scripts文件夹,并在其中新建脚本:
NonCacheBundle.cs

using System;
using UnityEngine;
using System.Collections;
class NonCacheBundle : MonoBehaviour
{
    //根据平台,得到相应的路径
    public static readonly string BundleURL =
#if UNITY_ANDROID
        "jar:file://" + Application.dataPath + "!/assets/MyAssetBundles/shape/cube";
#elif UNITY_IPHONE
        Application.dataPath + "/Raw/MyAssetBundles/shape/cube";
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR
        //我们将加载以前打包好的cube
 "file://" + Application.dataPath + "/MyAssetBundles/shape/cube";//由于是编辑器下,我们使用这个路径。
#else
        string.Empty;
#endif

    //还记得吗?在cube这个AssetBundle中有两个资源,Cube1和Cube2
    private string AssetName = "Cube1";

    IEnumerator Start()
    {
        // 从URL中下载文件,不会存储在缓存中。
        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;
            GameObject cube = Instantiate(bundle.LoadAsset(AssetName)) as GameObject;
            cube.transform.position = new Vector3(0f, 0f, 0f);
            // 卸载加载完之后的AssetBundle,节省内存。
            bundle.Unload(false);

        }//由于使用using语法,www.Dispose将在加载完成后调用,释放内存
    }
}

将代码多拽到Hierarchy视口中的MainCamera物体中,运行游戏,可以看到cube1被加载到场景中。

缓存方式

使用WWW.LoadFromCacheOrDownload接口。AssetBundles将保存在本地设备的Unity的缓存文件夹中。WebPlayer 有50MB的缓存上限,PC/Mac/Android/IOS应有有4 GB的缓存上限。这种方式也是加载AssetBundle推荐的方式。我们使用这种方式来实践一下。在Scripts文件夹中新建脚本:
CacheBundle.cs

using System;
using UnityEngine;
using System.Collections;

public class CacheBundle : MonoBehaviour
{
    public static readonly string BundleURL =
#if UNITY_ANDROID
        "jar:file://" + Application.dataPath + "!/assets/MyAssetBundles/shape/cube";
#elif UNITY_IPHONE
        Application.dataPath + "/Raw/MyAssetBundles/shape/cube";
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR
        //我们将加载以前打包好的cube
 "file://" + Application.dataPath + "/MyAssetBundles/shape/cube";//由于是编辑器下,我们使用这个路径。
#else
        string.Empty;
#endif

    //还记得吗?在cube这个AssetBundle中有两个资源,Cube1和Cube2
    private string AssetName = "Cube2";

    //版本号
    public int version;

    void Start()
    {
        StartCoroutine(DownloadAndCache());
    }

    IEnumerator DownloadAndCache()
    {
        // 需要等待缓存准备好
        while (!Caching.ready)
            yield return null;

        // 有相同版本号的AssetBundle就从缓存中获取,否则下载进缓存。
        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;
            GameObject cube = Instantiate(bundle.LoadAsset(AssetName)) as GameObject;
            cube.transform.position = new Vector3(1.5f, 0f, 0f);
            // 卸载加载完之后的AssetBundle,节省内存。
            bundle.Unload(false);

        } //由于使用using语法,www.Dispose将在加载完成后调用,释放内存
    }
}

同样将该脚本拖动到MainCamera中,运行游戏,可以看到Cube2被加载进场景中。这是最终运行效果:

run_assetbundle.png

当我们访问www对象的.assetBundle属性时,下载好的数据被解压并创建了AssetBundle对象。此时就可以加载该AssetBundle中的所有资源。

使用异步方法

前两个例子中,我们都使用了AssetBundle类中的LoadAsset接口,这是一个同步的方法。这里提供一个异步的示例:
LoadAsyncBundle.cs

using UnityEngine;
using System;
using System.Collections;

public class LoadAsyncBundle : MonoBehaviour
{

    //根据平台,得到相应的路径
    public static readonly string BundleURL =
#if UNITY_ANDROID
        "jar:file://" + Application.dataPath + "!/assets/MyAssetBundles/shape/cube";
#elif UNITY_IPHONE
        Application.dataPath + "/Raw/MyAssetBundles/shape/cube";
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR
 "file://" + Application.dataPath + "/MyAssetBundles/shape/sphere";
#else
        string.Empty;
#endif

    private string AssetName = "Sphere1";

    IEnumerator Start()
    {
        while (!Caching.ready)
            yield return null;
        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;

            // 异步加载
            AssetBundleRequest request = bundle.LoadAssetAsync(AssetName, typeof(GameObject));

            // 等待加载完成
            yield return request;

            // 获取加载好的对象引用
            GameObject prefab = request.asset as GameObject;
            GameObject sphere = Instantiate(prefab);
            sphere.transform.position = new Vector3(0f, 1.5f, 0f);
            // 卸载加载完之后的AssetBundle,节省内存。
            bundle.Unload(false);

        }//由于使用using语法,www.Dispose将在加载完成后调用,释放内存
    }
}

至此,Unity5中新的AssetBundle机制的使用已经大致讲完啦。当然还有许多细节无法赘述,大家可以通过查看官方文档继续了解。有问题欢迎和我一起讨论。我已经将本工程上传到我的github,以供大家参考。请使用assetbundle这个分支。

[参考链接][1]http://docs.unity3d.com/Manual/DownloadingAssetBundles.html
[参考链接][2]http://docs.unity3d.com/Manual/LoadingAssetBundles.html


上一篇:Unity5.x新的AssetBundle机制02——压缩



作者:kashiwa
链接:https://www.jianshu.com/p/f3453543302b
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

转自https://blog.csdn.net/lodypig/article/details/51872595

 Unity特殊路径

 在加载AssetBundle时,要给出AssetBundle文件路径,Unity有很多特殊路径,这里列出部分与加载相关的路径。这些路径在不同平台下是不相同的,并可能包含项目或公司名字。下文中出现的类似myProject、myCompany应换成你工程所对应的名字。

 
      Resources

Resources文件可以在根目录下,也可以在子目录下,只要叫Resources就好。Resources目录下所有资源将被打包进游戏存放资源的archive中,Resources目录在应用中也就不复存在,但加载时仍使用曾在Resource下的路径。该目录下所有资源会被压缩,只读不可写,使用Resources.Load()接口加载。


       StreamingAssetsPath
     StreamingAssets目录必须在Assets根目录下,该目录下所有资源也会被打包到游戏里,不同于Resources目录,该目录下的资源不会进行压缩,同样是只读不可写的。Unity基本也没有提供从该路径下直接读取资源的方法,只有www可以加载audioClip、texture和二进制文件。但Unity提供了从该目录加载AssetBundle的方法,我们一般直接在这个目录下存放AssetBundle文件。可以通过Application.streamingAssetsPath访问该路径。 


        各平台StreamingAssets路径打印: 
        Win:E:/myProj/Assets/StreamingAssets 
        Mac : /myProj/Assets/StreamingAssets 
        Andorid:jar:file:///data/app/com.myCompany.myProj-1/base.apk!/assets 
       iOS: /var/containers/Application/E5543D66-83F3-476D-8A8F-49D5332B3763/myProj.app/Data/Raw


        PersistentDataPath
     该目录为应用程序沙盒目录,应用程序安装后才会出现。该目录独特之处在于是可写的,所以我们一般将下载的AssetBundle存放于此。使用Application.persistentDataPath访问。
 
        各平台PersistentDataPath路径打印: 
        Win:C:/Users/lodypig/Appdata/LocalLow/myCompany/myProj 
        Mac : /Users/lodypig/Library/Application Support/myCompany/myProj 
        Andorid:/data/data/com.myCompany.myProj/files 
        iOS: /var/mobile/Containers/Data/Appliction/A112252D-6B0E-459Z-9D49-CD3EAC6D47D/Documents


         DataPath
     应用程序目录,即Assets目录。使用Appliction.dataPath访问。
 
         各平台DataPath路径: 
         Win:E:/myProj/Assets 
         Mac : /myProj/Assets/ 
         Andorid:/data/app/com.myCompany.myProj-1/base.apk! 
         iOS: /var/containers/Application/E5543D66-83F3-476D-8A8F-49D5332B3763/myProj.app/Data

猜你喜欢

转载自blog.csdn.net/qq_31967569/article/details/83182591