Unity 的 AssetBundle 系统提供了多种加载方式,以满足不同场景下的资源管理和性能需求。


同步加载(LoadFromFile)

同步加载使用 AssetBundle.LoadFromFile 方法从文件系统中直接加载 AssetBundle。这种方式会阻塞主线程,直到加载完成。

基本用法

// 同步加载
AssetBundle bundle = AssetBundle.LoadFromFile(path);

使用场景

  • 小型 AssetBundle:适用于加载速度快、不会导致明显卡顿的资源。
  • 预加载:在游戏启动或场景切换时加载必要的资源。
  • 测试和调试:开发阶段快速验证资源加载。

优缺点

  • 优点
    • 实现简单,代码量少。
    • 加载速度快,适合小型资源。
  • 缺点
    • 阻塞主线程,可能导致游戏卡顿。
    • 不适合加载大型 AssetBundle。

应用建议

  • 建议在加载小型资源或加载屏幕期间使用,避免在游戏运行时加载大型 AssetBundle,以免影响用户体验。

异步加载(LoadFromFileAsync)

异步加载使用 AssetBundle.LoadFromFileAsync 方法,加载过程在后台进行,不会阻塞主线程。返回一个 AssetBundleCreateRequest 对象,可通过协程或回调监控加载进度。

基本用法

// 异步加载
AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path);
yield return request;
AssetBundle bundle = request.assetBundle;

使用场景

  • 大型 AssetBundle:加载大文件时避免游戏卡顿。
  • 后台加载:在游戏运行时动态加载资源。
  • 加载进度显示:需要展示加载进度条的场景。

优缺点

  • 优点
    • 不阻塞主线程,保持游戏流畅。
    • 支持加载进度监控。
  • 缺点
    • 实现相对复杂,需要处理异步逻辑。
    • 加载速度可能略慢于同步加载。

应用建议

  • 推荐在加载大型资源时使用,结合协程或回调函数处理加载完成后的逻辑,是游戏中常用的加载方式。

从内存加载(LoadFromMemory)

从内存中的字节数组加载 AssetBundle,使用 AssetBundle.LoadFromMemory 方法。通常用于从网络下载的字节数据直接加载。

基本用法

// 同步加载
byte[] bundleData = GetBundleBytes(); // 从某处获取字节数据
AssetBundle bundle = AssetBundle.LoadFromMemory(bundleData);// 异步加载
AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(bundleData);
yield return request;
AssetBundle bundle = request.assetBundle;

使用场景

  • 网络下载后处理:下载完成后立即加载
  • 加密资源:解密后的数据直接加载
  • 内存缓存:将常用Bundle缓存在内存中
  • 自定义存储:从数据库或特殊格式中读取

优缺点

  • 优点
    • 灵活性高:可以从任何数据源加载
    • 支持加密:可以对Bundle数据进行加密处理
    • 无文件依赖:不需要实际的文件系统
    • 即时加载:数据已在内存中,加载速度快
  • 缺点
    • 内存占用大:需要同时存储原始数据和Bundle
    • GC压力:大量字节数组可能触发垃圾回收
    • 不支持大文件:受限于可用内存大小
    • 数据拷贝开销:需要完整拷贝Bundle数据

应用建议

  • 适用于需要从网络下载并立即加载的场景,注意内存管理以避免泄漏。

应用示例

public class MemoryBundleLoader : MonoBehaviour
{private Dictionary<string, byte[]> bundleCache = new Dictionary<string, byte[]>();// 加密Bundle加载public IEnumerator LoadEncryptedBundle(string bundleName, string encryptionKey){// 从网络或本地获取加密数据byte[] encryptedData = yield return DownloadEncryptedBundle(bundleName);// 解密数据byte[] decryptedData = DecryptBundle(encryptedData, encryptionKey);// 从内存加载AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(decryptedData);yield return request;if (request.assetBundle != null){Debug.Log($"Encrypted bundle loaded: {bundleName}");}// 清理敏感数据Array.Clear(encryptedData, 0, encryptedData.Length);Array.Clear(decryptedData, 0, decryptedData.Length);}// 内存缓存系统public IEnumerator PreloadBundleToMemory(string bundleName){if (bundleCache.ContainsKey(bundleName))yield break;string path = GetBundlePath(bundleName);byte[] bundleData = File.ReadAllBytes(path);bundleCache[bundleName] = bundleData;Debug.Log($"Bundle cached to memory: {bundleName}");}public AssetBundle LoadFromCache(string bundleName){if (bundleCache.ContainsKey(bundleName)){return AssetBundle.LoadFromMemory(bundleCache[bundleName]);}return null;}
}

