Unity-AssetBundle

news2024/10/7 4:34:05

一、AB 包介绍

​ AB 包是特定于平台的资源压缩包,类似于压缩文件。其中资源可包括:模型、贴图、预设体、音效、材质球等等。

​ 相较于 Resources 文件夹下的资源文件,AB 包能够更好管理资源:

  • Resources 文件夹:打包时资源固定,只读,无法修改。

  • AB 包:存储位置可自定义,压缩方式可自定义,后期可动态更新。

​ 用途:

  1. 减小包体大小

    • 压缩资源
    • 减少初始包的大小
  2. 热更新

    • 资源热更新
    • 脚本热更新

第一步:
获取资源服务器地址

第二步:
通过资源对比文件
检测和更新AB包

客户端

自带很少的默认资源

资源对比文件

服务器端

资源服务器

资源对比文件
最新的各种AB包

二、AB 包资源打包

(一)导入 AB 包
  • Unity2019 版本:

    在 Window -> Package Manager 中搜索 “Asset Bundle Browser” 进行安装。

    image-20230608185233975

    安装完成后,在 Project 窗口下可看见 AB 包。

    image-20230608185346645

  • 2019 以上版本:

    对于高版本 Unity,不能通过包管理器进行下载。原因:高版本 Unity 用 Addressables 功能封装了 AB 包功能。

    如果仍要使用 AB 包,在 GitHub 上搜索 AssetBundles 下载对应压缩包,对应链接:GitHub - Unity-Technologies/AssetBundles-Browser: Editor tool for viewing and debugging asset bundle contents before and after builds。

    image-20230608190136883

    下载完成后解压文件夹到项目中,若导入后报错,只需删除导入内容中的事例文件夹即可。

    image-20230608190232062

(二)将资源关联 AB 包

​ 点击需要关联的资源,这里选图片 fat_boss_green01.png

image-20230608191215133

​ 在 Inspector 窗口下方的 AssetBundle 窗口内点击 new 新建 AB 包 monsters,即可将资源装进 monster 包。

image-20230608191514096

​ 点击 Window -> AssetBundle Browser,在 Configure 页签下可以查看新建的 AB 包以及对应关联的资源。

image-20230608192234300

(三)打包参数选项

image-20230608191810720

​ 点击 Build 页签,可以看到有如下打包配置参数:

  1. Build Target:目标平台

  2. Output Path:目标输出路径

  3. Clear Folders:是否清空文件夹 重新打包

  4. Copy To StreamingAssets:是否拷贝到 StreamingAssets 文件夹下

  5. Compression:压缩方式

    • NoCompression:不压缩,解压快,包较大 不推荐
    • LZMA:压缩最小,解压慢
      • 缺点:用一个资源 要解压所有
    • LZ4:压缩,相对 LZMA 大一点点
      • 建议使用,用什么解压什么,内存占用低
  6. 其他(非重要参数)

    • Exclude Type Information:在资源包中不包含资源的类型信息

    • Force Rebuild:重新打包时需要重新构建包

      和 Clear Folders 不同,它不会删除不再存在的包

    • Ignore Type Tree Changes:增量构建检查时,忽略类型数的更改

    • Append Hash:将文件哈希值附加到资源包名上

    • Strict Mode:严格模式,如果打包时报错了,则打包直接失败无法成功

    • Dry Run Build:运行时构建

(四)打包结果

image-20230608192836716

  • maps / monsters:

    maps 包和 monsters 包,为二进制文件,记录了资源数据。

  • maps.manifest / monsters.manifest:

    maps 包和 monsters 包的配置文件,为文本文件,记录了对应资源文件的配置信息。

    • 资源信息(Assets)

    • 依赖关系(Dependencies)

    • 版本信息(ManifestFileVersion)

      等等

    image-20230608193256371

  • StandaloneWindows / StandaloneWindows.manifest:

    所有 AB 包的主包(包名和文件目录名称一样),记录了所有 AB 包的关键依赖关系。

(五)AB 包信息

​ 点击 Inspect 页签,可以看到 AB 包的详细信息。

image-20230608193527659

三、加载 AB 包资源

