Unity AssetBundles(AB包)

目录

前言

AB包是什么

AB包有什么作用

1.相对Resources下的资源AB包更好管理资源

2.减小包体大小

3.热更新

官方提供的打包工具:Asset Bundle Browser

AB包资源加载

 AB包资源管理模块代码


前言

在现代游戏开发中,资源管理是一项至关重要的任务。随着游戏内容的日益丰富和复杂,如何高效地加载、管理和卸载游戏资源成为了开发者们必须面对的挑战。Unity,作为一款广泛使用的游戏引擎,提供了一套强大的资源管理方案——AssetBundles(简称AB包)。

AB包是什么

特定于平台的资产压缩包,有点类似压缩文件
资产包括:模型、贴图、预设体、音效、材质球等等


AB包有什么作用

1.相对Resources下的资源AB包更好管理资源

2.减小包体大小

1.压缩资源
2.减少初始包大小

3.热更新

资源热更新
脚本热更新


官方提供的打包工具:Asset Bundle Browser

将以下脚本放置在Editor文件夹中

using UnityEditor;
using UnityEngine;public class CreateAssetBundles
{[MenuItem("Assets/Build AssetBundles")]static void BuildAllAssetBundles(){string assetBundleDirectory = "Assets/AssetBundles";if (!System.IO.Directory.Exists(assetBundleDirectory)){System.IO.Directory.CreateDirectory(assetBundleDirectory);}BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);}
}

创建AB包,选中资源,在Asset Bundle里选择New
我这里取名为icon

点击Asset/Build AssetBundles

这样就会在AssetBundles文件夹里生成一些资源文件

AB包文件:资源文件
manifest文件:AB包文件信息;当加载时,提供了关键信息,资源信息,依赖关系,版本信息等等
关键AB包(和目录名一样的包):主包,AB包依赖关键信息

AB包资源加载

将脚本挂载到Image上,启动项目,资源会从ab包中加载到sprite上

using UnityEngine;
using UnityEngine.UI;public class ABTest : MonoBehaviour
{// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){//第一步 加载 AB包AssetBundle ab= AssetBundle.LoadFromFile("Assets/AssetBundles/icon");//第二步 加载 AB包中的资源//只是用名字加载 会出现 同名不同类型资源 分不清//建议用泛型或Type指定类型Sprite icon = ab.LoadAsset("item_0", typeof(Sprite)) as Sprite;GetComponent<Image>().sprite = icon;}// Update is called once per framevoid Update(){}
}

协程加载

