Addressable系統的加載資源API總結

你好,我是跟着大智學Unity的萌新,我叫小新,這是我本週的學習總結報告哦。

大智:“小新,這周學習有沒有遇到什麼問題呢?”

小新:“確實遇到了,那個Addressables.LoadAssetsAsyncAPI,我有一次怎麼都加載不出來資源,倒騰了半天,最後發現是參數傳的不對。。。”

大智:“那你現在搞明白了沒?”

小新:“基本搞明白了。。。”

大智:“那你把Addressable中的加載API總結一下吧~我看看你到底搞明白了沒。”

小新:“好嘞。”

Addressable系統的加載資源API

Addressable中加載資源主要有兩個途徑:

  • 通過AssetReference加載
  • 使用Addressables類中的靜態方法通過地址/Label加載

1.AssetReference加載的API

使用AssetReference類訪問Addressable資產時無需知道他們的地址字符串,但是需要在Inspector上關聯。使用流程如下:

  1. 新建一個腳本,任何可序列化的組件都支持AssetReference變量(例如,繼承MonoBehaviour的腳本,ScriptableObject或其他可序列化的類)。
  2. 在組件中添加一個AssetReference類型的公共變量(例如public AssetReference explosion;)。
  3. 在Inspector中,將資產從“ Project”窗口拖到AssetReference字段上(非Addressable資產也可以拖,會自動標記爲Addressable),或從項目中已經設置的可尋址資產的下拉列表中進行選擇(如下所示)。

通過腳本組件引用可尋址資產

要加載或實例化AssetReference資產,需要調用其相應的方法。例如:

僅加載到內存中,多用於貼圖、材質、動畫、音頻等資產:

[AssetReference的變量名].LoadAssetAsync<GameObject>();

直接實例化到場景中,一般用於Prefab:

[AssetReference的變量名].InstantiateAsync(pos, rot);

加載場景:

[AssetReference的變量名].LoadSceneAsync();

:這幾個API都是異步操作,異步操作詳解在大智的教程中有(洪流學堂公衆號中回覆addr可以獲取),在這就不多說了。

2. 使用Addressables類中的靜態方法通過地址/Label加載

Addressables類中有加載單個資源的API和多個資源的API。

加載單個資源

在腳本中使用字符串地址加載資產,先聲明using UnityEngine.AddressableAssets;名稱空間,然後調用以下方法:

僅加載到內存中,多用於貼圖、材質、動畫、音頻等資產:

Addressables.LoadAssetAsync<GameObject>("AssetAddress");

加載完成後並不會將所需的資產實例化到場景中。要將資產添加到場景中,還需要一步:實例化。

還有一個加載和實例化二合一的接口,這個接口會加載資產,然後立即將其實例化到場景中:

Addressables.InstantiateAsync("AssetAddress");

這會將指定地址的資產實例化到場景中。

注意:上面的API是異步操作。你可以在資產完成加載後提供一個回調來使用資產,異步操作詳解在大智的教程中有(洪流學堂公衆號中回覆addr可以獲取),在這就不多說了。

using System.Collections;
using System.Collections.Generic;
using UnityEngine.AddressableAssets;
using UnityEngine;

public class AddressablesExample : MonoBehaviour {

    GameObject myGameObject;

    void Start{
        Addressables.LoadAssetAsync<GameObject>("AssetAddress").Completed += OnLoadDone;
    }

    private void OnLoadDone(UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle<GameObject> obj)
    {
        // In a production environment, you should add exception handling to catch scenarios such as a null result.
        myGameObject = obj.Result;
    }
}

一次加載多個資產

一次加載多個資產通常是使用Label加載。

如上圖所示的分組策略,可以按如下方式加載HD的皮膚貼圖。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class TextureController : MonoBehaviour
{
    public Renderer m_ReferencedMaterial;

    public void SwitchToHighDef()
    {
        LoadTexture("ArcherColor", "HD");
    }

    void LoadTexture(string key, string label)
    {
        Addressables.LoadAssetsAsync<Texture2D>(new List<object> { key, label }, null, Addressables.MergeMode.Intersection).Completed
            += TextureLoaded;
    }

    void TextureLoaded(AsyncOperationHandle<IList<Texture2D>> obj)
    {
        m_ReferencedMaterial.material.mainTexture = obj.Result[0];
    }
}

在這一定要注意:LoadAssetsAsync有三個重載:

public static AsyncOperationHandle<IList<TObject>> LoadAssetsAsync<TObject>(object key, Action<TObject> callback);
public static AsyncOperationHandle<IList<TObject>> LoadAssetsAsync<TObject>(IList<object> keys, Action<TObject> callback, MergeMode mode);
public static AsyncOperationHandle<IList<TObject>> LoadAssetsAsync<TObject>(IList<IResourceLocation> locations, Action<TObject> callback);

通常我們使用前兩種重載:

第一種:用於加載單個標籤或地址。

第二種:用於加載地址+標籤的形式。用第二種時一定要注意加上第三個參數MergeMode。否則重載匹配時就會去匹配第一個重載,會導致找不到資源。

MergeMode是什麼呢?翻譯過來是合併模式。

public enum MergeMode
{
    None = 0,
    UseFirst = 0,
    Union,
    Intersection
}

採用第二種重載加載時,其實會去先查詢每一個地址/標籤對應的資源,然後再根據MergeMode進行最終結果的計算。

舉個栗子:

比如傳入的參數是new List<object>{"cube", "red"},根據cube查詢出來的資源有A、B、D,根據red查詢出來的資源有C、D、E。

那麼MergeMode是Node或UseFirst時,會取第一個key查詢到的資源:A、B、D;

MergeMode是Union時,會取所有key查詢到的資源的並集:A、B、C、D、E;

MergeMode是Intersection時,會取所有key查詢到的資源的交集:D。


總結

大智:“看來這個LoadAssetsAsync就是你栽了的API吧?”

小新:“沒錯。”

大智:“之前我都有講過哦,一定要注意這些細節。特別是方法有重載的時候,要注意查閱API文檔或者閱讀源碼,不能想當然。”


《大話Unity2019》,大智帶小新學Unity2019的有趣經歷,讓你學Unity更簡單。

https://edu.hongliu.cc

發佈了142 篇原創文章 · 獲贊 77 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章