从网络加载(UnityWebRequestAssetBundle)

使用 UnityWebRequestAssetBundle 从 URL 下载并加载 AssetBundle,集成了网络请求和资源加载,适合热更新场景。

基本用法

public IEnumerator LoadBundleFromWeb(string url)
{UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(url);yield return request.SendWebRequest();if (request.result == UnityWebRequest.Result.Success){AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);// 使用bundle...}else{Debug.LogError($"Download failed: {request.error}");}
}

使用场景

  • 热更新:从服务器下载最新资源
  • 按需加载:用户触发时才下载特定内容
  • CDN分发:利用CDN加速资源分发
  • A/B测试:动态加载不同版本的资源

优缺点

  • 优点
    • 支持网络协议:HTTP/HTTPS等标准协议
    • 内置缓存:自动处理HTTP缓存机制
    • 进度监控:可以获取下载进度
    • 错误处理:完善的网络错误处理机制
  • 缺点
    • 网络依赖:需要稳定的网络连接
    • 下载延迟:首次加载需要等待下载完成
    • 带宽消耗:消耗用户流量
    • 缓存管理:需要处理缓存清理和版本控制

应用建议

  • 在热更新系统中使用,建议结合版本管理和哈希校验,确保加载正确的资源,同时保证网络请求的稳定性。

应用示例

