管理已加载的 AssetBundle
管理已加载的 AssetBundle
另请参阅:Unity 学习教程 - 管理已加载的 AssetBundle (Managing Loaded AssetBundles)
从活动场景中删除对象时,Unity 不会自动卸载对象。资源清理在特定时间触发,也可以手动触发。
了解何时加载和卸载 AssetBundle 非常重要。不正确地卸载 AssetBundle 会导致在内存中复制对象或其他不良情况,例如缺少纹理。
关于 AssetBundle 管理最重要的事情就是何时调用
AssetBundle.Unload(bool); 以及应该将 true 还是 false 传递给函数调用。Unload 是一个非静态函数,可用于卸载 AssetBundle。此 API 会卸载正在调用的 AssetBundle 的标头信息。该参数指示是否还要卸载通过此 AssetBundle 实例化的所有对象。
AssetBundle.Unload(true) 卸载从 AssetBundle 加载的所有游戏对象(及其依赖项)。这不包括复制的游戏对象(例如实例化的游戏对象),因为它们不再属于 AssetBundle。发生这种情况时,从该 AssetBundle 加载的纹理(并且仍然属于它)会从场景中的游戏对象消失,因此 Unity 将它们视为缺少纹理。
假设材质 M 是从 AssetBundle AB 加载的,如下所示。
如果调用 AB.Unload(true),活动场景中的任何 M 实例也将被卸载并销毁。
如果改作调用 AB.Unload(false),那么将会中断 M 和 AB 当前实例的链接关系。
如果稍后再次加载 AB 并且调用 AB.LoadAsset(),则 Unity 不会将现有 M 副本重新链接到新加载的材质。而是将加载 M 的两个副本。
通常,使用 AssetBundle.Unload(false) 不会带来理想情况。大多数项目应该使用 AssetBundle.Unload(true) 来防止在内存中复制对象。
大多数项目应该使用 AssetBundle.Unload(true) 并采用一种方法来确保对象不会重复。两种常用方法是:
在应用程序生命周期中具有明确定义的卸载瞬态 AssetBundle 的时间点,例如在关卡之间或在加载屏幕期间。
维护单个对象的引用计数,仅当未使用所有组成对象时才卸载 AssetBundle。这允许应用程序卸载和重新加载单个对象,而无需复制内存。
如果应用程序必须使用 AssetBundle.Unload(false),则只能以两种方式卸载单个对象:
在场景和代码中消除对不需要的对象的所有引用。完成此操作后,调用 Resources.UnloadUnusedAssets。
以非附加方式加载场景。这样会销毁当前场景中的所有对象并自动调用 Resources.UnloadUnusedAssets。
如果不想自己管理加载资源包、依赖项和资源,可能需要使用 Addressable Assets 包。