【Unity】あるAssetBundleに紐づくAssetをビルド後のAssetBundleからしっかり解析するための3つの方法

AssetBundleは依存関係に注意しないと、大きなAssetBundleができてしまったり重複が発生したりしてしまいがちです。
この記事ではあるAssetBundleとに紐づくAssetを解析する方法をまとめます。

Unity1018.3.9

3つの紐づき方

あるAssetBundleにあるAssetが紐づく原因には以下の3種類があります。

  1. 同じAssetBundleに含まれる
  2. AssetBundleは分かれているが、AssetBundle同士が依存関係にある
  3. AssetをAssetBundle化していないが依存関係にあるため、自動的にAssetBundleに含まれる

同じAssetBundleに含まれる場合の解析方法

同じAssetBundle名を付けたAssetは同じAssetBundleに含まれます。
こうして同じAssetBundleに含まれたAssetはAssetBundle.GetAllAssetNames()で取得できます。 Asset自体が必要であればAssetBundle.LoadAllAssets()で取得できます。

docs.unity3d.com

docs.unity3d.com

AssetBundle同士が依存関係にある場合の解析方法

AssetBundle同士が依存関係にある場合は依存関係の情報を、AssetBundleをビルドしたフォルダと同名のAssetBundleから取得することができます。

これについては次の記事で詳しく解説しているのでこちらを参照してください。

light11.hatenadiary.com

自動的にAssetBundleに含まれる場合の解析方法

AssetBundle化していないAssetがAssetBundleから依存された場合には、自動的にAssetBundleに含まれます。
これは少し厄介な問題ではありますが、下記の記事のやり方で取得できました。
ただこれで取得できるのは自動的に含まれるものと、前節のように同じAssetBundle名を付けたものの合計であるように見えます。

tsubakit1.hateblo.jp

m_PreloadTableという、AssetBundleにシリアライズされている情報を使います。
AssetBundleBrowserのInspectタブでも見れるアレです(AssetBundleBrowserのは微妙に挙動が不安定な気がしますが)。

よくテクスチャが自動的に含まれて大変なことになるので、型指定して取得できるメソッドを作ってみました。

/// <summary>
/// AssetBundleに内包するAssetのうち該当する型のものをを取得する
/// </summary>
public static T[] GetIncluded<T>(string assetBundlePath) where T : Object
{
    var assetBundle = AssetBundle.LoadFromFile(assetBundlePath);
    var so = new SerializedObject(assetBundle);
    var objects = new List<T>();
    foreach (SerializedProperty preloadObjProp in so.FindProperty("m_PreloadTable")) {
        var obj = preloadObjProp.objectReferenceValue as T;
        if (obj != null) {
            objects.Add(obj);
        }
    }
    so.Dispose();
    assetBundle.Unload(false);
    return objects.Distinct().ToArray();
}

関連

light11.hatenadiary.com

参考

docs.unity3d.com

docs.unity3d.com

tsubakit1.hateblo.jp