Unity AssetBundle详解

简介

AssetBundle(简称:AB包) 是 Unity 提供的一种资源压缩包,用于在应用运行时动态地加载和卸载资源。它可以将非代码资源(如模型、纹理、预制体、音频、甚至整个场景)打包成一个或多个文件,这些文件可以存放在本地或远程服务器上。(不支持打包C#脚本

AB包的创建

AssetBundles Browser 打包工具

下载安装

GitHub下载地址:GitHub - Unity-Technologies/AssetBundles-Browser: Editor tool for viewing and debugging asset bundle contents before and after builds

1、在Unity工程中创建文件夹Editor

2、将删除资源包中Tests文件夹后放入到Editor文件夹中

3、确认是否安装成功

打开Window=>AssetBundle Browser

资源打包

1、标记资源

选中资源,在Inspector面板进行Assetbundle标记。可以自定义包名和资源扩展名。AssetBundle的名字固定为小写,如果在名字中使用了大写字母,系统会自动转换为小写格式。另外,每个AssetBundle都可以设置一个扩展名。如果需要区别素材,可使用扩展名来加以区分。要添加子文件夹,请用 / 分隔文件夹名称。例如,使用 AssetBundle 名称 environment/forest 在 environment 子文件夹下创建名为 forest 的捆绑包。

2、资源设置

打开AssetBundle Browser窗口,可以看见已经标记过的AB包信息

3、了解Bulid面板

|-----------------------------|--------------------------------------------------------------------------------------------------------------------------------|
| 参数 | 描述 |
| Build Target | 选择面向什么平台打包 |
| Output Path | AssetBundle打包后的输出路径 |
| Clear Folders | 指打包前是否将Output Path中的文件清空 |
| Copy to StreamingAssets | 将Output path中的文件复制到Unity StreamingAssets文件夹中 |
| Compression | No Compression 不压缩,解压快,但是AssetBundle包大 LZMA 压缩大小最小,但是解压慢,如果需要AB包中一个资源,会将所有资源进行解压 LZ4压缩大小会比LZMA大,但是用什么资源就解压什么资源(推荐) |

4、点击Build按钮,进行资源构建

每一个AssetBundle资源将会有一个和文件相关的".mainfest"文件,该文件提供了所打包资源的CRC和资源依赖的信息。还有两个文件(StandaloneWindows),记录整个AssetBundle文件夹的信息,包括资源列表及各个列表之间的依赖关系。

自定义工具(使用AB包构建API)

输出路径一般情况下为Assets下的某一个文件夹,该文件夹不会自动创建,需要玩家在运行前手动创建,否则会报错

cs 复制代码
[MenuItem("项目工具/AssetBundle/构建AB包资源")]
public static void BuildAssetBundleLogic()
{
    BuildPipeline.BuildAssetBundles("Assets/AssetBundles", BuildAssetBundleOptions.None,
        BuildTarget.StandaloneWindows);
}

加载AB包

AssetBundle不能够重复加载,否则报错

|----------------------------------------------|--------------------------|
| 方法 | 描述 |
| AssetBundle.LoadFromFile | 从磁盘上的文件同步加载 AssetBundle。 |
| AssetBundle.LoadAsset(string name) | 从捆绑包中加载名为 name 的资源。 |
| AssetBundle.LoadAsset<T>(string name) | 从捆绑包中加载名为 name 的资源。 |
| AssetBundle.LoadAsset(string name,Type type) | 从捆绑包中加载名为 name 的资源。 |
| AssetBundle.LoadAllAssets | 加载AssetBundle中所有资源对象 |
| AssetBundle.LoadAllAssetsAsync | 异步加载AssetBundle中所有资源togn |

为了便于测试,将打包后的AB包放到StreamingAssets文件夹中,实际开发时可以自己指定路径。

同步加载

cs 复制代码
public Image icon;
    
void Start()
{
    var abPath=Path.Combine(Application.streamingAssetsPath,"role.game");
    //先加载AB包
    var ab = AssetBundle.LoadFromFile(abPath);
    //从AB包中加载指定资源
    var sprite = ab.LoadAsset<Sprite>("迪希雅");
    icon.sprite = sprite;
}

异步加载

cs 复制代码
StartCoroutine(LoadABRes("role.game", "迪希雅", (obj) =>
                         {
                             if (obj is Sprite sprite)
                             {
                                 icon.sprite = sprite;
                             }
                         }));



/// <summary>
/// 异步加载AB包中的资源
/// </summary>
/// <param name="abName">ab包名称</param>
/// <param name="resName">资源名称</param>
/// <param name="callback">成功加载后回调</param>
/// <returns></returns>
IEnumerator LoadABRes(string abName, string resName,Action<object> callback)
{
    //加载ab包
    var ab = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath + "/" + abName);
    yield return ab;
    //从ab包中加载资源
    var asset = ab.assetBundle.LoadAssetAsync(resName, typeof(Sprite));
    yield return asset;
    callback?.Invoke(asset.asset);
}

