Unity可寻址系统的概念和实现原理

        Unity可寻址系统提供了一个统一的资源管理接口,它允许我们通过地址来获取到任意类型的资源(如场景、贴图、音频等)。在使用Unity可寻址系统之前,我们需要对游戏资源进行打包,并生成相应的AssetBundle文件。具体打包的过程可以参考Unity官方文档。

可寻址资源的加载流程通常如下所示:

  1. 在Unity Editor中创建一个Addressable Asset,为其分配一个唯一的地址。
  2. 在打包时将这些已经分配好地址的资源打包成AssetBundle文件。
  3. 在游戏运行时通过地址来加载相应的AssetBundle文件。
  4. 加载AssetBundle文件后通过地址来获取相应的资源。

Unity可寻址系统的实现原理主要是通过以下三个类来实现:

  1. AddressableAssetSettings:可寻址系统的设置类,通过该类可以进行可寻址系统的配置和管理。
  2. AsyncOperationHandle:异步的操作句柄类,用于异步加载和释放可寻址资源。
  3. Addressables:可寻址系统的静态类,用于通过地址来获取相应的资源。

分标签加载可寻址资源

        对于大型游戏而言,打包出的AssetBundle文件往往会非常庞大,这会导致加载资源时出现卡顿或者等待时间较长的情况。这时我们可以采取分标签加载的方式来优化资源的加载速度。分标签加载是将不同类型的资源打包到不同的AssetBundle文件中,并为其打上不同的标记。例如我们可以将场景、贴图、音频等不同的资源放在不同的AssetBundle文件中,并为其分别打上Scene、Texture、Audio等标记。这样当我们需要加载某一类型的资源时,只需要加载对应标记的AssetBundle文件即可。

下面我们演示如何使用分标签加载来优化可寻址资源的加载速度。

  1. 在Unity Editor中创建一个Addressable Asset并为其添加标记(Tag)。

  2. 编写代码来加载对应标记的AssetBundles,如下所示:

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class LoadAssetByTag : MonoBehaviour
{
    public string tag = "MyTag";  // 需要加载的标记名称

    // 加载对应标记的所有AssetBundle
    public void LoadAssetsByTag()
    {
        AsyncOperationHandle<IList<string>> opHandle = Addressables.LoadResourceLocationsAsync(tag);
        opHandle.Completed += OnComplete;
    }

    // 加载完成后回调
    private void OnComplete(AsyncOperationHandle<IList<string>> obj)
    {
        if (obj.Status == AsyncOperationStatus.Succeeded)
        {
            foreach (var location in obj.Result)
            {
                Addressables.LoadAssetAsync<GameObject>(location).Completed += OnLoadAssetComplete;
            }
        }
    }

    // 加载单个AssetBundle中的资源完成后回调
    private void OnLoadAssetComplete(AsyncOperationHandle<GameObject> obj)
    {
        if (obj.Status == AsyncOperationStatus.Succeeded)
        {
            Debug.Log("Load Asset Successfully: " + obj.Result.name);
        }
    }
}

以上代码会异步加载所有打上指定标记的AssetBundle,并在加载完成后输出每个AssetBundle中所包含的资源的名称。

代码加载可寻址资源

除了使用分标签加载可寻址资源外,我们还可以通过代码加载可寻址资源。这种方式适用于需要在游戏运行时动态加载资源的情况。下面我们演示如何使用代码加载可寻址资源。

  1. 在Unity Editor中创建一个Addressable Asset并为其分配一个唯一的地址。

  2. 编写代码来加载指定地址的资源,如下所示:

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class LoadAssetByAddress : MonoBehaviour
{
    public string address;  // 需要加载的地址

    // 加载指定地址的AssetBundle
    public void LoadAssetsByAddress()
    {
        AsyncOperationHandle<GameObject> opHandle = Addressables.LoadAssetAsync<GameObject>(address);
        opHandle.Completed += OnComplete;
    }

    // 加载完成后回调
    private void OnComplete(AsyncOperationHandle<GameObject> obj)
    {
        if (obj.Status == AsyncOperationStatus.Succeeded)
        {
            Instantiate(obj.Result);  // 实例化已加载的GameObject
        }
    }
}

以上代码会异步加载指定地址的AssetBundle,并在加载完成后实例化其中包含的GameObject。

        同时,在代码加载可寻址资源时,我们也可以使用LoadResourceLocationsAsync方法来获取所有打上指定标记的AssetBundle的地址列表,并根据需要来加载对应的资源。

// 获取指定标记的所有AssetBundle的地址列表
AsyncOperationHandle<IList<string>> opHandle = Addressables.LoadResourceLocationsAsync("MyTag");
opHandle.Completed += OnComplete;

// 加载所有地址列表中的资源
private void OnComplete(AsyncOperationHandle<IList<string>> obj)
{
    if (obj.Status == AsyncOperationStatus.Succeeded)
    {
        foreach (var location in obj.Result)
        {
            Addressables.LoadAssetAsync<GameObject>(location).Completed += OnLoadAssetComplete;
        }
    }
}

总结

        在本篇技术博客中,我们介绍了Unity可寻址系统的概念和实现原理,并演示了如何通过分标签加载和代码加载可寻址资源。使用Unity可寻址系统可以有效地管理游戏资源,并提高资源加载速度,使得游戏体验更加流畅。

猜你喜欢

转载自blog.csdn.net/Asklyw/article/details/130131505