Unity:如何根据AssetBundle将AssetBundle构建到单独的目录中

时间:2018-05-04 15:27:41

标签: c# unity3d build assets assetbundle

我的项目包含多个AssetBundle,我希望能够单击编辑器中的一个按钮,将所有AssetBundle构建到他们自己的相应命名文件夹中。

换句话说,鉴于AssetBundles名为" A"和" B",输出将是两个文件夹,其中" A"包含已标记为包含在" A"中的已构建捆绑资产,以及" B"的类似文件夹。

我已经在某种程度上熟悉了AssetBundleBuildBuildPipeline类。

这使我产生了以下脚本(见下文)。

我觉得我非常接近,因为我得到了项目中所有资产包的列表,为它们设置目录,并尝试构建它们。问题是我收到以下错误:

  

Manifest AssetBundle name" 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时,它正在制作一个重复的资产包,其中包含具有相同名称的原始内容。 < / p>

2 个答案:

答案 0 :(得分:1)

为什么要编写代码来构建AssetsBundle? AssetBundle浏览器有什么不能做的吗? 只需下载Asset StoreGithub,然后根据需要整理捆绑包。

答案 1 :(得分:0)

我已经通过编写一个单独的方法来解决这个问题,一旦构建了assetbundle文件。

这可以通过获取assetsbundle文件的名称(减去扩展名)并创建同名目录(如果尚不存在)来实现。创建了所有目录后,我将相同名称的文件移动到相关目录中。

注意:在Windows(至少)上,您将拥有两个文件,即软件包本身和清单。清单有扩展名,但捆绑文件没有。我给文件一个临时文件扩展名,这样我就可以在无扩展束文件所在的同一目录中创建一个同名目录,然后在移动后恢复。