卸载AB包

|--------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------|
| 方法 | 描述 |
| Unload (bool unloadAllLoadedObjects); 有异步方法 | 卸载 AssetBundle 释放其数据。 当 unloadAllLoadedObjects 为 false 时,只卸载ab包,不清除已加载的资源 当为 true 时,不仅卸载ab包,还会清除已加载的资源引用 |
| AssetBundle.UnloadAllAssetBundles(bool unloadAllObjects) 无异步方法 | 卸载当前已加载的所有 AssetBundle。 unloadAllObjects的true/false规则同上 |

cs 复制代码
private void UnloadAssetBundle(string abName)
{
    var list = AssetBundle.GetAllLoadedAssetBundles().ToList();
    for (var i = 0; i < list.Count; i++)
    {
        var ab = list[i];
        if (ab.name == abName)
        {
            ab.Unload(true);
            break;
        }
    }
}

注意

资源依赖问题

这是 AB 系统中最复杂也最容易出问题的部分。

如果包 A 中的预制体使用了包 B 中的材质,那么包 A 就依赖于包 B。加载包 A 中的预制体前,必须确保包 B 中的材质已经被加载到内存中。

cs 复制代码
//加载依赖资源
private void LoadDependRes(string abName)
{
    //加载主包
    var abMain = AssetBundle.LoadFromFile($"{Application.streamingAssetsPath}/StandaloneWindows");
    //加载主包中的固定文件
    var abManifest = abMain.LoadAsset<AssetBundleManifest>("AssetBundleManifest"); //从固定文件中,得到依赖信息
    var strs = abManifest.GetAllDependencies(abName);

    //得到了依赖包的名字
    foreach (var item in strs)
    {
        AssetBundle.LoadFromFile($"{Application.streamingAssetsPath}/{item}");
    }
}
相关推荐
萘柰奈10 小时前
Unity学习----【进阶】Addressables(二)--加载资源与打包及更新
学习·unity
lvcoc16 小时前
unity 接入火山引擎API,包括即梦AI
windows·unity·ai·火山引擎
王家视频教程图书馆1 天前
2025年最新 unityHub游戏引擎开发2d手机游戏和桌面游戏教程
游戏·unity·游戏引擎
SmalBox1 天前
【URP】法线贴图为什么主要是蓝色的?
unity·渲染
2301_793116942 天前
Unity 解决天空盒中间出现一条线
unity
佩京科技VR2 天前
禁毒教育展厅互动设备-禁毒教育基地-禁毒体验馆方案-VR禁毒教育软件
unity·vr·禁毒展厅·vr禁毒学习机
平行云3 天前
Paraverse平行云实时云渲染助力第82届威尼斯电影节XR沉浸式体验
unity·云原生·ue5·xr·实时云渲染
Xeon_CC3 天前
Unity中,软遮罩SoftMaskForUGUI的使用
unity·游戏引擎
DanmF--3 天前
NGUI--三大基础组件
unity·游戏引擎