在Unity中开始使用Addressable感觉还蛮良好的,从流程出发,可能差不多该从使用Resources文件夹的资产开发中走出来了。
不推荐Resources文件夹
Resources文件夹是方便读取资产的方法。
但是实际上通过Resources文件夹读取资产已经成为Unity作为公式不再推荐的方法。实际上,在官方的博客发文中,也进行了不要使用的说明。
Resources文件夹已弃用
Resources文件夹是快速加载资源的便捷方法。但是,Unity不再正式推荐从Resources文件夹加载资源。
为什么它被弃用了?
主要有以下三个原因:
- 精细的内存管理变得困难。
- 如果Resources中的资源较多,则应用程序的启动时间和构建时间会很长。
- 无法按照平台分配资源。
作为第一点的补充,Resources有一个Resources.UnloadAssets()
叫做Resources的API
,它只是简单地卸载资源,卸载包括严格的内存管理和使用引用计数器的依赖项,没有任何功能。
还有Resources.UnloadUnusedAssets()
一个API,但这是一个相当粗糙的功能,可以一次性卸载未使用的资源。
可以使用资源的情况
然而,仅在以下情况下才被认为是有用的功能。
- 原型创建时。
- 应用程序启动时驻留的资源。
- 当用于不消耗太多内存的事情时。
- 如果不需要在平台之间切换资源。
- 用于应用程序启动处理时。
除此之外,在为编辑器创建工具时应该使用很多案例。大家可以通过百度或者360搜索相关知识,有机会在做详细讲解吧。
使用Addressable资产系统
因此,不使用资源的情况下,可以使用可寻址资产系统,Addressable asset系统是Unity 2019.2或.3前后发布的资源管理机制。
使用地址加载
可寻址资产系统的一大特点是“地址”。
地址是可以为每个资产指定的任意名称,通过指定它来加载资源。

源代码看起来像这样:
// 使用地址加载
Addressables.LoadAssetAsync<GameObject>("ExamplePrefab");
通过一项设置即可在内置/DLC之间切换
此外,Addressable是在对开发工作流程有很强的意识的情况下制作的,只需切换设置项目即可更改,资产是包含在应用程序中还是下载的内容中。

无论哪种情况,加载方法都是相同的,只需切换设置即可。
Addressables.LoadAssetAsync<GameObject>( "ExamplePrefab" );
零成本从Prototype迁移到AssetBundle
Resources文件夹暂时在应用程序的原型和主要开发的初始阶段经常使用。在这种情况下,将通过指定Resources文件夹的相对路径来加载资源。
例如Assets/Resources/Prefabs/ExamplePrefab.prefab
,要读取它,请写:
Resources.LoadAsync("Prefabs/ExamplePrefab.prefab");
然而,随着项目的进展,需要将通过这种方式读取的资源移出Resources文件夹,并将它们剪切为AssetBundles。加载AssetBundle是使用AssetBundle名称和资源名称完成的。
var assetBundle = AssetBundle.LoadFromFile("SomeFolder/some_bundle.bundle");
assetBundle.LoadAssetAsync<GameObject>("Assets/Prefabs/ExamplePrefab.prefab");
那么,当然就需要对使用Resources编写的读取过程进行大幅度的修改。
另一方面,使用Addressable,只需按上述方式更改设置即可在内置内容和下载内容之间切换,因此无需像这样重写路径的成本。
严格的内存管理
Addressable还具有内部引用计数,可实现严格的内存管理,每次加载都会增加参考计数器。
// 参考计数器递增
var handle = Addressables.LoadAssetAsync<GameObject>("ExamplePrefab");
卸载会减少引用计数器,当它达到零时,资源将被卸载。
//参考计数器递减
//变成零后卸载
Addressables.Release(handle);
尝试使用Addressable作为Resources的替代品
现在实际使用可寻址资源系统而不是资源文件夹。
首先从包管理器安装Addressables,打开窗口Window > Asset Management > Addressables > Groups。

注册地址
默认情况下,Default Local Group是内置资源的组。请注意Built in Data,这些是构建设置中包含的场景和资源文件夹中的场景,它是灰色的,因为它不遵循Addressable机制(地址不能更改哦)。
因此,将Default Local Group一个合适的预制件拖放到此,输入适当的地址字符串,这次是用以下地址注册的。

编写读取脚本
然后编写一个加载此文件的脚本。
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class Example : MonoBehaviour
{
private AsyncOperationHandle<GameObject> _handle;
private async void Start()
{
// 加载与实例化
_handle = Addressables.InstantiateAsync("Example", Vector3.zero, Quaternion.identity);
await _handle.Task;
}
private void OnDestroy()
{
// 解放
Addressables.ReleaseInstance(_handle);
}
}
可以通过在编辑器中运行来检查GameObject是否正常生成。

构建实机
接下来,构建实际的机器,为了在实际机器上使用Addressable,需要构建Addressable。
选择从可寻址窗口进行构建:Build > New Build > Default Build Script

这个构建由Addressable内部使用的AssetBundle,以及地址和依赖信息。
内置的AssetBundle在应用程序构建时由Addressable资产系统包含在应用程序中(StreamingAssets),然后正常构建应用程序即可。

能够确认即使在实际的机器构建中也可以正常加载资源。
自动化Addressable构建
如果选中Unity 2021.2或更高版本和Addressables 1.19.4 ,Addressable Asset Settings则在构建播放器时也会构建Addressbles,在玩家构建中构建可寻址内容。

构建之前
构建Addressable既麻烦又容易忘记,所以将其自动化,当从构建窗口按下构建按钮时,还可以运行可寻址构建。
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;
public class AddressableBuilder
{
[InitializeOnLoadMethod]
private static void Initialize()
{
// 按下构建按钮
BuildPlayerWindow.RegisterBuildPlayerHandler(BuildPlayerHandler);
}
private static void BuildPlayerHandler(BuildPlayerOptions options)
{
// 必要时进行清理
AddressableAssetSettings.CleanPlayerContent(AddressableAssetSettingsDefaultObject.Settings.ActivePlayerDataBuilder);
// 构建Addressable
AddressableAssetSettings.BuildPlayerContent();
// 构建Player
BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(options);
}
}
由于上面的钩子按下了构建按钮,因此在从脚本构建时有必要编写一个单独的过程,希望可以用IPreprocessBuildWithReport
来做到这一点,但是用它构建Addressable时似乎会抛出异常。
另外,Addressable可以自己处理这个问题,但从性能的角度来看,这似乎是故意这样做的。
还支持同步加载
Addressables在Unity 2021.06.08新增的功能最初并不支持同步加载,因此,如果已经Resources.Load()
使用Addressables进行同步加载,则必须首先将它们设为异步。
但从Addressables 1.17.4版本开始,正式支持同步加载。由于存在一些使用注意事项,请参阅下面的文章吧,所以Resources.Load()
也是可以轻松更换的。
有用的工具介绍
最后,将总结一些与可寻址资产系统相关的有用的工具。
EZAddresser自动设置地址
Addressable中的地址设置很麻烦,必须一 一拖放,EZAddresser就是消除这种麻烦的工具,可以通过下文参阅。
使用EZAddresser,可以通过以下两个步骤轻松设置和读取地址。
- 将要加载的资源放入Addressables文件夹中。
- 调用
Addressables.LoadAssetAsync("[此处为资产的名称]")
。

Unity可寻址导入器
如果想更严格地管理地址,建议使用Unity Addressable Importer。
通过使用它,可以使用正则表达式指定目标资产并设置地址、组等。

…
以上是关于资源文件夹的全部内容。
如果你有任何反馈,请随时在本页面下方留言。