ue3dAddressable资产系统同步加载,Resources.Load可以替换

Addressable资产系统同步加载,Resources.Load可以替换

分类:
ue3d - Addressable资产系统同步加载,Resources.Load可以替换

Unity的Addressable资产系统支持同步加载,所以本文介绍下如何使用以及如何替换Resources.Load。

可寻址和同步加载

到现在只有异步加载方式

Addressable资产系统历来不支持同步加载,因此,需要通过如下所示的异步方法或协程等待加载完成。

// 异步方法
var handle = Addressables.LoadAssetAsync<GameObject>("FooPrefab");
await handle.Task; // 待机
var prefab = handle.Result;

// 协程
var handle = Addressables.LoadAssetAsync<GameObject>("FooPrefab");
yield return handle; // 待机
var prefab = handle.Result;

// 打回来
var handle = Addressables.LoadAssetAsync<GameObject>("FooPrefab").Completed += x =>
{
    var prefab = handle.Result;
};

如果想同步获取资源,需要预加载或编写一个专用的Provider。

可以从这里参阅站内文章:Unity与Addressable资源系统同步加载资源

如何同步加载

传统的异步加载AsyncOperationHandle需要在waits或coroutines中等待,在同步加载的实现中,WaitForCompletion()可以通过调用同步等待。

using UnityEngine;
using UnityEngine.AddressableAssets;

public class Example : MonoBehaviour
{
    private void Start()
    {
        // 像以前一样调用load方法
        var op = Addressables.LoadAssetAsync<GameObject>("FooPrefab");
        
        // 使用 WaitForCompletion 同步等待加载完成
        var prefab = op.WaitForCompletion();
        
        // 使用后释放(与之前相同)
        Addressables.Release(op);
    }
}

替换为Resources.Load

在那篇文章的实现方法中,由于需要释放资源,所以源码是多行的。

但是,考虑到替换已经写的Resources.Load内容,所以尽量写得简洁一点。

// 使用 Resources.Load 加载的示例
var prefab = Resources.Load<GameObject>("FooPrefab");

// 在Addressables中这样写(理想)
var prefab = Addressables.Load<GameObject>("FooPrefab");

用Addler写在一行

由于需要显式释放Addressables,因此上面的描述将跨越多行。因此,为了简明扼要地写出这个发布过程,使用了一个名为Addler的库。

可以从这里参阅:介绍Addressables生命周期Addler管理库

通过使用它,可以将资源生命周期与指定的GameObject关联起来,并在GameObject销毁时一起释放,如下图一行描述即可,不用担心忘记释放而导致内存泄露。

using Addler.Runtime.Core;
using UnityEngine;
using UnityEngine.AddressableAssets;

public class Example : MonoBehaviour
{
    private void Start()
    {
        // 当游戏对象被销毁时,该资产会自动释放
        var prefab = Addressables.LoadAssetAsync<GameObject>("FooPrefab").BindTo(gameObject).WaitForCompletion();
    }
}

Addler的功能不仅限于此,它是一个包含对象池和预加载等功能的库。

这样简单的写

实际使用的时候,觉得把它包装起来,创建一个可以写得更简洁的类会更好。

using Addler.Runtime.Core;
using UnityEngine;
using UnityEngine.AddressableAssets;

public class ResourceLoader
{
    private readonly GameObject _defaultBindTarget;

    public ResourceLoader(GameObject defaultBindTarget)
    {
        _defaultBindTarget = defaultBindTarget;
    }
    
    public T Load<T>(string address, GameObject bindTarget = null)
    {
        if (bindTarget == null)
        {
            bindTarget = _defaultBindTarget;
        }
        return Addressables.LoadAssetAsync<T>(address).BindTo(bindTarget).WaitForCompletion();
    }
}

如果这样做,可以非常简单地加载它,如下所示。

using Addler.Runtime.Core;
using UnityEngine;
using UnityEngine.AddressableAssets;

public class Example : MonoBehaviour
{
    private ResourceLoader _resourceLoader;
    
    private void Start()
    {
        _resourceLoader = new ResourceLoader(gameObject);

        // 同步负载
        _resourceLoader.Load<GameObject>("FooPrefab");
    }
}

EZAddresser(自动分配类似资源的地址)

替换资源的另一个障碍是地址的设置,要加载上面的内容FooPrefab,需要提前设置地址FooPrefab为那个Prefab。

ue3d - Addressable资产系统同步加载,Resources.Load可以替换

这是通过将资产拖放到上面的窗口中然后设置名称来完成的,但是手动执行此操作绝对不是人工工作。

使用EZAddresser,只需创建一个名为Addressables的文件夹并将资产放入其中,地址就会自动分配。

可以从这篇文章中了解:EZAddresser一个用于自动化可寻址地址设置工具

默认情况下,文件名将是地址,但如果更改设置,也可以使用Addressables文件夹的相对路径(无扩展名)作为地址,如Resources文件夹。

换句话说,如果使用此设置将现有Resources文件夹的名称更改为Addressables,则可以将Resources替换为Addressables。

但是请注意,此库需要Unity 2020或更高版本。

使用同步加载时的注意事项

手册描述了同步加载时需要注意的一些要点,从这里参阅。

等到所有AsyncOperations完成

考虑并行加载多个资产的情况,如只使用其中的一个WaitForCompletion()等待同步加载,可以直观的想象只有它会被同步等待,其他资源会被异步加载。然而实际上,WaitForCompletion()即使只完成其中一个,看起来也会同步等待,直到此时存在的所有AsyncOperations都完成。

这是一个相当微妙的规范,但它是对引擎的一个约束,只在可以很好地控制加载内容的情况下WaitForCompletion()使用。

加载影响性能

还写了Unity 2021.2.0之前的版本使用同步加载会影响性能,不知道它有多大影响,但WaitForCompletion()似乎调用时正在进行的负载处理越多,它的影响就越大。

请勿用于下载

如果资源不在本地,Addressable的加载方法将下载资源,这种行为WaitForCompletion()在使用时是一样的,但是像下载这样耗时的过程一般不应该被同步处理,因为它们会卡住。

所以WaitForCompletion()建议下载的时候不要使用(有意的话也可以)。

以上是关于Unity如何使用以及替换Resources.Load的全部内容,如果你有任何反馈,请随时在本页面下方留言。

相关信息

  • 类型:知识
  • 字数:1191
  • 字符:5796
  • 适用软件:Unity
  • 说明:无
  • 编号:164049

热门内容

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

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