Unity资源管理和策略
发布日期:2021-05-10 06:02:07 浏览次数:25 分类:精选文章

本文共 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些其它优化方法

比如对场景资源的优化、材质对象的优化等。

这些需要结合项目实际情况来决定。

思考到这里,才发现优化资源的工作做起来有点像搭积木。没有一种方法绝对完美,只能找到最适合的方案。


后记

这篇文章是我在实际项目中面临的一些问题总结。内容可能不那么系统,逻辑处理上也还有些欠缺。但希望能对一些刚入行的小伙伴有什么帮助。看起来这篇文章越来越像我的个人技术博客,呵呵。

上一篇:番茄工作法——总结笔记
下一篇:Mac、移动端的抓包方式和注意事项——Charles

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2025年04月19日 05时34分28秒