The concept and implementation principle of Unity addressable system

        The Unity addressable system provides a unified resource management interface, which allows us to obtain any type of resource (such as scenes, textures, audio, etc.) through addresses. Before using the Unity addressable system, we need to package game resources and generate corresponding AssetBundle files. For the specific packaging process, please refer to the official Unity documentation.

The loading flow for addressable resources typically looks like this:

  1. Create an Addressable Asset in the Unity Editor and assign it a unique address.
  2. When packaging, these resources with allocated addresses are packaged into AssetBundle files.
  3. Load the corresponding AssetBundle file through the address when the game is running.
  4. After loading the AssetBundle file, obtain the corresponding resource through the address.

The realization principle of the Unity addressable system is mainly realized through the following three classes:

  1. AddressableAssetSettings: The setting class of the addressable system, through which the configuration and management of the addressable system can be performed.
  2. AsyncOperationHandle: An asynchronous operation handle class for asynchronous loading and release of addressable resources.
  3. Addressables: Static classes of addressable systems, used to obtain corresponding resources through addresses.

Loading addressable resources by label

        For large-scale games, the packaged AssetBundle file is often very large, which will cause lag or long waiting time when loading resources. At this time, we can adopt the method of sub-label loading to optimize the loading speed of resources. Sub-label loading is to package different types of resources into different AssetBundle files and mark them with different tags. For example, we can put different resources such as scenes, textures, and audio in different AssetBundle files, and mark them with Scene, Texture, Audio, etc. respectively. In this way, when we need to load a certain type of resource, we only need to load the corresponding marked AssetBundle file.

Below we demonstrate how to use sub-label loading to optimize the loading speed of addressable resources.

  1. Create an Addressable Asset in the Unity Editor and add a tag to it.

  2. Write code to load the AssetBundles corresponding to the tag, as follows:

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);
        }
    }
}

The above code will asynchronously load all AssetBundles marked with the specified mark, and output the name of the resource contained in each AssetBundle after the loading is complete.

Code loads addressable resources

In addition to using sub-labels to load addressable resources, we can also load addressable resources through code. This method is suitable for situations where resources need to be loaded dynamically while the game is running. Below we demonstrate how to load addressable resources using code.

  1. Create an Addressable Asset in the Unity Editor and assign it a unique address.

  2. Write code to load the resource at the specified address, as follows:

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
        }
    }
}

The above code will asynchronously load the AssetBundle at the specified address, and instantiate the GameObject contained in it after the loading is complete.

        At the same time, when the code loads addressable resources, we can also use the LoadResourceLocationsAsync method to obtain the address list of all AssetBundles marked with the specified mark, and load the corresponding resources as needed.

// 获取指定标记的所有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;
        }
    }
}

Summarize

        In this technical blog, we introduced the concept and implementation principle of Unity's addressable system, and demonstrated how to load addressable resources through sub-label loading and code loading. Using the Unity addressable system can effectively manage game resources and improve resource loading speed, making the game experience smoother.

Guess you like

Origin blog.csdn.net/Asklyw/article/details/130131505