public class WebBundleLoader : MonoBehaviour
{[System.Serializable]public class DownloadProgress{public float progress;public long downloadedBytes;public long totalBytes;public string status;}public IEnumerator LoadBundleWithProgress(string url, System.Action<DownloadProgress> onProgress){DownloadProgress progress = new DownloadProgress();using (UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(url)){// 设置超时时间request.timeout = 30;// 开始下载request.SendWebRequest();// 监控下载进度while (!request.isDone){progress.progress = request.downloadProgress;progress.downloadedBytes = (long)(request.downloadedBytes);progress.status = $"Downloading... {progress.progress * 100:F1}%";onProgress?.Invoke(progress);yield return null;}// 检查结果if (request.result == UnityWebRequest.Result.Success){AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);progress.status = "Download completed";onProgress?.Invoke(progress);// 使用bundle...}else{progress.status = $"Download failed: {request.error}";onProgress?.Invoke(progress);}}}// 带重试机制的下载public IEnumerator LoadBundleWithRetry(string url, int maxRetries = 3){int retryCount = 0;while (retryCount < maxRetries){using (UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(url)){yield return request.SendWebRequest();if (request.result == UnityWebRequest.Result.Success){AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);Debug.Log($"Bundle downloaded successfully: {url}");yield break;}else{retryCount++;Debug.LogWarning($"Download attempt {retryCount} failed: {request.error}");if (retryCount < maxRetries){yield return new WaitForSeconds(Mathf.Pow(2, retryCount)); // 指数退避}}}}Debug.LogError($"Failed to download bundle after {maxRetries} attempts: {url}");}
}

流式加载(LoadFromStream)

从流中加载 AssetBundle,使用 AssetBundle.LoadFromStream 方法,支持从文件流或网络流加载,适合分块加载或流式传输。

基本用法

public IEnumerator LoadBundleFromStream()
{// 创建文件流FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);// 异步加载AssetBundleCreateRequest request = AssetBundle.LoadFromStreamAsync(stream);yield return request;AssetBundle bundle = request.assetBundle;// 注意:stream需要保持打开状态直到bundle卸载
}

使用场景

  • 大文件分块加载:逐步加载大型Bundle
  • 自定义数据源:从数据库或网络流加载
  • 内存控制:精确控制内存使用
  • 特殊格式处理:处理压缩或加密的流数据

优缺点

  • 优点
    • 内存效率:只加载需要的部分到内存
    • 支持大文件:适合处理超大Bundle
    • 灵活的数据源:可以从任何Stream加载
    • 精确控制:可以控制加载的时机和方式
  • 缺点
    • 复杂性高:需要管理Stream的生命周期
    • 平台限制:某些平台可能不支持
    • 调试困难:Stream相关的问题不容易定位
    • 性能开销:可能比直接文件加载慢

应用建议

  • 适用于需要流式加载大型资源的场景,确保流的稳定性和错误处理机制。

应用示例

public class StreamBundleLoader : MonoBehaviour
{private Dictionary<AssetBundle, Stream> activeStreams = new Dictionary<AssetBundle, Stream>();// 分块加载大文件public IEnumerator LoadLargeBundleFromStream(string path){FileStream stream = null;try{stream = new FileStream(path, FileMode.Open, FileAccess.Read);// 检查文件大小long fileSize = stream.Length;Debug.Log($"Loading large bundle: {fileSize / (1024 * 1024)}MB");// 异步加载AssetBundleCreateRequest request = AssetBundle.LoadFromStreamAsync(stream);// 显示加载进度(这里是模拟,实际Stream加载没有内置进度)float startTime = Time.time;while (!request.isDone){float elapsed = Time.time - startTime;Debug.Log($"Loading... {elapsed:F1}s");yield return null;}if (request.assetBundle != null){// 保存Stream引用,Bundle卸载前不能关闭activeStreams[request.assetBundle] = stream;Debug.Log("Large bundle loaded from stream");}else{stream?.Close();}}catch (System.Exception e){Debug.LogError($"Failed to load bundle from stream: {e.Message}");stream?.Close();}}// 自定义数据源加载public IEnumerator LoadBundleFromCustomSource(string bundleId){// 假设从某个自定义数据源获取流Stream customStream = GetCustomDataStream(bundleId);if (customStream != null){AssetBundleCreateRequest request = AssetBundle.LoadFromStreamAsync(customStream);yield return request;if (request.assetBundle != null){activeStreams[request.assetBundle] = customStream;Debug.Log($"Bundle loaded from custom source: {bundleId}");}else{customStream.Close();}}}// 卸载Bundle时关闭对应的Streampublic void UnloadBundleWithStream(AssetBundle bundle){if (activeStreams.ContainsKey(bundle)){activeStreams[bundle].Close();activeStreams.Remove(bundle);}bundle.Unload(false);}private Stream GetCustomDataStream(string bundleId){// 这里实现你的自定义数据源逻辑// 比如从数据库、网络服务或加密文件中获取数据return null;}void OnDestroy(){// 清理所有活跃的Streamforeach (var stream in activeStreams.Values){stream?.Close();}activeStreams.Clear();}
}

性能对比和选择建议

性能排序(从快到慢)

  1. LoadFromFile - 内存映射,性能最佳
  2. LoadFromStream - 流式访问,适中
  3. LoadFromMemory - 需要数据拷贝,较慢
  4. UnityWebRequest - 网络延迟,最慢

选择合适的 AssetBundle 加载方式需根据项目需求和资源特点进行权衡。

加载方式场景优点缺点
同步加载

LoadFromFile

小型资源、预加载简单、快速阻塞主线程
异步加载

LoadFromFileAsync

大型资源、后台加载不阻塞主线程、支持进度实现复杂

从内存加载

LoadFromMemory

网络下载、加密资源灵活、支持加密内存占用高

从网络加载

UnityWebRequestAssetBundle

热更新、在线资源支持异步下载和加载依赖网络

流式加载

LoadFromStream

流式传输、大文件加载支持分块加载实现复杂

在实际开发中,开发者应结合内存管理、性能优化和用户体验需求选择加载方式。小型资源可用同步加载快速处理,大型资源或动态加载场景推荐异步加载,而热更新和在线资源则优先考虑网络加载方式。通过合理规划,可确保游戏运行流畅并提升用户体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/86533.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/86533.shtml
英文地址,请注明出处:http://en.pswp.cn/web/86533.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙边缘智能计算架构实战:多线程图像采集与高可靠缓冲设计

目录 一、技术背景与挑战二、鸿蒙边缘计算架构的核心特性1. 分布式软总线&#xff1a;打破设备孤岛2. 轻量化多线程模型 三、多线程图像采集的稳定性设计1. 分层缓冲队列架构2. 线程优先级策略 四、边缘侧高可靠缓冲机制1. 基于分布式数据管理的容错设计2. 动态带宽调节 五、实…

excel中vba开发工具

1、支持单元格点击出现弹框进行选择 支持模多次模糊查询 Private Sub CommandButton1_Click() Call vehicle_查询 End SubPrivate Sub Worksheet_Activate()Call vehicle_取出车架号和公司名称 取出不重复的车架号Sheet13.ComboBox1.Visible False 车架号显示Sheet13.ComboB…

CatBoost:征服类别型特征的梯度提升王者

基于有序提升与对称树的下一代GBDT框架&#xff0c;重塑高维分类数据处理范式 一、CatBoost的诞生&#xff1a;解决类别特征的终极挑战 2017年由俄罗斯Yandex团队开源&#xff0c;CatBoost&#xff08;Categorical Boosting&#xff09;直指机器学习中的核心痛点&#xff1a;类…

使用 WSL 启动ubuntu.tar文件

使用 WSL 启动ubuntu.tar文件&#xff0c;可按以下步骤进行3&#xff1a; 检查 WSL 版本&#xff1a;确保你的 WSL 版本为 2.4.8 或更高版本。可以在命令行中输入wsl --update来更新 WSL 到最新版本。 设置默认 WSL 版本&#xff1a;如果还没有将 WSL 2 设置为默认版本&#x…

vue-23(创建用于逻辑提取的可重用组合组件)

创建用于逻辑提取的可重用组合组件 可重用的组合式是 Vue 组合式 API 的基石&#xff0c;它使你能够在多个组件中提取和重用有状态逻辑。这有助于编写更清晰的代码&#xff0c;减少冗余&#xff0c;并提高可维护性。通过将特定功能封装到组合式中&#xff0c;你可以轻松地共享…

数据透视表学习笔记

学习视频&#xff1a;Excel数据透视表大全&#xff0c;3小时从小白到大神&#xff01;_哔哩哔哩_bilibili 合并行标签 初始数据透视表 不显示分类汇总 以大纲形式显示 在组的底部显示所有分类汇总 以表格形式显示 合并单元格-右键-数据透视表选项 选中-合并并剧中排列带…

吃透 Golang 基础:测试

文章目录 go test测试函数随机测试测试一个命令白盒测试外部测试包 测试覆盖率基准测试剖析示例函数 go test go test命令是一个按照一定的约定和组织来测试代码的程序。在包目录内&#xff0c;所有以xxx_test.go为后缀名的源文件在执行go build时不会被构建为包的一部分&#…

酒店服务配置无门槛优惠券

1.查看酒店绑定的是那个仓库&#xff1b; 凯里亚德酒店(深圳北站壹城中心店)&#xff0c;绑定的是“龙华民治仓&#xff08;睿嘀购” 2.“门店列表”选择“龙华民治仓&#xff08;睿嘀购””中的“绑定场所” 3.通过酒店名字查找绑定的商品模板&#xff1b; 凯里亚德酒店(深圳…

IoT创新应用场景,赋能海外市场拓展

在数字化浪潮席卷全球的当下&#xff0c;物联网&#xff08;Internet of Things, IoT&#xff09;正以革命性的力量重塑产业生态。这项通过传感器、通信技术及智能算法实现设备互联的技术&#xff0c;不仅推动全球从“万物互联”迈向“万物智联”&#xff0c;更成为赋能企业开拓…

Idea中Docker打包流程记录

1. maven项目&#xff0c;先打package 2.添加Dockerfile 3.执行打包命令 注意最后的路径 . docker buildx build -t xxx-app:版本号 -f Dockerfile . 4.下载文件 docker save -o xxx-app-版本号.tar xxx-app:版本号 5.加载镜像 docker load -i xxx-app-版本号.tar 6.编…

硬件工程师笔试面试高频考点-电阻

目录 1.1 电阻选型时一般从哪几个方面进行考虑? 1.2上拉下拉电阻的作用 1.3 PTC热敏电阻作为电源电路保险丝的工作原理 1.4 如果阻抗不匹配&#xff0c;有哪些后果 1.5 电阻、电容和电感0402、0603和0805封装的含义 1.6 电阻、电容和电感的封装大小与什么参数有关 1.7 …

小程序入门:小程序 API 的三大分类

在小程序开发中&#xff0c;API&#xff08;Application Programming Interface&#xff09;起着至关重要的作用&#xff0c;它为开发者提供了丰富的功能和能力&#xff0c;使我们能够创建出功能强大、用户体验良好的小程序。小程序 API 大致可分为以下三大分类&#xff1a;事件…

算法第55天|冗余连接、冗余连接II

冗余连接 题目 思路与解法 #include <iostream> #include <vector> using namespace std; int n; // 节点数量 vector<int> father(1001, 0); // 按照节点大小范围定义数组// 并查集初始化 void init() {for (int i 0; i < n; i) {father[i] i;} } //…

Docker单独部署grafana

Docker单独部署grafana 环境说明 操作前提&#xff1a; 先去搭建PC端的MySQL和虚拟机 自行找参考 Linux部署docker参考文章&#xff1a; 02-Docker安装_docker安装包下载-CSDN博客 本文参考文章&#xff1a; 运维小记 说明&#xff1a; 本文的操作均以搭建好的PC端的MySQL和虚…

【数据分析,相关性分析】Matlab代码#数学建模#创新算法

【数据分析&#xff0c;相关性分析】118-matlab代码 #数学建模#创新算法 相关性分析及绘图 基于最大互信息系数的特征筛选 最大互信息系数 皮尔逊相关系数 spearman相关系数 kendall秩相关系数 请自带预算时间与需求以便高效沟通&#xff0c;回复超快&#xff0c;可以加急…

浅谈C++ 中泛型编程(模版编程)

C 是一种强大且灵活的编程语言&#xff0c;支持多种编程范式&#xff0c;使得开发者能够选择最适合特定问题的解决方案。在实际开发中&#xff0c;面向对象编程、泛型编程、函数式编程和元编程是最常用的几种范式。 今天主要与大家一起来介绍和学习泛型编程&#xff08;即模版…

iOS开发中的KVO以及原理

KVO概述 KVO(Key-Value-Observing)是iOS开发中一种观察者模式实现&#xff0c;允许对象监听另一个对象属性的变化。当被观察属性的值发生变化时&#xff0c;观察者会收到通知。KVO基于NSKeyValueObserving协议实现&#xff0c;是Foundation框架的核心功能之一。 1.KVO的基本使…

雷卯针对灵眸科技EASY Orin-nano RK3516 开发板防雷防静电方案

一、应用场景 1. 人脸检测 2. 人脸识别 3. 安全帽检测 4. 人员检测 5. OCR文字识别 6. 人头检测 7. 表情神态识别 8. 人体骨骼点识别 9. 火焰检测 10. 人脸姿态估计 11. 人手检测 12. 车辆检测 13. 二维码识别 二、 功能概述 1 CPU&#xff1a;八核64位ARM v8处…

中国双非高校经费TOP榜数据分析

当我们习惯性仰望985、211这些“国家队”时&#xff0c;一批地方重点支持的高校正悄悄发力&#xff0c;手握重金&#xff0c;展现出不逊于名校的“钞能力”。特别是“双非”大学中的佼佼者&#xff0c;它们的年度经费预算&#xff0c;足以让许多普通院校望尘莫及。 今天就带大…

C++ Lambda表达式详解:从入门到精通

Lambda表达式是C11引入的最重要特性之一&#xff0c;它彻底改变了我们在C中编写函数对象的方式。本文将带你全面掌握Lambda表达式的使用技巧&#xff01; 1. 什么是Lambda表达式&#xff1f; Lambda表达式是C11引入的一种匿名函数对象&#xff0c;它允许我们在需要函数的地方…