【问题标题】:Unity: How to build AssetBundles into separate directories per AssetBundleUnity:如何将 AssetBundle 构建到每个 AssetBundle 的单独目录中
【发布时间】:2018-10-15 03:28:05
【问题描述】:

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

换句话说,给定名为“A”和“B”的 AssetBundle,输出将是两个文件夹,其中“A”包含构建的捆绑资产,这些资产被标记为包含在“A”中,同样的文件夹“乙”。

我已经在一定程度上熟悉了AssetBundleBuildBuildPipeline 类。

这导致我生成了以下脚本(见下文)。

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

清单 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 时,它正在制作一个重复的资产包,其中包含具有相同名称的原始文件的所有内容。

【问题讨论】:

  • 我觉得这样做的唯一方法可能是在构建之后这样做。换句话说,将所有资产包构建到一个目录中,然后按名称追溯选择它们中的每一个,并将它们放入一个以文件名命名的新文件夹中,不包括扩展名......有人能提出更好的方法吗?
  • 这就是这样做的方式。游戏的单个版本不应多次调用BuildPipeline.BuildAssetBundles;它会很差地建立依赖关系,并且可能会导致某些资产在多个捆绑包中重复。如果我可能会问,您为什么要将它们放在单独的目录中?这将使加载程序的逻辑更加复杂。
  • 感谢您的评论@Foggzie。这背后的想法是,将有一个带有基本功能的交付可执行文件,然后客户可以选择在未来的不同时间点向他们交付一个或多个捆绑包,以便为他们提供附加内容,类似于 dlc 的概念。我们知道从一开始就会有多个这样的附加组件,因此我们希望能够以最少的手动工作轻松地将它们分类到目录中

标签: c# unity3d build assets assetbundle


【解决方案1】:

您为什么要编写代码来构建 AssetsBundle?有什么 AssetBundle Browser 不能做的吗? 只需下载 Asset StoreGithub 并根据需要整理您的捆绑包。

【讨论】:

  • AssetBundle 浏览器总体上是一个很大的帮助,所以谢谢你的建议!
【解决方案2】:

我已经解决了这个问题,方法是编写一个单独的方法来组织资产包文件,一旦它们被构建。

这通过获取assetbundle 文件的名称(减去扩展名)并创建一个同名的目录(如果尚不存在)来工作。创建完所有目录后,我将同名文件移动到相关目录中。

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

【讨论】:

    猜你喜欢
    • 2018-04-12
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    相关资源
    最近更新 更多