Unity: Как собрать AssetBundles в отдельные каталоги для AssetBundle - PullRequest
0 голосов
/ 04 мая 2018

Мой проект содержит несколько AssetBundles, и я хочу иметь возможность щелкнуть кнопку в Редакторе, которая собирает все AssetBundles в свои собственные соответственно названные папки .

Другими словами, учитывая AssetBundles с именами «A» и «B», выходной результат будет две папки, где «A» содержит встроенные связанные активы, которые были помечены для включения в «A», а также аналогичную папку для "B".

Я в некоторой степени ознакомился с классами AssetBundleBuild и BuildPipeline.

Это привело меня к созданию следующего сценария (см. Ниже).

Я чувствую, что довольно близок к тому, что у меня есть список всех комплектов ресурсов в проекте, настроил для них каталоги и попытался их построить. Проблема в том, что я получаю следующую ошибку:

Манифест имени AssetBundle "example_bundle_name" конфликтует с предопределенным пользователем именем AssetBundle.

Что мне нужно сделать, чтобы сделать эту работу, пожалуйста?

public class BuildAssetBundles : MonoBehaviour
{
    private const string AssetBundleRootDirectory = "Assets/BuiltAssetBundles";
    private const BuildTarget BuildTarget = UnityEditor.BuildTarget.StandaloneWindows;

    [MenuItem("Build Asset Bundles/Build All Asset Bundles")]
    public static void BuildBundlesIntoDirectories()
    {
        Debug.Log("Asset bundle building started...");
        // Get all assets

        var assets = AssetDatabase.GetAllAssetPaths().ToArray();

        List<AssetBundleBuild> assetBundleBuilds = new List<AssetBundleBuild>();
        HashSet<string> processedBundles = new HashSet<string>();

        // Get asset bundle names from selection
        foreach (var o in assets)
        {
            var assetPath = o;
            var importer = AssetImporter.GetAtPath(assetPath);

            if (importer == null)
            {
                continue;
            }

            // Get asset bundle name & variant
            var assetBundleName = importer.assetBundleName;
            var assetBundleVariant = importer.assetBundleVariant;
            var assetBundleFullName = string.IsNullOrEmpty(assetBundleVariant) ? assetBundleName : assetBundleName + "." + assetBundleVariant;

            // Only process assetBundleFullName once. No need to add it again.
            if (processedBundles.Contains(assetBundleFullName))
            {
                continue;
            }

            processedBundles.Add(assetBundleFullName);

            AssetBundleBuild build = new AssetBundleBuild();

            build.assetBundleName = assetBundleName;
            build.assetBundleVariant = assetBundleVariant;
            build.assetNames = AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleFullName);

            assetBundleBuilds.Add(build);
        }

        foreach (var assetBundle in assetBundleBuilds.ToArray())
        {
            if(!String.IsNullOrWhiteSpace(assetBundle.assetBundleName))
                BuildAnAssetBundle(assetBundle);
        }
        Debug.Log("Asset bundle building finished.");

    }

    static void BuildAnAssetBundle(AssetBundleBuild assetBundleToBuild)
    {
        // Put the bundles in a folder within the Assets directory.
        string assetBundleOutputDirectory = Path.Combine(AssetBundleRootDirectory, assetBundleToBuild.assetBundleName);
        if (string.IsNullOrWhiteSpace(assetBundleToBuild.assetBundleVariant))
        {
            Path.Combine(assetBundleOutputDirectory, assetBundleToBuild.assetBundleVariant);
        }

        if(!Directory.Exists(assetBundleOutputDirectory))
            Directory.CreateDirectory(assetBundleOutputDirectory);


        try
        {
            BuildPipeline.BuildAssetBundles(assetBundleOutputDirectory, new AssetBundleBuild[]{assetBundleToBuild}, BuildAssetBundleOptions.None, BuildTarget);
        }
        catch (Exception e)
        {
            Debug.Log(e);
        }
    }
}

Заранее большое спасибо за вашу помощь и предложения.

Мне кажется, что ошибка подразумевает, что мой подход немного неверен, возможно, при настройке AssetBundleBuild он создает дубликат пакета ресурсов, содержащий все содержимое оригинала с идентичным именем.

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Я решил эту проблему, написав отдельный метод организации файлов ресурсов после их сборки.

Это работает, беря имя файла assetbundle (без расширения) и создавая каталог с тем же именем (если он еще не существует). Создав все каталоги, я перемещаю файлы с одинаковыми именами в соответствующий каталог.

Примечание. В Windows (по крайней мере) у вас будет два файла: сам пакет и манифест. У манифеста есть расширение, но у файла пакета нет. Я даю файлу временное расширение файла, чтобы я мог создать каталог с тем же именем, в том же каталоге, в котором находится пакетный файл без расширения, перед тем как вернуться после перемещения.

0 голосов
/ 05 мая 2018

Почему вы пишете код для сборки AssetsBundle? Есть ли что-нибудь, что AssetBundle Browser не может сделать? Просто скачайте его Asset Store или Github и организуйте свои пакеты по своему усмотрению.

...