unity 资源加载框架设计

本文介绍了一种Unity资源加载框架的设计思路,旨在实现增量更新、减小安装包体积及提高资源加载速度。通过将资源组织成不同的AssetBundle,并定义其依赖关系,能够有效地管理游戏内的各种资源。

本篇文章主要介绍了"unity 资源加载框架设计",主要涉及到unity 资源加载框架设计方面的内容,对于unity 资源加载框架设计感兴趣的同学可以参考一下。

目的

便于增量更新功能的实现

降低安装包大小,unity不支持过滤掉Resources目录中不用的文件。

用AB包的方式加快资源文件的读取速度

生成asset bundle文件

基本流程如下图所示, 后面会详细说明。

BundleResources目录的资源组织

现在游戏中的资源放在Resources目录中,需要把这些资源按照一定的规则移动到BundleResources目录中。并且这个文件组织规则需要告知策划,美术,以后策划美术就把资源放到对应的目录中。下图是基本的组织方式。

 

游戏中的UI用到的图片分三个目录组织,如上图所示,Common目录存放战斗和主城共用的资源, Battle存放战斗用到的资源,City存放主城用到的资源。

UI目录存放美术做的UI Prefab,Battle存放战斗用到的UI prefab,City存放主城用到的UI prefab。

LUA文件不放在这里,直接把LUA文件copy到StreamingAssets下面的一个子目录。

 

为文件或者文件夹指定asset Label

指定asset Label是为了后面打AB包用,一个原则是如果很多相同类型的文件需要几乎同时读入内存,比如Atalas图集,一个场景用到的所有音效等。

上图中目录atalas下每个子目录一个AB包。

上图中目录Audio下每个子目录一个AB包。

其余每个文件一个AB包。

打包

调用API BuildPipeline.BuildAssetBundles 打包,这个函数有三个参数

outputPath

Output path for the AssetBundles.

assetBundleOptions

AssetBundle building options.

targetPlatform

Chosen target build platform.

outputPath 为StreamingAssets/BundleResources

assetBundleOptions为BuildAssetBundleOptions.None, 默认用LZMA格式压缩,好处是包会小一点,坏处是打开AB包时需要解压缩。还有两个选项,Chunk Compressed (LZ4)和Uncompressed 这两种方式性能上有优势,但包体会变大。参考这里:https://docs.unity3d.com/Manual/AssetBundleCompression.html

targetPlatform 为打包的目录平台,android, ios or windows.参考这里https://docs.unity3d.com/ScriptReference/BuildTarget.html

生成每个AB包的信息

AB包生成后,我们需要维护每个AB包的信息,所有AB包的信息保存在一个json文件中,用于打开AB包时使用。每一个AB包会生成如下的信息:

bundlePath是在第2步给该文件指定的asset Label,这个路径也是它在StreamingAsset/BundleResources s目录中的路径。

bundleHash 是根据bundlePath生成的一个Hash值。最后一个字段deps里会用到这个值。

Crc 和 hash128是AB包的校验值,用于增量更新时的校验,调用BuildPipeline.GetCRCForAssetBundle和BuildPipeline.GetHashForAssetBundle获得

Deps 是该AB包所依赖的包的bundlePath的hash值。通过调用API AssetBundleManifest.GetDirectDependencies获得。当读取一个AB包时,会把AB包依赖的AB包先读出来。

读取asset bundle文件

所有读取操作都是异步的,调用者需要提供回调函数,读取完成后会调用该函数,参数包含已实例化的对像。

提供3个接口用来读取AB包:

1.     读取一个Scene文件生成的AB包,Scene加载完成调提供的回调函数;

2.     读取一个AB包,该AB包中只包含一个文件,调用者只需要提供文件路径,AB包的包名通过文件路径自动获得。加载完成调提供的回调函数;

3.     读取一个AB包中的一个文件,该AB包中只包含多个文件,加载完成调提供的回调函数;

提供1个接口用来释放对象

针对每个被读取的Gameobject,会生成一个对象池,当调用者不用这个对象时,调用Free函数,该对象会放到对象池中,供下次调用使用。

读取的逻辑如下图所示:


### Unity 中的资源加载方法 在Unity3D开发过程中,为了优化游戏性能、减少内存占用并提升用户体验,合理规划资源加载与卸载至关重要[^2]。以下是几种常见的资源加载方式: #### 使用 `Resources` 文件夹加载资源 这是最简单的方式之一,在项目中创建名为 `Resources` 的特殊文件夹,并将需要动态加载资源放置其中。通过调用静态类 `Resources.Load<T>(string path)` 方法来获取指定路径下的对象实例。 然而这种方式存在局限性,比如无法精确控制何时释放不再使用的资产;另外当工程规模较大时容易造成不必要的膨胀,因此建议谨慎采用此法作为主要手段[^4]。 ```csharp // 加载纹理 Texture2D texture = Resources.Load<Texture2D>("Textures/my_texture"); ``` #### 利用 AssetBundle 进行打包管理 对于大型项目而言更推荐的做法是构建自定义的AssetBundles来进行分组式的资源整合[^1]。这不仅有助于按需下载特定场景所需的数据集合,而且能够有效降低初次启动时间以及整体安装包大小。 具体操作上先要在编辑器端完成打包流程,之后运行期间可通过网络请求或者本地存储读取对应名称前缀匹配的目标bundle文件,再利用其提供的接口如 `LoadAsset()` 或者泛型版本的方法取得内部含有的任意类型实体[^3]。 ```csharp using UnityEngine; using System.Collections; public class Example : MonoBehaviour { IEnumerator Start () { using (WWW www = new WWW("file://path_to_your_bundle")) { yield return www; } AssetBundle bundle = www.assetBundle; GameObject prefab = bundle.LoadAsset<GameObject>("prefab_name").Instantiate(); } } ``` #### 借助 Addressables 实现现代化解决方案 Addressable Assets 是官方推出的新一代资产管理工具集,旨在解决传统模式下遇到的各种痛点问题。它允许开发者以更加灵活高效的方式来组织处理各种类型的素材,支持异步预加载、缓存策略配置等功能特性。 借助于这套框架可以轻松实现跨平台兼容性的部署方案,同时也简化了多语言适配和支持热更新等复杂业务逻辑的设计难度。 ```csharp await Addressables.InstantiateAsync("address_key_here"); ``` ### 最佳实践总结 - **评估需求**:根据项目的实际情况权衡不同加载机制之间的优劣之处; - **测试验证**:确保所选途径能够在目标设备上稳定工作且满足预期效果; - **持续迭代改进**:随着产品演进不断调整和完善现有的资源配置计划。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值