using System.Collections;
using UnityEngine;
using UnityEngine.UI;public class ABTest : MonoBehaviour
{// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){StartCoroutine(LoadABRes("item_0"));}IEnumerator LoadABRes(string resName){AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync("Assets/AssetBundles/icon");yield return abcr;//加载资源AssetBundleRequest abq= abcr.assetBundle.LoadAssetAsync(resName,typeof(Sprite));yield return null;GetComponent<Image>().sprite = abq.asset as Sprite;}}

卸载AB包

//卸载所有加载的AB包 参数为ture 会把通过AB包加载的资源也卸载了AssetBundle.UnloadAllAssetBundles(false);

关于AB包的依赖,一个资源身上用到了别的AB包中的资源,这个时候,如果只加载自己的AB包,通过它创建对象会出现资源丢失的情况,这种时候 需要把依赖包 一起加载了 才能正常。

依赖包的固定写法

using System.Collections;
using UnityEngine;
using UnityEngine.UI;public class ABTest : MonoBehaviour
{// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){//第一步 加载 AB包AssetBundle ab = AssetBundle.LoadFromFile("AB包文件路径");//依赖包的关键知识点一利用主包 获取依赖信息//加载主包AssetBundle abMain = AssetBundle.LoadFromFile("主包文件路径");//加载主包中的固定文件AssetBundleManifest abManifest = abMain.LoadAsset<AssetBundleManifest> ("AssetBundleManifest");//从固定文件中 得到依赖信息string[] strs = abManifest.GetAllDependencies("AB包名");for (int i = 0; i < strs.Length; i++) {AssetBundle.LoadFromFile("前置路径/" + strs[i]);}}}

 AB包资源管理模块代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;public class ABMgr : MonoBehaviour
{private static ABMgr instance;public static ABMgr GetInstance(){if (instance == null){GameObject obj = new GameObject();//设置对象的名字为脚本obj.name = typeof(GameObject).ToString();instance = obj.AddComponent<ABMgr>();}return instance;}//主包private AssetBundle mainAB = null;//主包依赖获取配置文件private AssetBundleManifest manifest = null;//选择存储 AB包的容器//AB包不能够重复加载 否则会报错//字典知识 用来存储 AB包对象private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();/// <summary>/// 获取AB包加载路径/// </summary>private string PathUrl{get{return Application.streamingAssetsPath + "/";}}/// <summary>/// 主包名 根据平台不同 报名不同/// </summary>private string MainName{get{
#if UNITY_IOSreturn "IOS";
#elif UNITY_ANDROIDreturn "Android";
#elsereturn "PC";
#endif}}/// <summary>/// 加载主包 和 配置文件/// 因为加载所有包是 都得判断 通过它才能得到依赖信息/// 所以写一个方法/// </summary>private void LoadMainAB(){if (mainAB == null){mainAB = AssetBundle.LoadFromFile(PathUrl + MainName);manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");}}/// <summary>/// 加载指定包的依赖包/// </summary>/// <param name="abName"></param>private void LoadDependencies(string abName){//加载主包LoadMainAB();//获取依赖包string[] strs = manifest.GetAllDependencies(abName);for (int i = 0; i < strs.Length; i++){if (!abDic.ContainsKey(strs[i])){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + strs[i]);abDic.Add(strs[i], ab);}}}/// <summary>/// 泛型资源同步加载/// </summary>/// <typeparam name="T"></typeparam>/// <param name="abName"></param>/// <param name="resName"></param>/// <returns></returns>public T LoadRes<T>(string abName, string resName) where T : Object{//加载依赖包LoadDependencies(abName);//加载目标包if (!abDic.ContainsKey(abName)){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}//得到加载出来的资源T obj = abDic[abName].LoadAsset<T>(resName);//如果是GameObject 因为GameObject 100%都是需要实例化的//所以我们直接实例化if (obj is GameObject)return Instantiate(obj);elsereturn obj;}/// <summary>/// Type同步加载指定资源/// </summary>/// <param name="abName"></param>/// <param name="resName"></param>/// <param name="type"></param>/// <returns></returns>public Object LoadRes(string abName, string resName, System.Type type){//加载依赖包LoadDependencies(abName);//加载目标包if (!abDic.ContainsKey(abName)){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}//得到加载出来的资源Object obj = abDic[abName].LoadAsset(resName, type);//如果是GameObject 因为GameObject 100%都是需要实例化的//所以我们直接实例化if (obj is GameObject)return Instantiate(obj);elsereturn obj;}/// <summary>/// 名字 同步加载指定资源/// </summary>/// <param name="abName"></param>/// <param name="resName"></param>/// <returns></returns>public Object LoadRes(string abName, string resName){//加载依赖包LoadDependencies(abName);//加载目标包if (!abDic.ContainsKey(abName)){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}//得到加载出来的资源Object obj = abDic[abName].LoadAsset(resName);//如果是GameObject 因为GameObject 100%都是需要实例化的//所以我们直接实例化if (obj is GameObject)return Instantiate(obj);elsereturn obj;}/// <summary>/// 泛型异步加载资源/// </summary>/// <typeparam name="T"></typeparam>/// <param name="abName"></param>/// <param name="resName"></param>/// <param name="callBack"></param>public void LoadResAsync<T>(string abName, string resName, UnityAction<T> callBack) where T : Object{StartCoroutine(ReallyLoadResAsync<T>(abName, resName, callBack));}//正儿八经的 协程函数private IEnumerator ReallyLoadResAsync<T>(string abName, string resName, UnityAction<T> callBack) where T : Object{//加载依赖包LoadDependencies(abName);//加载目标包if (!abDic.ContainsKey(abName)){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}//异步加载包中资源AssetBundleRequest abq = abDic[abName].LoadAssetAsync<T>(resName);yield return abq;if (abq.asset is GameObject)callBack(Instantiate(abq.asset) as T);elsecallBack(abq.asset as T);}/// <summary>/// Type异步加载资源/// </summary>/// <param name="abName"></param>/// <param name="resName"></param>/// <param name="type"></param>/// <param name="callBack"></param>public void LoadResAsync(string abName, string resName, System.Type type, UnityAction<Object> callBack){StartCoroutine(ReallyLoadResAsync(abName, resName, type, callBack));}private IEnumerator ReallyLoadResAsync(string abName, string resName, System.Type type, UnityAction<Object> callBack){//加载依赖包LoadDependencies(abName);//加载目标包if (!abDic.ContainsKey(abName)){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}//异步加载包中资源AssetBundleRequest abq = abDic[abName].LoadAssetAsync(resName, type);yield return abq;if (abq.asset is GameObject)callBack(Instantiate(abq.asset));elsecallBack(abq.asset);}/// <summary>/// 名字 异步加载 指定资源/// </summary>/// <param name="abName"></param>/// <param name="resName"></param>/// <param name="callBack"></param>public void LoadResAsync(string abName, string resName, UnityAction<Object> callBack){StartCoroutine(ReallyLoadResAsync(abName, resName, callBack));}private IEnumerator ReallyLoadResAsync(string abName, string resName, UnityAction<Object> callBack){//加载依赖包LoadDependencies(abName);//加载目标包if (!abDic.ContainsKey(abName)){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}//异步加载包中资源AssetBundleRequest abq = abDic[abName].LoadAssetAsync(resName);yield return abq;if (abq.asset is GameObject)callBack(Instantiate(abq.asset));elsecallBack(abq.asset);}//卸载AB包的方法public void UnLoadAB(string name){if (abDic.ContainsKey(name)){abDic[name].Unload(false);abDic.Remove(name);}}//清空AB包的方法public void ClearAB(){AssetBundle.UnloadAllAssetBundles(false);abDic.Clear();//卸载主包mainAB = null;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(一)Linux下安装NVIDIA驱动(操作记录)

目录 一、查看CUDA版本 1.输入nvidia-smi&#xff0c;查看驱动支持的最大CUDA版本&#xff0c;这里是11.6 2.输入nvcc --version&#xff0c;查看当前安装的CUDA版本&#xff0c;这里是11.3 二、卸载旧的NVIDIA驱动 1.卸载原有驱动 2.禁用nouveau&#xff08;必须&#x…

用Python做数据分析环境搭建及工具使用(Jupyter)

目录 一、Anaconda下载、安装 二、Jupyter 打开 三、Jupyter 常用快捷键 3.1 创建控制台 3.2 命令行模式下的快捷键 3.3 运行模式下快捷键 3.4 代码模式和笔记模式 3.5 编写Python代码 一、Anaconda下载、安装 【最新最全】Anaconda安装python环境_anaconda配置python…

Ai编程cursor + sealos + devBox实现登录以及用户管理增删改查(十三)

一、什么是 Sealos&#xff1f; Sealos 是一款以 Kubernetes 为内核的云操作系统发行版。它以云原生的方式&#xff0c;抛弃了传统的云计算架构&#xff0c;转向以 Kubernetes 为云内核的新架构&#xff0c;使企业能够像使用个人电脑一样简单地使用云。 二、适用场景 业务运…

重学设计模式-工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)

在平常的学习和工作中&#xff0c;我们创建对象一般会直接用new&#xff0c;但是很多时候直接new会存在一些问题&#xff0c;而且直接new会让我们的代码变得非常繁杂&#xff0c;这时候就会巧妙的用到设计模式&#xff0c;平常我们通过力扣学习的算法可能并不会在我们工作中用到…

数据结构4——栈和队列

目录 1.栈 1.1.栈的概念及结构 1.2栈的实现 2.队列 2.1队列的概念及结构 2.2队列的实现 1.栈 1.1.栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一段称为栈顶&#xff0c;另一端称为…

家政小程序开发,打造便捷家政生活小程序

目前&#xff0c;随着社会人就老龄化和生活压力的加重&#xff0c;家政服务市场的需求正在不断上升&#xff0c;家政市场的规模也正在逐渐扩大&#xff0c;发展前景可观。 在市场快速发展的影响下&#xff0c;越来越多的企业开始进入到市场中&#xff0c;同时家政市场布局也发…

Spring Cloud Alibaba(六)

目录&#xff1a; 分布式链路追踪-SkyWalking为什么需要链路追踪什么是SkyWalkingSkyWalking核心概念什么是探针Java AgentJava探针日志监控实现之环境搭建Java探针日志监控实现之探针实现编写探针类TestAgent搭建 ElasticsearchSkyWalking服务环境搭建搭建微服务微服务接入Sky…

HTTP 探秘之旅:从入门到未来

文章目录 导言&#xff1a;目录&#xff1a;第一篇&#xff1a;HTTP&#xff0c;互联网的“快递员”第二篇&#xff1a;从点开网页到看到内容&#xff0c;HTTP 究竟做了什么&#xff1f;第三篇&#xff1a;HTTP 的烦恼与进化史第四篇&#xff1a;HTTP 的铠甲——HTTPS 的故事第…

万字长文解读深度学习——多模态模型BLIP2

&#x1f33a;历史文章列表&#x1f33a; 深度学习——优化算法、激活函数、归一化、正则化 深度学习——权重初始化、评估指标、梯度消失和梯度爆炸 深度学习——前向传播与反向传播、神经网络&#xff08;前馈神经网络与反馈神经网络&#xff09;、常见算法概要汇总 万字长…

qt QToolBox详解

1、概述 QToolBox是Qt框架中的一个控件&#xff0c;它提供了一个带标签页的容器&#xff0c;用户可以通过点击标签页标题来切换不同的页面。QToolBox类似于一个带有多页选项卡的控件&#xff0c;但每个“选项卡”都是一个完整的页面&#xff0c;而不仅仅是标签。这使得QToolBo…

如何把阿里云ECS里的文件下载到本地(免登录免配置)

如何把阿里云ECS里的文件下载到本地&#xff08;免登录免配置&#xff09; 作为一个阿里云ECS的用户&#xff0c;Up时长会遇到希望把ECS里的文件下载到自己的个人电脑&#xff0c;然后在自己的电脑里面查看&#xff0c;保存或者发送给别人。最近发现阿里云新上了一个功能&…

Centos7安装MySQL8.0详细教程(压缩包安装方式)

本章教程&#xff0c;主要介绍如何在Centos7上安装MySQL8.0版本数据库&#xff08;压缩包安装方式&#xff09; 一、卸载系统自带的 Mariadb 1、查询 rpm -qa|grep mariadb2.、卸载 如果有查询结果&#xff0c;就进行卸载&#xff0c;没有就跳过该步骤。 rpm -e --nodeps mar…

c++预编译头文件

文章目录 c预编译头文件1.使用g编译预编译头文件2.使用visual studio进行预编译头文件2.1visual studio如何设置输出预处理文件&#xff08;.i文件&#xff09;2.2visual studio 如何设置预编译&#xff08;初始创建空项目的情况下&#xff09;2.3 visual studio打开输出编译时…

MySql:理解数据库

目录 一、什么是数据库 第一层理解 第二层理解 第三层理解 二、Linux下的数据库 三、基本认识 登录数据库时&#xff0c; mysql -u root -h 127.0.0.1 -P 3306 -p -h指定MySql服务器所在主机&#xff0c;若在本地则为回环地址。-P表示目标主机上MySql服务端口号 一般简单…

Spire.PDF for .NET【页面设置】演示:旋转 PDF 中的页面

在某些情况下&#xff0c;您可能需要旋转 PDF 页面。例如&#xff0c;当您收到包含混乱页面的 PDF 文档时&#xff0c;您可能希望旋转页面以便更轻松地阅读文档。在本文中&#xff0c;您将学习如何使用Spire.PDF for .NET在 C# 和 VB.NET 中旋转 PDF 中的页面。 Spire.PDF for…

【JavaEE初阶 — 网络编程】实现基于TCP协议的Echo服务

TCP流套接字编程 1. TCP &#xff06; UDP 的区别 TCP 的核心特点是面向字节流&#xff0c;读写数据的基本单位是字节 byte 2 API介绍 2.1 ServerSocket 定义 ServerSocket 是创建 TCP 服务端 Socket 的API。 构造方法 方法签名 方法说明 ServerS…

[linux应用]emby媒体服务器软件简单部署和使用

一、介绍 Emby 是一款媒体服务器软件&#xff0c;用于组织、管理和共享个人的音乐、电影、电视节目和其他媒体文件。简单来说&#xff0c;是管理和播放电影的软件。官方网址&#xff1a;Emby - The open media solution 二、部署 安装包下载地址&#xff1a;Download Emby -…

burp2

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…

基于hexo框架的博客搭建流程

这篇博文讲一讲hexo博客的搭建及文章管理&#xff0c;也算是我对于暑假的一个交代 &#xff01;&#xff01;&#xff01;注意&#xff1a;下面的操作是基于你已经安装了node.js和git的前提下进行的&#xff0c;并且拥有github账号 创建一个blog目录 在磁盘任意位置创建一个…

106.【C语言】数据结构之二叉树的三种递归遍历方式

目录 1.知识回顾 2.分析二叉树的三种遍历方式 1.总览 2.前序遍历 3.中序遍历 4.后序遍历 5.层序遍历 3.代码实现 1.准备工作 2.前序遍历函数PreOrder 测试结果 3.中序遍历函数InOrder 测试结果 4.后序遍历函数PostOrder 测试结果 4.底层分析 1.知识回顾 在99.…