AssetBundle详解

AssetBundle是Unity的一种资源管理方式,用于减小游戏包体和实现热更新。它支持无压缩、LZMA和LZ4三种压缩格式,其中LZ4在加载时仅解压所需资源,提高效率。AssetBundle打包过程会生成主包文件、资源文件及配置文件,方便资源按需加载。
摘要由CSDN通过智能技术生成

1、AssetBundle是什么?

AssetBundle是一个资源捆绑包,可以包含多个类型文件,可以包含模型,贴图场景,预制体,声音等

2、为什么使用AssetBundle

2.1  资源管理和打包: AssetBundle允许开发者将游戏中的资源(如模型、贴图、声音等)打包成独立的包,以便于动态加载和管理。这对于需要动态更新或减少游戏安装包大小的情况特别有用。

2.2 资源热更新: 通过AssetBundle,开发者可以将游戏的部分或全部资源作为单独的包进行分发和更新,而不必重新发布整个游戏。这使得游戏可以在运   行时进行资源更新,实现热更新的效果,提升游戏的灵活性和可维护性。

2.3 资源优化: 使用AssetBundle可以优化游戏的资源加载效率。资源可以按需加载,减少初始加载时间和内存占用,特别是在移动平台上有显著的性能提升。

2.4 版本控制: 将资源与游戏逻辑分离并使用AssetBundle,可以更好地管理不同版本之间的资源,确保游戏的稳定性和一致性。

2.5 跨平台支持: AssetBundle的设计允许开发者在不同平台上有效地管理和使用资源,提高了游戏在多个设备上的兼容性和性能表现。

3、AssetBundle的三种压缩方式

AssetBundle 在 Unity 中有三种主要的压缩方式,这些方式可以根据游戏项目的需求和目标平台进行选择和配置:

1. **LZMA**: 这是一种高效的压缩算法,能够显著减小 AssetBundle 的大小,适合于对游戏安装包大小有严格要求的情况。使用 LZMA 压缩的 AssetBundle 在加载时可能会稍微慢一些,因为需要进行解压缩操作。

2. **LZ4**: LZ4 是一种轻量级的压缩算法,能够快速压缩和解压缩数据,适合于需要快速加载和处理的场景。虽然相比 LZMA,LZ4 压缩的 AssetBundle 体积较大一些,但加载速度更快,适合需要快速加载资源的游戏。

3. **Uncompressed**: 未压缩的 AssetBundle 直接包含原始资源数据,加载速度最快,但文件体积最大。通常用于需要即时访问高性能数据的场景,如流媒体播放等。

这些压缩方式可以在 Unity 的打包设置中进行配置,开发者可以根据游戏项目的特性和目标平台的性能需求选择最合适的压缩方式,以优化游戏的加载速度和性能表现。


4、AssetBundle如何标记和打包

## 4.1 AB包标记的方式 
     4.1.1 选中要标记的资源,在Inspector进行操作
     4.1.2 使用代码
public static class AssetBundleUnmarker
{
   
