【Unity】AB包资源管理(二)

时间:2025-03-08 20:46:13

一、概述

由本地存储上的文件(在Unity缓存中或通过加载的文件)支持的AssetBundle具有最小的内存开销,很少消耗超过几十KB的内存。但是,如果存在大量资源依赖关系,则此开销仍然会成为问题(仅是文件头的问题

二、 AB包卸载

由于大多数项目允许用户重复体验内容,因此了解何时加载或卸载资产绑定非常重要。如果未正确卸载AssetBundle,可能会导致内存中的对象重复。在某些情况下,不正确地卸载资产绑定也可能导致不良行为,例如导致纹理丢失。

管理资产和资产绑定时需要了解的最重要的一点是调用时的行为差异,即unloadAllLoadedObjects参数为true或false。

此API将卸载正在调用的AssetBundle的头信息。unloadAllLoadedObjects参数确定是否也卸载从该AssetBundle实例化的所有对象。如果设置为true,则源自AssetBundle的所有对象也将立即卸载–即使它们当前正在活动场景中使用。

例如,假设材质M是从AssetBundle AB加载的,并且假设M当前在活动场景中。

如果调用(true),那么M将从场景中移除、销毁并卸载。但是,如果调用(false),则AB的头信息将被卸载,但M将保留在场景中,并且仍然可以正常工作。调用(false)会中断M和AB之间的链接。如果以后再次加载AB,则AB中包含的对象的新副本将加载到内存中。

如果以后再次加载AB,则会重新加载资产绑定头信息的新副本。但是,M不是从AB的新副本加载的。Unity不会在AB的新副本和M之间建立任何链接。

如果调用()重新加载M,Unity将不会将M的旧副本解释为AB中数据的实例。因此,Unity将加载M的新副本,并且场景中将有两个相同的M副本。

然而对于大多数项目而言,这种行为是不可取的。大多数项目应该使用(true)并采用一种方法来确保对象不重复。两种常用方法是:

(1)在应用程序的生命周期中设置一些卸载资源绑定的节点,例如场景切换时。

(2)维护单个对象的引用计数,并仅在其所有组成对象都未使用时卸载资产绑定。这允许应用程序卸载和重新加载单个对象,而无需复制内存。

如果应用程序必须使用(false),则只能通过两种方式卸载单个对象:

(1)消除对不需要的对象的所有引用。然后调用。

(2)以非添加方式加载场景(这里如果不懂的话可以考虑看下场景加载模式)。这将销毁当前场景中的所有对象并自动调用。

在决定如何将对象分组到AssetBundles中时,如果必须同时加载或更新对象,通常最好先将对象绑定到AssetBundles中。例如,在RPG游戏设计时。可以按场景将单独的贴图和剪切场景分组到组合框中,但大多数场景中都需要一些对象。可以构建AssetBundles来提供肖像、游戏中的UI以及不同的角色模型和纹理。这些后一种对象和资产可以分组到第二组资产绑定中,这些资产绑定在启动时加载,并在应用程序的生命周期内保持加载状态。

如果Unity在卸载AssetBundle后,从AssetBundle重新加载对象,则会出现另一个问题。在这种情况下,重新加载将失败,对象将作为(缺少的)对象出现在Unity编辑器的层次结构中。

这主要发生在Unity失去并重新控制其图形上下文时,例如当移动应用程序挂起或用户锁定其PC时。在这种情况下,Unity必须将纹理和着色器重新上载到GPU。如果这些资源的源AssetBundle不可用,则应用程序将以洋红色渲染场景中的对象(这里是游戏开发人员需要额外注意的内容)。