AssetBundle详解-03

277 阅读2分钟

「这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战」。

作为一名优秀的开发者,对于技术的探求应该是永无止步的,如何让自己更进步,那就只有不停的学习,不停的充电.而这些都都是说起来容易做起来难,坚持才是难的地方 --蛙哈哈

AssetBundle详解-03

1.AB使用-卸载

如果说AssetBundle真的有什么容易出问题的地方,那恐怕就是卸载了。

public void Unload(bool unloadAllLoadedObjects);

一个被加载过的AssetBundle可以通过调用Unload来卸载这个Bundle下所有的Asset。但是调用这个函数时传入的参数对卸载结果影响甚大。

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

如果使用不当就很容易出现以下情形:

image-20220218205130758.png

image-20220218205140017.png

2.举个例子

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

image-20220218205237176.png

如果调用了AssetBundle.Unload(true),那么M将从场景中移除,销毁并卸载。但是,如果调用AssetBundle.Unload(false),则AB的标题信息将被卸载,但M仍将保留在场景中并且仍然有效。调用AssetBundle.Unload(false)会中断M和AB之间的链接。

image-20220218205251829.png

如果稍后再次加载AB,则将重新加载AssetBundle标题信息的新副本。但是,M没有从AB的这个新副本中加载。Unity不会在AB和M的新副本之间建立任何关联。

image-20220218205307665.png

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

image-20220218205328356.png

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

在应用程序的整个生命周期(例如加载屏幕期间.)卸载临时AssetBundles时具有明确定义的点。这是更简单和最常见的选择。

仅当各个对象的所有构成对象都未使用时,才维护各个对象的引用计数并卸载AssetBundles。这允许应用程序卸载并重新加载单个对象而不复制内存。

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

消除场景和代码中对不需要的Object的所有引用。完成此操作后,调用Resources.UnloadUnusedAssets。

非加性地加载场景。这将破坏当前场景中的所有对象并自动调用Resources.UnloadUnusedAssets。