    [MenuItem("Assets/AB包操作/检查是否是AB包")]
    public static void CheckAssetBundleMark()
    {
   
        // 获取选中的文件或文件夹
        var selected = Selection.GetFiltered<Object>(SelectionMode.Assets);

        foreach (var obj in selected)
        {
   
            // 获取资产的路径
            string path = AssetDatabase.GetAssetPath(obj);

            // 获取这个路径的AssetImporter
            AssetImporter importer = AssetImporter.GetAtPath(path);

            // 检查资产的AssetBundle名称
            if (!string.IsNullOrEmpty(importer.assetBundleName))
            {
   
                Debug.Log(path + " 标记成了AB包: " + importer.assetBundleName);
            }
            else
            {
   
                Debug.Log(message: path + "没有标记成AB包.");
            }
        }
    }
    [MenuItem("Assets/AB包操作/取消AssetBundle标记")]
    public static void UnmarkSelectedAssetBundle()
    {
   
        // 获取当前选中的所有资产
        foreach (var obj in Selection.objects)
        {
   
            // 获取资产的路径
            string path = AssetDatabase.GetAssetPath(obj);

            // 获取资产的AssetImporter
            AssetImporter importer = AssetImporter.GetAtPath(path);

            // 取消资产的AssetBundle标记
            if (importer != null)
            {
   
                importer.assetBundleName = string.Empty;
                importer.SaveAndReimport();
            }
        }

        // 刷新AssetDatabase以确保更改被应用
        AssetDatabase.Refresh();
        Debug.Log("AssetBundle标记已取消。");
    }
    /*
    // 如果你想取消整个文件夹的AssetBundle标记,你可以使用这个方法
    [MenuItem("Assets/AB包操作/取消整个文件夹的AssetBundle标记")]
    public static void UnmarkAssetBundlesInFolder()
    {
        // 确保有一个选中的文件夹
        var selected = Selection.activeObject;
        if (selected == null) return;

        string folderPath = AssetDatabase.GetAssetPath(selected);
        if (!AssetDatabase.IsValidFolder(folderPath)) return;

        // 获取文件夹内所有资产的路径
        string[] assetPaths = AssetDatabase.GetAllAssetPaths();

        foreach (var path in assetPaths)
        {
            // 只处理选中文件夹内的资产
            if (path.StartsWith(folderPath))
            {
                AssetImporter importer = AssetImporter.GetAtPath(path);
                if (importer != null && !string.IsNullOrEmpty(importer.assetBundleName))
                {
                    importer.assetBundleName = string.Empty;
                    importer.SaveAndReimport();
                }
            }
        }

        AssetDatabase.Refresh();
        Debug.Log($"AssetBundle标记在文件夹'{folderPath}'中已取消。");
    }
    */
    [MenuItem("Assets/AB包操作/标记成AB包")]
    public static void MarkSelectedAssetBundle()
    {
   
        // 获取当前选中的所有资产
        foreach (var obj in Selection.objects)
        {
   
            // 获取资产的路径
            string path = AssetDatabase.GetAssetPath(obj);

            // 获取资产的AssetImporter
            AssetImporter importer = AssetImporter.GetAtPath(path);

            // 为资产设置AssetBundle标记(这里使用资产名作为Bundle名,你可以修改为你想要的名称)
            if (importer != null)
            {
   
                importer.assetBundleName = obj.name.ToLower();
                importer.SaveAndReimport();
            }
        }

        // 刷新AssetDatabase以确保更改被应用
        AssetDatabase.Refresh();
        Debug.Log("AssetBundle标记已设置。");
    }
}
4.2 AB包的打包
4.2.1 AB包打包分类
        AB包的打包分类一般遵循场景,资源,甚至有的预制体进行分类,具体看项目,其中遵循资源分类的好处在于可以避免重复打包

逻辑实体分组
一个UI界面或所有UI界面一个包(贴图、布局信息)
一个角色或所有角色一个包(模型、动画)
场景之间共享的资源一个包
类型分组
所有音频资源一个包
所有模型资源一个包
所有材质资源一个包
并发内容分组
同一时间内需要用到的资源一个包
一个关卡所需的资源一个包
一个场景所需的资源一个包

原文链接:https://blog.csdn.net/XF199710126818/article/details/137779941

如果物体 A 和物体 B 都依赖于同一张贴图 A,但贴图 A 没有被单独设置成一个独立的 AssetBundle 包,而是随着物体 A 和物体 B 的 AssetBundle 打包在一起,这意味着:
增加了 AssetBundle 的容量:贴图 A 的数据会被重复打包进物体 A 和物体 B 的 AssetBundle 中,导致
AssetBundle 包的体积增大。这种重复包含可能会导致不必要的资源冗余。
增加了加载到内存中的数据量:当加载物体 A 或物体 B 的 AssetBundle 时,贴图 A 的数据会随之加载到内存中。如果贴图 A
在多个 AssetBundle 中重复出现,加载时会增加内存使用量,尤其是如果这些 AssetBundle 同时被加载时。
为了避免这种情况,通常建议将共享的资源(如贴图 A)单独设置为一个 AssetBundle 包,然后让物体 A 和物体 B
分别依赖于这个单独的 AssetBundle。这样做有助于减少 AssetBundle 的体积和内存使用,同时优化资源的管理和加载效率。

4.2.2 AB包打包代码

让我解释一下这段代码的各个参数和作用:

BuildPipeline.BuildAssetBundles(assetBundleDirectory,
                                BuildAssetBundleOptions.ChunkBasedCompression,
                                EditorUserBuildSettings.activeBuildTarget);
  1. assetBundleDirectory: 这是打包后的 AssetBundle 文件将存储的目录路径。在这个目录下会生成一个或多个 AssetBundle 文件,每个文件包含了打包好的资源数据和元数据。

  2. BuildAsset

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值