​ 使用 AB 包加载资源主要分为 2 步:

  1. 加载 AB 包
  2. 加载 AB 包中的资源

​ 注意:AB 包不能重复加载,否则会报错。

​ 以下示例默认 AB 包存储在路径 Application.streamingAssetsPath 下。

(一)同步加载
public class ABTest : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        // 第一步 加载 AB 包
        AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/model");
        
        // 第二步 加载 AB 包中的资源
        // 只用名字加载 会出现同名不同类型资源 分不清
        // 建议使用 泛型加载
        GameObject cube = ab.LoadAsset<GameObject>("Cube");
        // GameObject cube = ab.LoadAsset("Cube", typeof(GameObject)) as GameObject;
        Instantiate(cube);
    }
}
(二)异步加载
public class ABTest : MonoBehaviour
{
    public Image image;
    
    // Start is called before the first frame update
    void Start()
    {
        // 异步加载——协程
        StartCoroutine(LoadABRes("monsters", "fly_yellow02.png"));
    }

	IEnumerator LoadABRes(string ABName, string resName) {
        // 第一步 加载 AB 包
        AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath + "/" + ABName);
        yield return abcr;
        // 第二步 加载 AB 包中的资源
        AssetBundleRequest abq = abcr.assetBundle.LoadAssetAsync(resName, typeof(Sprite));
        yield return abq;

        image.sprite = abq.asset as Sprite;
    }
}
(三)卸载 AB 包
  • 卸载所有 AB 包:

    AssetBundle.UnloadAllAssetBundles(bool unloadAllObjects);

  • 卸载单个 AB 包 ab:

    ab.UnloadAllAssetBundles(bool unloadAllObjects);

    • unloadAllObjects:决定是否卸载场景中 AB 包所创建的资源
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ABTest : MonoBehaviour
{
    public Image image;
    
    // Start is called before the first frame update
    void Start()
    {
        // 第一步 加载 AB 包
        AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/model");
        
        // 第二步 加载 AB 包中的资源
        // 只用名字加载 会出现同名不同类型资源 分不清
        // 建议使用 泛型加载
        GameObject cube = ab.LoadAsset<GameObject>("Cube");
        Instantiate(cube);
        
        // 卸载单个 AB 包
        ab.Unload(false);

        // 加载一个球
        GameObject sphere = ab.LoadAsset("Sphere", typeof(GameObject)) as GameObject;
        Instantiate(sphere);
        
        // 异步加载——协程
        StartCoroutine(LoadABRes("monsters", "fly_yellow02.png"));
    }

    IEnumerator LoadABRes(string ABName, string resName) {
        // 第一步 加载 AB 包
        AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath + "/" + ABName);
        yield return abcr;
        // 第二步 加载 AB 包中的资源
        AssetBundleRequest abq = abcr.assetBundle.LoadAssetAsync(resName, typeof(Sprite));
        yield return abq;

        image.sprite = abq.asset as Sprite;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space)) {
            // 卸载所有加载的 AB 包 参数为 true 会把通过 AB 包加载的资源也卸载
            AssetBundle.UnloadAllAssetBundles(false);
        }
    }
}

(四)AB 包依赖

​ 当 A 包中的某个资源 a 使用了另一个资源 b,则打包时会将 b 默认打包到 A 包中。

​ 如果将资源 b 手动打包进 B 包中,则 A 包中有资源依赖于 B 包。

​ 此时,如果要使用资源 a,则需要同时加载 A 包和 B 包。

