【Unity】【Addressable】複数キーを指定してロードする際のMergeModeの使い道

UnityのAddressableアセットシステムで、複数キーを指定してロードする際のMergeModeの使い道についてまとめました。

Unity2021.3.0f1
Addressables 1.19.19

はじめに

Addressableで複数のキーを指定して複数のアセットをロードする際には、引数に Addressables.MergeMode を指定する必要があります。

Addressables.LoadAssetsAsync<GameObject>(keys, null, Addressables.MergeMode.Intersection);

この MergeMode の説明は以下の通りです。

  • None: 最初のキーにマッチするアセットを全て取得
  • UseFirst: Noneと同じ
  • Union: いずれかのキーにマッチするアセットを全て取得
  • Intersection: 全てのキーにマッチするアセットだけを取得

さてこの Merge Modeは、アドレスをキーとして使うケースでは、使い道がいまいちわからないので混乱の原因となりがちです。

しかしながら、次節のようにラベルを複数指定するケースを考えると、これの有用性が理解できます。

ラベルを複数指定する時のための機能

たとえばいま、以下のような4つのPrefabがAddressableに登録されているとします。

  • 通常エネミーのPrefab - ラベル: enemy
  • ボスエネミーのPrefab - ラベル: enemy, boss
  • イベント用通常エネミーのPrefab - ラベル: enemy, event
  • イベント用ボスエネミーのPrefab - ラベル: enemy, boss, event

これを設定したAddressable Groupsウィンドウは下図の通りです。

Addressable Groups

それでは次に、enemy、boss、eventの三つのラベルを指定してロードを行うことを考えます。
まず以下のように、MergeMode に Union を指定して Prefab をロードします。

var labels = new List<string> { "enemy", "boss", "event" };
var handle = Addressables.LoadAssetsAsync<GameObject>(labels, null, Addressables.MergeMode.Union);
yield return handle;
var prefabs = handle.Result;
for (var i = 0; i < prefabs.Count; i++)
{
    var prefab = prefabs[i];
    var position = new Vector3(i * 1.5f, 0, 0);
    Instantiate(prefab, position, Quaternion.identity, transform);
}

すると下図のように、いずれかのラベルにマッチするPrefabが全てロードされることを確認できます。
つまりここでは、enemy、boss、eventのいずれかのラベルを含むPrefabが全てロードされます。

なお、下図において、球体は通常エネミー、立方体はボスエネミーを示します。緑色はイベントエネミーです。

Prefabs

次に、全ての「イベント用ボスエネミー」だけをフィルタリングしてロードするケースを考えます。
このような場合には、以下のように MergeMode を Intersection に設定します。

var labels = new List<string> { "enemy", "boss", "event" };
var handle = Addressables.LoadAssetsAsync<GameObject>(labels, null, Addressables.MergeMode.Intersection);
yield return handle;
var prefabs = handle.Result;
for (var i = 0; i < prefabs.Count; i++)
{
    var prefab = prefabs[i];
    var position = new Vector3(i * 1.5f, 0, 0);
    Instantiate(prefab, position, Quaternion.identity, transform);
}

MergeMode.Intersection は全てのラベルに一致するアセットをロードします。
つまり今回のケースでは、enemy、boss、event全てに当てはまるPrefab、すなわちイベント用ボスエネミーのPrefabのみをフィルタリングしてロードすることができます。

以下は実行結果です。

Intersection

同様に、enemyとeventラベルだけを指定して MergeMode を Intersection に指定するとイベント用の通常エネミーとボスエネミーだけをロードすることができます。

Intersection
なお MergeMode.UseFirst については用途がいまいち分かりませんが、MergeMode.None と同じ挙動であることを考えると、ただデフォルトの挙動を定義するためのものという理解で良さそうな気がします。
もし良い感じに使っている人がいたら教えてください。

参考

docs.unity3d.com