stream | 托管 Stream 对象。Unity 调用 Read()、Seek() 和该对象的 Length 属性来加载 AssetBundle 数据。 |
crc | 未压缩内容的 CRC-32 校验和(可选)。 |
managedReadBufferSize | 加载数据时使用的读取缓冲区大小(可选)。默认大小为 32KB。 |
AssetBundle 已加载的 AssetBundle 对象,加载对象失败时为 null。
从托管 Stream 同步加载 AssetBundle。
该函数支持任意压缩类型的捆绑包。
如果是 lzma 压缩数据,则将数据解压缩到内存。如果是未压缩或使用块压缩的捆绑包,则直接从 Stream 读取。
当校验和为非零值时,加载前将内容与校验和进行比较,如果不匹配则抛出错误。
与 LoadFromStreamAsync 不同的是,该函数是同步的,将等待 AssetBundle 对象创建完毕才返回。
与 LoadFromFile 不同的是,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; using System.IO;
public class LoadFromStreamExample : MonoBehaviour { void Start() { var fileStream = new FileStream(Application.streamingAssetsPath, FileMode.Open, FileAccess.Read); var myLoadedAssetBundle = AssetBundle.LoadFromStream(fileStream); if (myLoadedAssetBundle == null) { Debug.Log("Failed to load AssetBundle!"); return; }
var prefab = myLoadedAssetBundle.LoadAsset<GameObject>("MyObject"); Instantiate(prefab);
myLoadedAssetBundle.Unload(false); } }