​ 具体操作如下:

  1. 加载主包

    AssetBundle abMain = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/StandaloneWindows");
    
  2. 加载主包中的固定文件

    AssetBundleManifest abManifest = abMain.LoadAsset<AssetBundleManifest>(nameof(AssetBundleManifest);
    
  3. 从固定文件中获取 monsters 包的依赖信息

    string[] strs = abManifest.GetAllDependencies("monsters");
    
  4. 加载依赖包

    for (int i = 0; i < strs.Length; i++) {
        AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + strs[i]);
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/782796.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【设计模式】23种设计模式——建造者模式Builder(原理讲解+应用场景介绍+案例介绍+Java代码实现)

介绍 建造者模式又叫生成器模式&#xff0c;是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别)&#xff0c;使这个抽象过程的不同实现方法可以构造出不同属性的对象建造者模式是一步一步创建一个复杂的对象&#xff0c;它允许用户只通过指定复杂对象的类型和…

【PHP面试题79】在Linux中如何设置MySQL和PHP服务开机启动

文章目录 &#x1f680;一、前言&#x1f680;二、设置MySQL服务开机启动&#x1f50e;2.1 打开终端&#x1f50e;2.2 编辑MySQL配置文件&#x1f50e;2.3 修改配置文件&#x1f50e;2.4 检查MySQL服务是否已启动&#x1f50e;2.5 设置MySQL服务开机启动 &#x1f680;三、设置…

C# Modbus通信从入门到精通(12)——Modbus ASCII协议原理

Modbus ASCII是串行链路上的协议,也就是说ModbusASCII是通过串口通信来实现的,它可以通过RS232、RS485物理层的接口来实现,同时它也是一个主从协议,在同一时间总线上只能有一个主站和一个或多个(最多247)个从站。Modbus通信总是由主站发起,从站没有接收到主站的请求时不…

NOAA国家强风暴实验室的天气雷达研究历史(1962年~2016年)

一、1962年-NSSP开始研究WSR-57 美国气象局国家严重风暴项目(NSSP)的一小群研究人员从堪萨斯城搬到俄克拉荷马州诺曼的天气雷达实验室,并开始研究最近安装的研究天气监视雷达-1957(WSR-57)。 二、1964年-NSSL开发的脉冲多普勒雷达技术 1956年,康奈尔航空实验室建造了一…

C++OpenCV(2):图像处理基础概念与操作

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 &#x1f506; OpenCV项目地址及源代码&#xff1a;点击这里 文章目录 图形读取与显示加载图片显示图片打印图片信息保存图片 色彩模型转换RGB颜色模型HSV颜色模型HLS模型LAB模型 图像像素读写操作像素算数运…

python机器学习(二)特征工程、K-近邻算法、KNN工作流程、scikit-learn实现K近邻算法、K值选择、距离计算、KD树

特征工程 把特征转换为机器容易识别的数据&#xff0c;把特征a转化为机器容易读懂、量化的语言 归一化Min-Max 将原始数据映射到[0,1]之间 X ′ x − m i n m a x − m i n X \frac{x-min}{max-min} X′max−minx−min​ 但是归一化是有弊端的&#xff0c;比如有一个值错误…

OJ练习第142题——路径总和 II

113. 路径总和 II 力扣链接&#xff1a;113. 路径总和 II 题目描述 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 Java代码&#xff08;深度优先搜…

基于linux下的高并发服务器开发(第三章)- 3.8 线程同步

sellticket.c /*使用多线程实现买票的案例。有3个窗口&#xff0c;一共是100张票。 */#include <stdio.h> #include <pthread.h> #include <unistd.h>// 全局变量&#xff0c;所有的线程都共享这一份资源。 int tickets 100;void * sellticket(void * arg)…

后处理材质球:黄金螺旋分割线和参考图

后处理材质球&#xff1a;黄金螺旋分割线和参考图 Begin Object Class/Script/UnrealEd.MaterialGraphNode Name"MaterialGraphNode_0"Begin Object Class/Script/Engine.MaterialExpressionLinearInterpolate Name"MaterialExpressionLinearInterpolate_1&qu…

(202307)wonderful-sql:初识数据库(task1)

学习知识 初识数据库 关系型数据库简介 特点是由行和列组成的二维表来管理数据&#xff0c;这种类型的 DBMS 称为关系数据库管理系统&#xff08;Relational Database Management System&#xff0c;RDBMS&#xff09;。本课程将向大家介绍使用 SQL 语言的数据库管理系统&am…

No5:学习过程中基础语法积累

文章目录 基础语法&#xff1a;对象对象构建和数据封装 集合列表截取输出&#xff08;特色是数据可变即可重新赋值&#xff09;元组截取输出&#xff08;元组特色是数据不可变&#xff09;字典&#xff08;根据key取value&#xff09; 字符串函数 基础语法&#xff1a;对象 对…

【动态规划part04】| 背包问题理论基础、416.分割等和子集

目录 &#x1f388;背包问题理论基础 &#x1f45c;01背包 ✨二维dp数组01背包 ✨一维dp数组01背包&#xff08;滚动数组&#xff09; &#x1f388;LeetCode416.分割等和子集 &#x1f388;背包问题理论基础 &#x1f45c;01背包 有n件物品和一个最多能背重量为w 的背…

AUTOSAR从入门到精通-【应用篇】基于 LIN 总线的汽车自动天窗防夹控制系统的设计与实现

目录 前言 天窗控制系统的 LIN 总线 2.1 LIN 总线概述 2.2 LIN 总线协议规范 2.3 防夹控制系统的 LIN 总线 2.4 系统 LIN 网络测试 天窗防夹控制系统整体设计方案 3.1 天窗防夹控制系统功能 3.2 控制系统总体设计 3.2.1 系统结构 3.2.2 天窗防夹控制器 3.2.3 天窗传…

小黑子—JavaWeb:第二章 Maven与MyBatis

JavaWeb入门2.0 1.Maven1.1 Maven 简介1.2 Maven 安装配置1.3 Maven 基本使用1.3.1 Maven常用命令1.3.2 Maven生命周期 1.4 IDEA 配置 Maven1.4.1 配置 Maven 环境1.4.2 Maven 坐标详情1.4.3 IDEA 创建Maven项目1.4.4 IDEA 导入Maven文件1.4.5 配置Maven-Helper 插件 1.5 依赖管…

逻辑斯特回归

*分类是离散的&#xff0c;回归是连续的 下载数据集 trainTrue&#xff1a;下载训练集 逻辑斯蒂函数保证输出值在0-1之间 能够把实数值映射到0-1之间 导函数类似正态分布 其他饱和函数sigmoid functions 循环神经网络经常使用tanh函数 与线性回归区别 塞戈马无参数&#x…

《嵌入式 - 工具》J-link读写MCU内部Flash

1 J-Link简介 J-Link是SEGGER公司为支持仿真ARM内核芯片推出的JTAG仿真器。配合IAR EWAR&#xff0c;ADS&#xff0c;KEIL&#xff0c;WINARM&#xff0c;RealView等集成开发环境支持所有ARM7/ARM9/ARM11,Cortex M0/M1/M3/M4, Cortex A5/A8/A9等内核芯片的仿真&#xff0c;是学…

VirtualBox 7.0.10 使用宿主机物理硬盘

方法&#xff1a; 利用virtualbox的管理工具&#xff0c;将宿主机脱机后的物理硬盘&#xff0c;映射为一个vmdk&#xff0c;然后在vitrualbox中注册该vmdk&#xff0c;然后分配给虚拟机使用。 1. 右键单击window桌面左下角&#xff0c;选择 Windows PowerShell (管理员) 2. c…

第一章 函数的概念

文章目录 考点1、定义域2、对应法则 一、函数的概念1、自变量 x , 因变量 y&#xff0c;一一对应&#xff0c;因此有公式 y f (x)2、定义域具体函数的定义域 &#xff08;送分题&#xff09; 真题1、2、3、4、抽象函数的定义域 真题1、2、 3、根据函数的对应法则求函数表达式题…

会声会影VideoStudio2023中文旗舰版有哪些新功能及最低系统配置要求

会声会影VideoStudio2023中文旗舰版使用起来很有趣。它很容易使用&#xff0c;但仍然给你很多功能和力量。会声会影VideoStudio2023中文旗舰版让我与世界分享我的想法&#xff01;“这个产品的功能非常多&#xff0c;我几乎没有触及它的表面&#xff0c;我可以做大量的编辑、色…

js ==运算规则

let a {name: zhangsan,valueOf(){return 100;} }; let b 100; console.log(ab); //true let a {value: 1,valueOf: function() {return this.value;} };console.log(a 1 && a 2 && a 3); // 输出 true