AssetBundleBuild.addressableNamesについて

# 概要

[AssetBundleBuild\.addressableNames \- Unity スクリプトリファレンス](https://docs.unity3d.com/ja/2017.4/ScriptReference/AssetBundleBuild-addressableNames.html)

いつの間にかこんなのが追加されている。2017.4でひっそりと入っていたっぽい。

> To provide custom addressable names for assets in the bundle, this array needs to be the same size as AssetBundleBuild.assetNames. Each entry in this array will be matched to the asset in assetNames based on index. If the string in a given index in addressableNames is empty, the value in assetNames at the same index is used instead (default behaviour).

要はLoadAsset時に使うアセットに対応する引数を自由に指定できるとのこと。
従来ではAssetBundleからアセットをロードする時はフルパス（プロジェクトフォルダからの相対パス）を指定しなければならなかった。

```cs
// assetNamesを指定してビルド
var assetBundleBuild = new AssetBundleBuild();
assetBundleBuild.assetBundleName = "hoge";
assetBundleBuild.assetNames = new string[2]{
  "Assets/AssetBundleResources/hoge/texture.png",
  "Assets/AssetBundleResources/fuga/texture.png"
};
// 以下略

// assetNamesを指定してロード
// 引数にはフルパス、ファイル名＋拡張子、ファイル名が使える
var hoge = assetBundle.LoadAsset<Sprite>("Assets/AssetBundleResources/hoge/texture.png");
var fuga = assetBundle.LoadAsset<Sprite>("Assets/AssetBundleResources/fuga/texture.png");
```

これが、addressableNamesを使うことで、ロード時に使う引数を自由に指定できるようになった。

```cs
// addressableNamesを指定してビルド
var assetBundleBuild = new AssetBundleBuild();
assetBundleBuild.assetBundleName = "hoge";
assetBundleBuild.assetNames = new string[2]{
  "Assets/AssetBundleResources/hoge/texture.png",
  "Assets/AssetBundleResources/fuga/texture.png"
};
assetBundleBuild.addressableNames = new string[2]{
  "hoge/texture", // -> Assets/AssetBundleResources/hoge/texture.pngに対応
  "fuga/texture" // -> Assets/AssetBundleResources/fuga/texture.pngに対応
};
// 以下略

// addressableNamesを指定してロードが可能
var hoge = assetBundle.LoadAsset<Sprite>("hoge/texture");
var fuga = assetBundle.LoadAsset<Sprite>("fuga/texture");
```

## 何が嬉しいのか

AssetBundleManager的なものを作る時に、今まではロード時に以下のような手順が必要だった

- いちいちフルパスを引数に入れるのは面倒なので、アセットの識別子となる文字列を決める（相対パスを使うなど）
- アセットの識別子からアセットのフルパスに変換する関数を用意

要はフルパスは扱いにくいので扱いやすいように省略形でロードできるようにしたいけど、アセットを特定するための識別子が2重化されるので冗長な実装になってしまい若干アレという感じだった。（ファイル名を使うのはバッティングしまくるのでナシ）
addressableNamesにロード時に使いたい識別子をそのまま入れてしまえばフルパスをいちいち管理する必要が無くなるので実装がシンプルになり、独自Manifestファイルの容量削減にも繋がったりする。

# 疑問点

- addressableNamesを指定した場合、LoadAssetの引数にassetNameを利用することができるのか？
- AssetBundle.GetAllAssetNamesで取得できる値は変わるのか？
- [BuildAssetBundleOptions\.DisableLoadAssetByFileName](https://docs.unity3d.com/ja/2018.3/ScriptReference/BuildAssetBundleOptions.DisableLoadAssetByFileName.html)、[BuildAssetBundleOptions\.DisableLoadAssetByFileNameWithExtension](https://docs.unity3d.com/ja/2018.3/ScriptReference/BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtension.html)の指定はどうなるか？
- StreamedSceneAssetBundleにも有効なのか？

解説文を見ると、デフォルトではaddressableNamesが指定されていない場合assetNamesが代わりに利用される的なことが書かれているので、予想ではassetNameは使えず、DisableLoadAssetByFileNameとかの指定は有効になる。
ということで検証してみた。

## 結果

> addressableNamesを指定した場合、LoadAssetの引数にassetNameを利用することができるのか？

結論：不可。
まあそもそも任意の識別子でロードできるようにするために使うので、元のフルパスが使えなくても何も問題無い。

> AssetBundle.GetAllAssetNamesで取得できる値は変わるのか？

結論：変わる。

> [BuildAssetBundleOptions\.DisableLoadAssetByFileName](https://docs.unity3d.com/ja/2018.3/ScriptReference/BuildAssetBundleOptions.DisableLoadAssetByFileName.html)、[BuildAssetBundleOptions\.DisableLoadAssetByFileNameWithExtension](https://docs.unity3d.com/ja/2018.3/ScriptReference/BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtension.html)の指定はどうなるか？

結論：有効。
どういうことかと言うと、例えばaddressableNameを`"hoge/fuga.png"`にした場合、assetNameの場合と同様に以下の引数でロードが可能。

- hoge/fuga.png
- fuga.png
- fuga

なので、DisableLoadAssetByFileName、DisableLoadAssetByFileNameWithExtensionの指定は有効。
どうせ自分で指定したフルのaddressableNameしか使わないので、上記オプションも同時に使ったほうが良さそう。

> StreamedSceneAssetBundleにも有効なのか？

結論：無効。
addressableNamesを指定してビルドしたAssetBundleからGetAllScenePathsで取得できるのはプロジェクトフォルダからの相対パスだった。（ex: `Assets/AssetBundleResources/scene.unity`）

# まとめ

- AssetBundleBuild.addressableNamesを指定することで、AssetBundleからアセットをロードする際の識別子を任意に決定する事ができる
- 元のフルパスでのロードは不可能になる
- BuildAssetBundleOptions.DisableLoadAssetByFileName、BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtensionも併用するのが良い