当前位置: 首页 > news >正文

【教程】Unity AssetBundle 资源管理方法

开发平台:Unity 2020版本以上
编程平台:Visual Studio 2022

一、前言


  在 Unity 中,“资源管理与使用” 是开发者必修内容。受限制于 项目目标平台、用户设备类型 等因素,资管管理方案不一。本文重点记录 Unity - AssetBundle 资源加载模式。

二、Resourse 与 AssetBundle


2.1 Resources 资源管理方式

  1. 无法对 Component、GameObject 等对象做到 “即用即卸载”,最终将影响运行时内存占用与其他性能开销。
  2. Resources 内所有资产将被 Unity 构建过程中打入应用体量内,对于大型资产的项目中进行资产更新将是困难的。

2.2 选择 AssetBundle 的理由

  • 有效解决商业项目中初次 "下载体量大"的特点。
    • 参考《小鳄鱼爱洗澡》以抢先体验前几关,后续游玩采取 "逐关下载,快速体验" 的策略。
      该策略让用户无需等待太长时间即可体验内容,进而更可能保留用户群体。
  • 设备内存管理优异,设备表现上优异。

三、资产加载 | AssetBundle


1)本地加载 AssetBundle 资产

string path = $"{Application.streamingAssetsPath}/Cube";
string modelName = "cube";public void Start() {AssetBundle thisAB = AssetBundle.LoadFromFile(path);GameObject thisAsset = thisAB.LoadAsset<GameObject>(modelName );MonoBehaviour.Instantiate(thisAsset);
}

2)使用 UnityWebRequestAssetBundle 加载 AssetBundle 资源

string downloadURL = $"  ---------------------------------------   ";
string modelName = $" ---------------------- ";private IEnumerator Start() {var thisRequst = UnityWebRequestAssetBundle.GetAssetBundle(downloadURL);yield return thisRequest.SendWebReqeust();AssetBundle thisBundle = DownLoadHandlerAssetBundle.GetContent(thisRequest);var thisLoadAsset = bundle.LoadAssetAsync<GameObject>(modelName);yield return loadAsset;Instantiate(loadAsset.asset);
}

3)异步加载资源

在这里插入代码片

四、依赖资产 | AssetBundle


在修改部分资源内容时,会出现资源依赖关系丢失的问题,例如 Material、Mesh 等。为防止各资源包中的引用丢失情况,提出加载前优先加载关联资源后再加载本资源对象。

除游戏对象生成的 assetbundle 文件,还会额外生成该目录下的 assetbundle 文件。该文件记录本次输出 assetbundle 对象群的所有外部依赖关联信息。例如在 StreamingAssets 目录下输出 Cube 的 assetbundle 文件,会额外产出命名 StreamingAssets.aseebundle 文件。

示例代码:

string manifestPath = $"{Application.streamingAssetsPath}/StreamingAssets";
string path = $"{Application.streamingAssetsPath}/cube";
string modelName = "cube"void Start() {// 加载依赖AssetBundle thisABDep = AssetBundle.LoadFromFile(manifestPath);var manifest = thisABDep.LoadAsset<AssetBundleManifest>("AssetBundleManifest");string[] dependcies = manifest.GetAllDependencies("cube");Array.ForEach(dependcies, e => AssetBundle.LoadFromFile($"{Application.streamingAssetsPath}/{e}"));// 加载模型var assetGameObject = thisAB.LoadAsset<GameObject>("cube");MonoBehaviour.Instantiate(assetGameObject);// 加载资产依赖资产Array.ForEach(dependcies, e => AssetBundle.LoadFromFile(e));
}

图1 Assetbundle 生成目录
图2 Aseetbundle 目录下所有AB的依赖关联信息

4.1 加载 Manifest

AssetBundle thisABDep = AssetBundle.LoadFromFile(manifestPath);
  • manifestPath 是 AssetBundle - Browsers 本次导出所有资产的依赖关系文件。
  • 该 Manifest 文件名以存储目录文件名为命名,并规定存储在该目录文件夹内。

4.2 AssetBundleManifest | 跳转

var manifest = thisABDep.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
  • 这段代码获取依赖信息下关于 AssetBundleManifest 的信息内容,详细参考上 图2。

五、资产加载 | 流程


5.1 关于存储数据结构

  使用环境中,多为单场景跳转时对上一场景的加载资源进行卸载,并准备当前场景的资源加载。而 AssetBundle 包加载 禁止重复加载。为管理与校验是否多次加载。需要定义数据结构管理已加载的 AssetBundle 对象。

public Dictionary<string, AssetBundle> AssetBundleDic { get; set; } = new();
  • 此处使用 Dictionary 作为 AssetBundle 管理

5.2 关于主要包体(可选)

public AssetBundle MainAssetBundle;

  即所有 AssetBundle 的依赖关系包对象。参考 [本博文] 4.2 AssetBundleManifest 的解释。 该 AssetBundle 包体仅需加载一次即可。故作为单独使用。当然通过 Dictionary 中判断是否加载也可。

5.3 关于多平台下包名差异

public string MainAssetBundle {get {
#if UNITY_IOSreturn "Ios";
#elif UNITY_ANDROIDreturn "Android";
#else return "Windows"
#endif}
}
  1. 对于多平台发布会涉及 AssetBundle 不一的情况,考虑主依赖包信息的命名差别,使用 宏定义
  2. 参考 [本博文] 4.1 加载Manifest 加载所有依赖项。

5.4 关于卸载

当 GameObject 被实例化至场景后,该 AssetBundle 内资产将被记入内存中。执行 UnLoad 后,并不影响已实例化在场景内的所有资源。

http://www.lryc.cn/news/610742.html

相关文章:

  • STM32F407VET6学习笔记10:移植smallmodbus
  • 【LeetCode 热题 100】347. 前 K 个高频元素——(解法一)排序截取
  • Redis类型之String
  • 【npm 解决】---- TypeError: crypto.hash is not a function
  • GPS信号捕获尝试
  • 【机器学习深度学习】模型剪枝
  • Python包安全工程实践:构建安全可靠的Python生态系统
  • 【学习笔记】NTP时间同步验证
  • 期权定价全解析:从Black-Scholes到量子革命的金融基石
  • Linux 逻辑卷管理:LVM 原理与 Stratis、VDO 特性对比
  • 基于 Spring Boot 的小区人脸识别与出入记录管理系统实现
  • 力扣经典算法篇-43-全排列(经典回溯问题)
  • css3属性总结和浏览器私有属性
  • Python、Java、C#实现浮点型转换为转型
  • Mysql使用Canal服务同步数据->ElasticSearch
  • 电子秤利用Websocket做为Client向MES系统推送数据
  • 文件编译、调试及库制作
  • 跑yolov5的train.py时,ImportError: Failed to initialize: Bad git executable.
  • 前端实现Excel文件的在线预览效果
  • 【机器学习】算法调参的两种方式:网格搜索(枚举)、随机搜索
  • 【力扣 Hot100】 刷题日记
  • Python分块读取大型Excel文件
  • 豆包新模型与 PromptPilot 实操体验测评,AI 辅助创作的新范式探索
  • LangGraph学习笔记 — LangGraph中State状态模式
  • 自动驾驶控制算法——MPC控制算法
  • qq scheme
  • GaussDB 并行创建索引
  • 使用iptables的nat链表进行端口转发
  • 基于MATLAB实现的频域模态参数识别方法
  • 算法3. 无重复字符的最长子串