【系统】Unity3D中的AssetBundle资源管理器(三)

前言

上一次讲到了用asset做资源管理,但是在asset的管理的时候,我们是同步把所需要的asset全部都加载出来的,前段时间看了下别人的管理机制,发现可以用unity的资源加载依赖来做这件事,就是不用我们自己加载asset,而是改用记录asset的依赖就好了。

正文

基于unity自身的依赖加载

在以前我们了解过,unity在加载一个资源的时候,如果它所依赖的assetbundle已经被打开了,那当我们加载它的时候,unity会自动把它所依赖资源一起加载出来,让asset能正常使用。在这个情况下,那当我们在根据asset来记录依赖的时候,我们只需要把它依赖的asset所在的assetbundle给加载出来,然后去对asset做一个引用计数的记录,这样的话,我们就可以省下去做加载依赖的asset这步的操作。在上一次我们所测试下来的结果,让我在这个版本做的方案就是,对assetbundle的卸载使用true这个参数,让它完全卸载掉。所以asset对于我来说就是一个做依赖关系绑定的用途。

改用异步的方式来做资源加载

在体验游戏的时候,我们可能最讨厌的就是界面卡顿,当点一个按钮需要打开一个界面的时候,我们发现,界面需要很久才出现,在等待的时候,我们会产生点击失败的感觉,这样很影响用户体验了。这种卡顿在我之前的方案里,很大一部分是因为我使用的是同步加载接口,它会阻塞住线程,等待资源全部加载回来才结束。这样的结果不是我们想要的表现方式。所以我改成用异步的方案来加载资源。但是在加载的时候,因为是异步,所以也会出现加载资源回来的顺序不一定是按照我们加载之前的顺序回来的。而且要抵消全部加载回来才显示的问题,我们可以做一个UI表现的动效,来抹平加载时间内的UI没有资源展示。

加载方案

当我们加载一个UI界面的时候,我们可以用对这个UI界面所需要的资源进行一个大的分类,如果是那种滑动列表内的资源,我们可以做一个优先级比较低的加载顺序,然后滑动列表加载进来的时候,做一个进入动画。那界面上顺序比较高的是哪个呢?我认为应该是玩家第一眼就能见到的界面,当我们在加载回来之后就可以直接显示了,那些一开始让玩家见不到面的资源,就可以在播动效的时候,再加载回来,其实不会慢很多,但是我们这样做就可以及时响应玩家的操作。我们需要给资源做一个引用列表,哪几个需要显示的prefab在引用它,还要记录一个状态,如果在加载中,所有需要引用的资源直接添加到引用列表里,如果它已经加载成功了,那就直接返回回调。

骚操作(我一般叫奇巧淫技)

在unity自带的资源依赖管理里,我们在加载出来一个prefab的时候如果它的资源没有加载成功,但是我们现实出来,它是会变紫红色的,但是,如果我们在接下来的时间内能加载出它依赖的asset所在的assetbundle的话,unity就会自动把资源赋值上去,正常现实的。所以在加载如果玩家看不到的资源,我们就可以一开始不用理会,只要第一眼能看到的资源以及加载成功了,我们就可以直接显示prefab。这里我就不知道如果出现这样的情况在unity底层会不会有cpu的消耗,一直在找丢失的资源。

卸载方案

如果我们使用了异步来做资源管理的话,会出现一个问题,就是我们如果这个资源还在加载的时候,我们就已经要把它卸载了,那我们就要在资源加载结束的时候做一个判断,这个资源是不是还用。所以我们需要给这个资源的回调做一个管理,如果不需要的话,我们就把回调事件-1,当资源加载回来之后,发现自己没有任何一个资源需要引用了,那它就把自己的状态变成卸载状态,等待下一次的回收。

资源的引用计数的问题

在之前我们所做的所有方案都是在一个理想的状态下做的,如果我们生成的一个prefab的资源,它被clone了,直接走unity的实例化,然后再把它给赋值到一个其他的地方,这个时候我们是不知道它真实的生命周期,这样的情况下,我如果默认它的生命死亡时间是跟某一界面,或者某一模块相关的话,那我们卸载了资源,它在别的地方的实体就会出现紫红色,然后出现问题。所以这种情况下,我现在想到的办法就是框架限制,资源的生命周期就限制死了,不能其他的地方使用我这个里面的资源,你要用自己去加载去。这样的话就能暂时解决了。其实这种方案也是有问题的,靠自觉,不知道什么时候就会出现问题的。只能等下一次解决了。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注