Version: 2022.3

AssetBundle.LoadFromStreamAsync

切换到手册
public static AssetBundleCreateRequest LoadFromStreamAsync (Stream stream, uint crc, uint managedReadBufferSize);

参数

stream 托管 Stream 对象。Unity 调用 Read()、Seek() 和该对象的 Length 属性来加载 AssetBundle 数据。
crc 未压缩内容的 CRC-32 校验和(可选)。
managedReadBufferSize 此值可用于重载 Unity 加载数据时使用的读取缓冲区大小。默认大小为 32KB。

返回

AssetBundleCreateRequest AssetBundle 的异步创建请求。加载后使用 assetBundle 属性获取 AssetBundle。

描述

从托管 Stream 异步加载 AssetBundle。

该函数支持任意压缩类型的捆绑包。 如果是 **lzma** 压缩数据,则将数据解压缩到内存。如果是未压缩或使用块压缩的捆绑包,则直接从 Stream 读取。

LoadFromStream 不同,该函数是异步的。

LoadFromFileAsync 不同的是,AssetBundle 的数据由托管 Stream 对象提供。

以下是对 Stream 对象的限制,以优化 AssetBundle 数据加载: AssetBundle 数据必须从流的位置零开始。 在加载 AssetBundle 数据前,Unity 将搜寻位置设置为零。 Unity 假定流中的读取位置不会被任何其他进程修改。这允许 Unity 进程直接从流读取内容,而不必在每次读取前调用 Seek()。 stream.CanRead 必须返回 true。 stream.CanSeek 必须返回 true。 必须可以从主线程以外的线程进行访问。可以从任何 Unity 本机线程调用 Seek() 和 Read()。 在某些情况下,Unity 会尝试读取超出 AssetBundle 数据大小的内容。Stream 实现必须成功处理这种情况而不抛出异常。此外,Stream 实现还必须返回读取的实际字节数(不包括超出 AssetBundle 数据末尾的任何字节)。 当从 AssetBundle 数据末尾开始并尝试读取数据时,Stream 实现必须返回 0 字节的读取内容,并且不抛出任何异常。 为了减少从本机代码到托管代码的调用次数,使用缓冲区大小为 **managedReadBufferSize** 的带缓冲读取器从 Stream 读取数据。 更改 **managedReadBufferSize** 可能会改变加载性能,这在移动设备上尤其明显。 **managedReadBufferSize** 的最佳值因项目而异,甚至随资源捆绑包的不同而不同。 一些值得尝试的值:8KB、16KB、32KB、64KB、128KB。 对于压缩资源捆绑包,或者如果资源捆绑包包含大型资源,或者资源捆绑包包含的资源不多并且从资源捆绑包顺序加载它们,则较大的值可能更好。 对于未压缩的资源捆绑包和读取大量小型资源的情况,或者如果资源捆绑包包含大量资源并且以随机顺序加载资源,则较小的值可能更好。 加载 AssetBundle 或从捆绑包中加载任何资源时,不要处置 Stream 对象。其生命周期应该比 AssetBundle 长。也就是说,您应该先调用 AssetBundle.Unload,而后处置 Stream 对象。

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

public class LoadFromFileAsyncExample : MonoBehaviour { IEnumerator Start() { var fileStream = new FileStream(Application.streamingAssetsPath, FileMode.Open, FileAccess.Read); var bundleLoadRequest = AssetBundle.LoadFromStreamAsync(fileStream); yield return bundleLoadRequest;

var myLoadedAssetBundle = bundleLoadRequest.assetBundle; if (myLoadedAssetBundle == null) { Debug.Log("Failed to load AssetBundle!"); yield break; }

var assetLoadRequest = myLoadedAssetBundle.LoadAssetAsync<GameObject>("MyObject"); yield return assetLoadRequest;

GameObject prefab = assetLoadRequest.asset as GameObject; Instantiate(prefab);

myLoadedAssetBundle.Unload(false); fileStream.Close(); } }