stream | 托管 Stream 对象。Unity 调用 Read()、Seek() 和该对象的 Length 属性来加载 AssetBundle 数据。 |
crc | 未压缩内容的 CRC-32 校验和(可选)。 |
managedReadBufferSize | You can use this to override the size of the read buffer Unity uses while loading data. The default size is 32KB. |
AssetBundleCreateRequest AssetBundle 的异步创建请求。加载后使用 assetBundle 属性获取 AssetBundle。
从托管 Stream 异步加载 AssetBundle。
该函数支持任意压缩类型的捆绑包。
如果是 lzma 压缩数据,则将数据解压缩到内存。如果是未压缩或使用块压缩的捆绑包,则直接从 Stream 读取。
与 LoadFromStream 不同,该函数是异步的。
与 LoadFromFileAsync 不同的是,AssetBundle 的数据由托管 Stream 对象提供。
以下是对 Stream 对象的限制,以优化 AssetBundle 数据加载:
1.AssetBundle 数据必须从流的位置零开始。
2.在加载 AssetBundle 数据前,Unity 将搜寻位置设置为零。
3.Unity 假定流中的读取位置不会被任何其他进程修改。这允许 Unity 进程直接从流读取内容,而不必在每次读取前调用 Seek()。
4.stream.CanRead 必须返回 true。
5.stream.CanSeek 必须返回 true。
6.必须可以从主线程以外的线程进行访问。可以从任何 Unity 本机线程调用 Seek() 和 Read()。
7.在某些情况下,Unity 会尝试读取超出 AssetBundle 数据大小的内容。Stream 实现必须成功处理这种情况而不抛出异常。此外,Stream 实现还必须返回读取的实际字节数(不包括超出 AssetBundle 数据末尾的任何字节)。
8.当从 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(); } }