You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity预制体导出为.unity3d格式Asset Bundle后加载报错问题

Unity AssetBundle打包(含子预制体)错误修正

原代码存在的问题

  • 打开保存面板后未使用用户选择的路径,硬编码输出路径导致实际打包位置与预期不符
  • 未校验选中对象是否为Project窗口中的预制体资产,若选中场景中的实例会导致依赖获取失败
  • 依赖处理逻辑冗余,脚本文件标记为null但未彻底过滤(虽不影响最终列表,但代码不够严谨)
  • 未处理子预制体已分配其他AssetBundle的情况,这会导致Unity跳过该依赖,加载时缺失资源

修正后的代码

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

#if UNITY_EDITOR 
public class AssetBundleBuilder : EditorWindow
{
    [MenuItem("Assets/Asset Bundle Builder")]
    static void BuildAssetBundle()
    {
        // 校验选中对象是否为预制体资产(必须在Project窗口选中)
        GameObject selectedPrefab = Selection.activeObject as GameObject;
        if (selectedPrefab == null || PrefabUtility.GetPrefabAssetType(selectedPrefab) == PrefabAssetType.NotAPrefab)
        {
            Debug.LogError("请在Project窗口中选择一个预制体进行打包!");
            return;
        }

        string bundleName = selectedPrefab.name;
        List<string> assetPaths = new List<string>();

        // 获取用户选择的保存路径
        string savePath = EditorUtility.OpenFolderPanel("选择AssetBundle保存路径", "", "");
        if (string.IsNullOrEmpty(savePath))
        {
            Debug.LogError("未选择保存路径,打包终止");
            return;
        }

        // 获取预制体的所有依赖(包含间接依赖,仅资产文件)
        string prefabPath = AssetDatabase.GetAssetPath(selectedPrefab);
        string[] dependencies = AssetDatabase.GetDependencies(prefabPath, false);

        // 过滤脚本文件,收集唯一资产路径
        foreach (string depPath in dependencies)
        {
            if (!depPath.EndsWith(".cs") && !depPath.EndsWith(".js") && !depPath.EndsWith(".boo"))
            {
                if (!assetPaths.Contains(depPath))
                {
                    assetPaths.Add(depPath);
                }
            }
        }

        // 构建打包映射
        AssetBundleBuild[] buildMap = new AssetBundleBuild[1];
        buildMap[0].assetBundleName = $"{bundleName}.unity3d";
        buildMap[0].assetNames = assetPaths.ToArray();

        // 打包选项(可根据需求调整,比如压缩选项)
        BuildAssetBundleOptions buildOptions = BuildAssetBundleOptions.DeterministicAssetBundle
                                             | BuildAssetBundleOptions.UncompressedAssetBundle;

        // 执行打包,使用用户选择的路径
        BuildPipeline.BuildAssetBundles(savePath, buildMap, buildOptions, EditorUserBuildSettings.activeBuildTarget);

        // 刷新资源数据库
        AssetDatabase.Refresh();

        Debug.Log($"AssetBundle打包完成!路径:{savePath}/{bundleName}.unity3d");
    }
}
#endif

额外注意事项

  • 确保所有子预制体未被分配到其他AssetBundle分组,否则Unity会将其视为外部依赖,不会打包进当前Bundle
  • 加载时需确保Bundle加载路径正确,使用AssetBundle.LoadFromFile或对应的异步加载方法
  • 若需要压缩Bundle,可移除UncompressedAssetBundle选项,改用BuildAssetBundleOptions.ChunkBasedCompression(LZ4)或BuildAssetBundleOptions.None(LZMA)

内容的提问来源于stack exchange,提问作者Amine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:06:40