三、AssetBundle打包分组策略的总结

1. 对于需要经常更新的资源放在单独的一个包,而不常使用的资源就进行分离出来;

2. 同时加载的资源放在一个包里面,相对于需要同时加载的小资源就可以打成一个包;

3. 多个物体对象共享的资源放在单独的一个包【依赖打包】(例:两个物体使用同一材质的情况,则将材质单独进行打包。);

4. 存在同一资源中有多个版本就能使用添加版本号后缀打包进行区分。

四、AssetBundle压缩选项

string assetBundleDirectory = "Assets/AssetBundles";
//三个参数分别是构建的路径、压缩的方式、适应平台。
BuildPipeline.BuildAssetBundles(assetBundleDirectory,BuildAssetBundleOptions.None,
                                                BuildTarget.StandaloneWindows);

1. BuildAssetBundleOptions.None:使用LZMA格式压缩,这种方式会对整个包进行解压缩,尽可能得到最小的文件大小,不过需要对整个包解压缩,导致加载时间会稍微长一些。

2. BuildAssetBundleOptions.UncompressedAssetBundle:这种不会进行压缩,构建的包就比较大,不过加载比较快。

3. BuildAssetBundleOptions.ChunkBasedCompression:LZ4的压缩方法,基于不同块的方式进行打包,压缩率是低于LZMA压缩,但是LZ4不用解压全部包,能够指定对应的资源解压,其加载时间与不压缩相差不大。

五、构建打包生成的 . manifest文件

//构建打包资源的路径
Assets:

- Assets/Prefab/Cube.prefab

//打包资源所依赖资源路径
Dependencies: []

如果是存在依赖资源打包,在加载资源的时候就需要加载先依赖资源,再加载对应资源。

六、加载AssetBundle包的方法

1. AssetBundle.LoadFromMemoryAsync(内存加载)

using UnityEngine;
using System.Collections;
using System.IO;

public class Example : MonoBehaviour
{

    //异步方式进行加载
    IEnumerator LoadFromMemoryAsync(string path)
    {
        AssetBundleCreateRequest createRequest = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));
        yield return createRequest;
        AssetBundle bundle = createRequest.assetBundle;

        var prefab = bundle.LoadAsset<GameObject>("MyObject");
        Instantiate(prefab);
    }

    //同步方式进行加载
        AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes(path));

        GameObject abPrefab = ab.LoadAsset<GameObject>("Cube");
        Instantiate(abPrefab);
}

2. AssetBundle.LoadFromFile(本地文件加载)(前一章总结)

3. WWW.LoadfromCacheOrDownload(服务器或者本地文件加载)【此方法逐渐弃用】

using UnityEngine;
using System.Collections;

public class LoadFromCacheOrDownloadExample : MonoBehaviour
{
    IEnumerator Start ()
    {
            while (!Caching.ready)
                    yield return null;

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

        var asset = myLoadedAssetBundle.mainAsset;
    }
}

4. UnityWebRequest(服务器加载)

IEnumerator InstantiateObject()
{
    string uri = "file:///" + Application.dataPath + "/AssetBundles/" + assetBundleName; 
    UnityEngine.Networking.UnityWebRequest request 
        = UnityEngine.Networking.UnityWebRequest.GetAssetBundle(uri, 0);
    yield return request.Send();
    AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);
    GameObject cube = bundle.LoadAsset<GameObject>("Cube");
    GameObject sprite = bundle.LoadAsset<GameObject>("Sprite");
    Instantiate(cube);
    Instantiate(sprite);
}

七、服务器加载方式解析

1. 简单服务器的搭建

使用工具:NetBox2

方法:新建文本重命名后缀为. html的文本(html中自行添加相应的文本),并且将构建打包的AssetBundles文件夹copy到同一个文件夹里面。

Unity 真机调试renderdoc unity rebuild_Unity

2. 从服务端下载AssetBundle( WWW.LoadfromCacheOrDownload方法)【此方法逐渐弃用】

using UnityEngine;
using System.Collections;

public class LoadFromCacheOrDownloadExample : MonoBehaviour
{
    IEnumerator Start ()
    {
            while (!Caching.ready)
                    yield return null;

        var www = 
       WWW.LoadFromCacheOrDownload(@"http://localhost/AssetBundles/ground.assetbundle", 1);
        yield return www;
        if(!string.IsNullOrEmpty(www.error))
        {
            Debug.Log(www.error);
            yield return;
        }
        var myLoadedAssetBundle = www.assetBundle;

        var asset = myLoadedAssetBundle.mainAsset;
    }
}

3. 使用UnityWebRequest方法在服务器下载

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEngine.Networking;

public class LoadFromFile : MonoBehaviour
{
    IEnumerator InstantiateObject()
    {

     //本地文件加载
    //本地文件应用的格式
    //string uri = "file:///" + Application.dataPath + "/AssetBundles/" + assetBundleName; 

        string uri = 
       @"file:///F:\AssetBundleProject\Assets\AssetBundles\ground.assetbundle";
        UnityWebRequest request = UnityWebRequest.Get(uri);
        yield return request.Send();
        AssetBundle ass = DownloadHandlerAssetBundle.GetContent(request);

        GameObject ground = ass.LoadAsset<GameObject>("Cube");
        Instantiate(ground);
    }
}

八、加载AssetBundle(主要用于处理资源绑定依赖关系)

(图中的AssetBundles)

Unity 真机调试renderdoc unity rebuild_热更新基础_02

加载的具体代码(可能存在部分问题,可以参考Unity官方文档)

//manifestFilePath表示AssetBundles文件路径
AssetBundle assetBundle = AssetBundle.LoadFromFile(manifestFilePath);
AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest("AssetBundleManifest");

//assetBundle表示加载的物体
string[] dependencies = manifest.GetAllDependencies("assetBundle");

foreach(string dependency in dependencies)
{

    //AssetBundle.LoadFromFile(Path.Combine(assetBundlePath, dependency));
      AssetBundle.LoadFromFile("AssetBundles/"+name);
}

未完待续.....................