ue3dResources文件夹读取资产已是Unity不再推荐的方法

Resources文件夹读取资产已是Unity不再推荐的方法

分类:

在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是在对开发工作流程有很强的意识的情况下制作的,只需切换设置项目即可更改,资产是包含在应用程序中还是下载的内容中。

设置在内置/DLC之间切换

无论哪种情况,加载方法都是相同的,只需切换设置即可。

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。

Window > Asset Management > Addressables > Groups

注册地址

默认情况下,Default Local Group是内置资源的组。请注意Built in Data,这些是构建设置中包含的场景和资源文件夹中的场景,它是灰色的,因为它不遵循Addressable机制(地址不能更改哦)。

因此,将Default Local Group一个合适的预制件拖放到此,输入适当的地址字符串,这次是用以下地址注册的。

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是否正常生成。

检查GameObject

构建实机

接下来,构建实际的机器,为了在实际机器上使用Addressable,需要构建Addressable。

选择从可寻址窗口进行构建:Build > New Build > Default Build Script

Build > New Build > Default Build Script

这个构建由Addressable内部使用的AssetBundle,以及地址和依赖信息。

内置的AssetBundle在应用程序构建时由Addressable资产系统包含在应用程序中(StreamingAssets),然后正常构建应用程序即可。

正常加载资源

能够确认即使在实际的机器构建中也可以正常加载资源。

自动化Addressable构建

如果选中Unity 2021.2或更高版本Addressables 1.19.4 ,Addressable Asset Settings则在构建播放器时也会构建Addressbles,在玩家构建中构建可寻址内容。

在构建播放器时也会构建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("[此处为资产的名称]")
将要加载的资源放入Addressables文件夹中

Unity可寻址导入器

如果想更严格地管理地址,建议使用Unity Addressable Importer。

通过使用它,可以使用正则表达式指定目标资产并设置地址、组等。

使用正则表达式指定目标资产并设置地址、组

以上是关于资源文件夹的全部内容。

如果你有任何反馈,请随时在本页面下方留言。

相关信息

  • 类型:知识
  • 字数:1738
  • 字符:6594
  • 适用软件:Unity
  • 说明:无
  • 编号:169373

热门内容

提示:3D天堂作为服务提供者,尊重网络版权及知识产权,对某些行为的发生不具备充分的监控能力,若无意间侵犯到您的权利,请 联系我们,我们会在收到信息后尽快给予处理。

本站文章版权归本站自创作者所有,未经允许不得转载!