C# Unity:如何将AssetBundle构建到每个AssetBundle的单独目录中
我的项目包含多个AssetBundle,我希望能够单击编辑器中的按钮,该按钮将所有AssetBundle构建到它们自己适当命名的文件夹中 换句话说,给定名为“A”和“B”的资产绑定,输出将是两个文件夹,其中“A”包含标记为包含在“A”中的已构建捆绑资产,同样,“B”也包含一个类似的文件夹 我已经在某种程度上熟悉了C# Unity:如何将AssetBundle构建到每个AssetBundle的单独目录中,c#,unity3d,build,assets,assetbundle,C#,Unity3d,Build,Assets,Assetbundle,我的项目包含多个AssetBundle,我希望能够单击编辑器中的按钮,该按钮将所有AssetBundle构建到它们自己适当命名的文件夹中 换句话说,给定名为“A”和“B”的资产绑定,输出将是两个文件夹,其中“A”包含标记为包含在“A”中的已构建捆绑资产,同样,“B”也包含一个类似的文件夹 我已经在某种程度上熟悉了AssetBundleBuild和BuildPipeline类 这使我产生了以下脚本(见下文) 我觉得我已经很接近了,我已经得到了项目中所有资产包的列表,为它们设置了目录,并尝试构建它们
AssetBundleBuild
和BuildPipeline
类
这使我产生了以下脚本(见下文)
我觉得我已经很接近了,我已经得到了项目中所有资产包的列表,为它们设置了目录,并尝试构建它们。问题是我遇到了以下错误:
清单资产绑定名称“示例绑定名称”与用户预定义的资产绑定名称冲突
我需要做些什么才能让这一切顺利进行
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);
}
}
}
公共类BuildAssetBundles:MonoBehavior
{
私有常量字符串AssetBundleRootDirectory=“资产/BuiltAssetBundles”;
private const BuildTarget BuildTarget=UnityEditor.BuildTarget.StandaloneWindows;
[菜单项(“构建资产捆绑包/构建所有资产捆绑包”)]
公共静态void BuildBundlesIntoDirectories()
{
Log(“资产包构建已启动…”);
//获取所有资产
var assets=AssetDatabase.GetAllAssetPath().ToArray();
List assetBundleBuilds=新建列表();
HashSet processedBundles=新HashSet();
//从所选内容中获取资产包名称
foreach(资产中的var o)
{
var assetPath=o;
var导入器=AssetImporter.GetAtPath(assetPath);
如果(导入器==null)
{
继续;
}
//获取资产包名称和变量
var assetBundleName=importer.assetBundleName;
var assetBundleVariant=进口商。assetBundleVariant;
var assetBundleFullName=string.IsNullOrEmpty(assetBundleVariant)?assetBundleName:assetBundleName+“”+assetBundleVariant;
//只处理assetBundleFullName一次,无需再次添加。
if(processedBundles.Contains(assetBundleFullName))
{
继续;
}
processedBundles.Add(assetBundleFullName);
AssetBundleBuild build=新建AssetBundleBuild();
build.assetBundleName=assetBundleName;
build.assetBundleVariant=assetBundleVariant;
build.assetNames=AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleFullName);
assetBundleBuilds.Add(build);
}
foreach(assetBundleBuilds.ToArray()中的var assetBundle)
{
如果(!String.IsNullOrWhiteSpace(assetBundle.assetBundleName))
BuildinasSetBundle(资产绑定);
}
Log(“资产包构建完成”);
}
静态void buildanasetbundle(AssetBundleBuild assetBundleToBuild)
{
//将捆绑包放在Assets目录中的文件夹中。
字符串assetBundleOutputDirectory=Path.Combine(AssetBundleRootDirectory,assetBundleToBuild.assetBundleName);
if(string.IsNullOrWhiteSpace(assetBundleToBuild.assetBundleVariant))
{
Combine(assetBundleOutputDirectory、assetBundleToBuild.assetBundleVariant);
}
如果(!Directory.Exists(assetBundleOutputDirectory))
CreateDirectory(assetBundleOutputDirectory);
尝试
{
BuildPipeline.BuildAssetBundles(assetBundleOutputDirectory,新AssetBundleBuild[]{assetBundleToBuild},BuildAssetBundleOptions.None,BuildTarget);
}
捕获(例外e)
{
Debug.Log(e);
}
}
}
非常感谢您的帮助和建议
在我看来,这个错误似乎暗示我的方法有点不正确,可能在设置AssetBundleBuild时,它正在生成一个重复的资产包,其中包含具有相同名称的原始文件的所有内容 为什么要编写代码来构建AssetBundle?有什么AssetBundle浏览器不能做的吗?
只需下载它或按您的意愿组织您的包。为什么要编写代码来构建AssetBundle?有什么AssetBundle浏览器不能做的吗?
只需下载它,或者按照您的意愿组织捆绑包。我通过编写一个单独的方法来解决这个问题,即在构建资产捆绑包文件后组织它们 这是通过获取assetbundle文件的名称(减去扩展名)并创建一个同名目录(如果还不存在的话)来实现的。创建完所有目录后,我将同名文件移动到相关目录中
注意:在Windows上(至少),您将有两个文件,捆绑包本身和清单。清单有扩展名,但捆绑包文件没有。我为该文件提供了一个临时文件扩展名,以便在移动后恢复之前,可以在无扩展名捆绑包文件所在的同一目录中创建一个同名目录 我已经通过编写一个单独的方法解决了这个问题,该方法在生成assetbundle文件后对其进行组织 这是通过获取assetbundle文件的名称(减去扩展名)并创建一个同名目录(如果还不存在的话)来实现的。创建完所有目录后,我将同名文件移动到相关目录中 注意:在Windows上(至少),您将有两个文件,捆绑包本身和清单。清单有扩展名,但捆绑包文件没有。我为文件提供了一个临时文件扩展名,这样我就可以在无扩展名包文件所在的同一目录中创建一个同名目录,bef