AssetBundle的加载

AssetBundle.LoadFromMemoryAsync

AssetBundleCreateRequest LoadFromMemoryAsync(byte[] binary, uint crc = 0);
  • 使用二进制数据异步加载ab对象,通常我们对ab进行加密后,下载到本地解密,然后将解密后的二进制数据传进来,最后获取到ab对象。

  • 如果是LZMA压缩的AB,会在加载的过程中进行解压;如果是LZ4压缩的AB,会直接加载压缩状态的数据。

  • 与同步版接口LoadFromMemory立即返回ab对象不同,LoadFromMemoryAsync会在后台线程中执行解压操作。

IEnumerator LoadFromMemoryAsync(string path)
{

    AssetBundleCreateRequest createRequest = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));

    yield return createRequest;

    AssetBundle bundle = createRequest.assetBundle;

    var prefab = bundle.LoadAsset.("MyObject");
    Instantiate(prefab);

}

AssetBundle.LoadFromFile

AssetBundle LoadFromFile(string path, uint crc = 0, ulong offset = 0); 
  • 从本地加载未压缩(uncompressed)或使用LZ4压缩的AB,效率很高。

  • 加载LZMA压缩的AB时,会先将其解压,然后再载入内存。

  • 在Unity5.3及之前的版本中,在Android平台下调用这个接口去加载StreamingAssets目录下的ab会失败,因为安卓下这个目录是一个.jar的压缩文件。不过Unity5.4以及之后的版本已经修复这个问题,可以正常使用。

var myLoadedAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "myassetBundle"));
if (myLoadedAssetBundle == null) {
    Debug.Log("Failed to load AssetBundle!");
    return;
}
var prefab = myLoadedAssetBundle.LoadAsset.("MyObject");
Instantiate(prefab);

WWW.LoadFromCacheOrDownload

WWW LoadFromCacheOrDownload(string url, int version);
  • 不推荐使用此接口,因为使用www对象来存储ab对象会造成内存开销过多,WebStreaming问题。

  • 先从本地缓存中获取ab,如果不存在或者不是最新版本,则会从远程下载。如果ab是压缩过的,则会在线程中解压ab,然后写入本地缓存中。一但ab解压完成并缓存之后的加载流程就跟AssetBundle.LoadFromFile完全一样。

  • version用法??

IEnumerator Start()
{
    while (!Caching.ready)
        yield return null;

    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;
}

ab缓存由Caching类管理,Caching还可以用来做ab备份以及回滚。

https://docs.unity3d.com/ScriptReference/Caching.html

由于www的性能问题,使用这个接口时需要注意:

  • 单个ab不能太大,一般建议不超过1M

  • 在移动平台,同一时间最多下载一个ab,避免造成内存高峰

其它:

  • 如果本地缓存没有足够空间,则会先删除最久没访问的资源;如果找不到可以删除的资源,则会跳过缓存过程,直接将文件加载到内容中,流程就跟"new WWW()"一样。

  • 只能用此方法来访问AB,对其它类型资源不适用。

  • url中的'%'必须被省去。

UnityWebRequest

UnityWebRequest UnityWebRequest.GetAssetBundle(string uri, uint crc);

AssetBundle DownloadHandlerAssetBundle.GetContent(Networking.UnityWebRequest www);
  • 最推荐的方式来替代www的方式加载AB,以减少webstream内存占用问题

  • 先用UnityWebRequest.GetAssetBundle进行下载

  • 再用DownloadHandlerAssetBundle.GetContent(UnityWebRequest)获取AB对象

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("Cube");
    GameObject sprite = bundle.LoadAsset("Sprite");
    Instantiate(cube);
    Instantiate(sprite);
}

LoadAsset

  • 同步加载
    T objectFromBundle = bundleObject.LoadAsset(assetName);
GameObject gameObject = loadedAssetBundle.LoadAsset(assetName);

Unity.Object[] objectArray = loadedAssetBundle.LoadAllAssets();
  • 异步加载
AssetBundleRequest request = loadedAssetBundleObject.LoadAssetAsync(assetName);
yield return request;
var loadedAsset = request.asset;
AssetBundleRequest request = loadedAssetBundle.LoadAllAssetsAsync();
yield return request;
var loadedAssets = request.allAssets;

Load Manifests

  • 在AB根目录,会有一个Manifest的AB文件,跟加载普通AB一样
  • 存储了依赖关系,哈希值,AB变体等
AssetBundle assetBundle = AssetBundle.LoadFromFile(manifestFilePath);
AssetBundleManifest manifest = assetBundle.LoadAsset("AssetBundleManifest");
  • 在加载AB前,需要先加载其依赖
AssetBundle assetBundle = AssetBundle.LoadFromFile(manifestFilePath);
AssetBundleManifest manifest = assetBundle.LoadAsset("AssetBundleManifest");
string[] dependencies = manifest.GetAllDependencies("assetBundle"); //Pass the name of the bundle you want the dependencies for.
foreach(string dependency in dependencies)
{
    AssetBundle.LoadFromFile(Path.Combine(assetBundlePath, dependency));
}

其它

  • 同一个AB只能加载一次,否则会报错,提示已经加载过
  • 同一个AB只有在Unload后,才可以再次加载

https://docs.unity3d.com/Manual/AssetBundles-Native.html

你可能感兴趣的:(AssetBundle的加载)