[Unity] AssetBundleNameをアセットのファイルパスから設定する


AssetBundleNameの設定

UnityEditor上で任意のアセット (Project上のSprite,Audio,Scene...etc) を選択すると
Inspectorの下部にて一つのAssetBundleNameが設定できます。
AssetBundleをBuildする際にAssetBundleNameが同一のアセットがAssetBundleとしてまとめられます。

これは AssetImporter を利用することで、Script上からでも設定することが出来ます。

AssetImporter importer = AssetImporter.GetAtPath("Assets/Resources/Sprites/Enemy/1.png");
importer.assetBundleName = "sprites/enemy/1.unity3d";

上記を利用して、指定したディレクト以下のファイルに対し
自動でAssetBundleNameを設定するエディタ拡張を作ってみます。
(ただし、1アセットに対し、1アセットバンドルを生成する前提)

コード

using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using System.IO;

public static class SetAssetBundleName
{
    [MenuItem("Assets/AssetBundle/SetName")]
    public static void SetName()
    {
        string resourcePath = Application.dataPath + "/Resources";
        string projectPath  = Application.dataPath.Replace("Assets", "");

        List<string> paths = Directory.GetFiles(resourcePath, "*.*", SearchOption.AllDirectories)
            .Where(path => !path.EndsWith(".meta"))
            .Select(path => path.Replace(projectPath, ""))
            .ToList();

        foreach (string path in paths)
        {
            AssetImporter importer = AssetImporter.GetAtPath(path);
            var assetBundleName = path.Substring(0, path.LastIndexOf(".")) + ".unity3d";
            importer.assetBundleName = assetBundleName;
        }
    }
}

Directory.GetFiles は指定した条件のファイルパスを返します。
SearchOption.AllDirectories を指定することでサブディレクトリ内のファイルも対象となります。

Directory.GetFiles(resourcePath, "*.*", SearchOption.AllDirectories)

System.Linqにおける Where は条件に沿う要素への絞込を行います。
ここでは .meta 拡張子のファイルを除外しています。

.Where(path => !path.EndsWith(".meta"));

System.Linqにおける Select は各要素に対する処理を行います。
Directory.GetFiles で取得されるファイルの絶対パス群に対し
AssetImporter.GetAtPath で使用するパスへ置換を行っています。

.Select(path => path.Replace(projectPath, ""));

importer.assetBundleNameassetBundleName を代入する前に
現状の拡張子を取り除いた上で、AssetBundleで付けたい拡張子を付けています。

var assetBundleName = path.Substring(0, path.LastIndexOf(".")) + ".unity3d";
importer.assetBundleName = assetBundleName;

使い方

エディタ拡張として生成しているので、 UnityEditor上部の Assets/AssetBundle/SetName にて実行できます。

ビルド時に漏れを防ぐのであれば、ビルド用のスクリプトで SetAssetBundleName.SetName()を呼ぶのが良さそうです。
(もしくはアセットインポートにフックしてAssetBundleName設定する君を作ると良さそう)

また、1アセット1アセットバンドルで無い運用の場合は string.IsNullOrEmpty(importer.assetBundleName) で漏れが無いかチェックする君に置き換えるのが良さそうです。

実行後

参考