
本文共 2697 字,大约阅读时间需要 8 分钟。
Unity资源管理和策略
前言
好久没写博客了。其实原因很简单,平时工作忙,偶尔又-pillow fight—and sometime想偷懒做些collector的工作。我知道学习这种事情需要被逼才行,否则 haha 便会沉迷到视频游戏中。记得刚入职的时候写博客可真的是稀里 hafta,还记得当时的我可没现在懂得这么多东西了,但贫道下笔真是太畅快了。
不过回过头来看写博客确实是一种督促自己总结的好方法,虽然不知道有没有人看,也不知道写得有没有用,但总不能自己的知识白白浪费掉吧。希望以后的我能继续坚持下去吧。
资源加载
资源管理在d Unity 中绝对是个不小的课题,说难不难,说简单不简单。
可以从以下几个方面展开来谈:
1、加载路径 从哪里加载资源。
2、加载方式 用什么方式加载资源。
3、资源管理 如何合理加载和卸载资源。
4、资源优化 如何更高效地管理和使用资源。
一、加载路径
在Unity中,资源的加载路径主要有以下三种:Resources、AssetBundle和网络(当然如果需要从本地某个路径单独加载资源,我也没什么可说的)。
1(Resource)
这是Unity最基础的资源加载方式,也是初学者接触Unity时的必经之路。
本质上,Unity并不希望我们手动管理太多资源,所以帮了我们一个ResourceManager,供我们调用。Just call Load()就OK了。
听起来非常方便,对吧?但我们是否想得太过分了呢?当资源堆积 到后来,资源包就变得越来越大,加载时间越来越长管理起来也越发麻烦。
换个角度想象一下,把所有东西都塞进一个大背包里。想用到其中某个物品时,必须把整个背包倒地重新排列,物品数多就越费时间。又或者本地清理时需要扫一遍整张地,这种效率实在太低了。
简单总结:
- 内存管理越来越难。
- 加载时间越来越长。
- 维护性差不多是 conecticut road。
这种模式其实只是初期开发的好帮手,项目稍微大点就得考虑更好的方案了。
2(AssetBundle)
AssetBundle,简称AB包。别没听说过的小伙伴可以去其他文章(比如 )了解一下复杂点了。
相比Resource,AB包的优势说起来就多了。简单而灵活的使用方式,更高的管理灵活性。
当然管理起来也要付出更多的努力。你需要考虑AB包之间的依赖关系,如何确保被调用的AB包都提前加载好了,这是资源管理器的基本功。
3(Network)
网络加载资源主要是一种热更新的方式。把资源放在服务器上,客户端下载后再转成资源格式加载进游戏。
这种方式的好处是可以不在本地占用空间,同时支持动态更新。但也要考虑带来的一些问题,比如带宽压力和感知问题 (以后再补) .
二、加载方式
在资源加载过程中,read acheive 我们经常会遇到同步加载和异步加载两种方式。
同步加载-vs-异步加载
同期 | 异步 | |
---|---|---|
帧数 | 同一帧加载 | 跨帧加载 |
CPU使用率 | 全机率 | 非全机率 |
代码简洁性 | 最简单 | 最复杂 |
玩家反馈 | 增强反馈 | 最好反馈 |
资源管理 | 简单 | 必须面对依赖管理 |
细节分量 | 不需要分层 | 需要细分水次 |
对绝大多数项目而言,异步加载是提升游戏体验的不二选择。虽然代码会比较复杂,但代价是每一帧都能更好地提供游戏体验。
三、资源管理
资源管理是项目框架出场的时候的D&D里的关键环节。流程大概是这样的:
第一步:资源划分
合理划分资源池,对资源的粒度打完之后才会有后续工作。AB包的粒度决定了管理的复杂度和效率。
核心问题如下:
-
粒度越细,每个AB包内容越小,灵活性越高,但单次加载时间的总和也会增加。
-
粒度越大,AB包的数量越少,资源加载时间缩短,但灵活性就会有所降低。
最终需要权衡所有因素找到最佳平衡点。
第二步:加载模式的选择
划分好资源之后,下一步就是确定用什么方式加载资源。同步和异步两种方式各有千秋,选用哪种要看项目的实际需求。
第三步:依赖管理
AB包的核心特征之一是依赖关系 onBind Josh?
比如某个AB包中出现了一只Digimon但缺少一个物件,那这只Digimon是没法正常工作的。
对于资源管理器来说,最关键的问题是如何确保所需的依赖AB包已经加载到内存中。这就需要建立一个反向的依赖关系图,控制加载顺序,避免资源\Plugin加载失败。
也就是说,如果用到了WA Resource需要确保先加载了它所在的AB包,否则等到它用到的时候就会出现问题。
此外,如何避免资源冗余也非常重要。经常会发现某个被其他AB包直接引用到的地方,打成了一个新的AB包反而会浪费资源。
解决办法是将这些被复制的资源整合到一个公共的AB包中,或许我会偷懒就这样。
第四步:卸载的时机
卸载不是在加载就要考虑的吗?理论上,卸载的时机越准确越有利。
这里的关键点在于是并非都知道什么时候还会用到资源,因此可以卸载的问题就变成策略的问题了。
你的目标就是让资源的生命周期控制好,既保证灵活,又减少内存浪费。
四、资源优化
资源优化相比于前面的资源管理要容易绕的多。这里说一些比较实际的点。
1.Object Pool(对象池)
当你发现某个Resources会被频繁地引用,就开始考虑优化了。我们可以用对象池的方式来管理这种频繁加载的问题。
它的原理很简单:第一次加载资源后,不管以后需要多少次,都不要再去 Resources 里 Load这个资源,而是通过对象池来管理实例。
这种方式可以避免资源多次加载带来的内存浪费,同时减少了程序的开销。
2.Delayed Deallocate(延时卸载)
内存管理的艺术在于如何平衡及时释放资源和灵活使用资源。如果资源不用了,并马上释放,可能会导致资源被频繁复用。
延时卸载的策略可以帮助解决这个问题。比如规定在30秒内没用到该资源的情况下才释放内存。
3.Preload(预加载)
有些资源对游戏体验有很大影响,预加载是提高游戏运行速度的有效方法。可以在进入游戏前提前加载一部分资源。
不过需要注意的是预加载资源会占用内存,这就需要我们权衡资源预加载的空间成本和加载速度提升。
4.A些其它优化方法
比如对场景资源的优化、材质对象的优化等。
这些需要结合项目实际情况来决定。
思考到这里,才发现优化资源的工作做起来有点像搭积木。没有一种方法绝对完美,只能找到最适合的方案。
后记
这篇文章是我在实际项目中面临的一些问题总结。内容可能不那么系统,逻辑处理上也还有些欠缺。但希望能对一些刚入行的小伙伴有什么帮助。看起来这篇文章越来越像我的个人技术博客,呵呵。
发表评论
最新留言
关于作者
