Unity AssetsBundle打包

为什么要使用AssetsBundle包

减少安装包的大小

默认情况下,unity编译打包是对项目下的Assets文件夹全部内容进行压缩打包

那么按照这个原理,你的Assets文件夹的大小将会影响到你最终打包出的安装包的大小,假如你现在正在制作一个游戏项目,最终打出来的安装包过大可能会对玩家下载造成一定影响,对一般玩家来讲,下载10M的游戏安装包远远比下载100M的游戏安装包要更容易接受,而AssetBundle可以将一部分资源打包到一个压缩包里面,游戏运行到需要的时候再进行下载这部分资源

游戏一共有100个关卡,如果将这些全部打包则打出的安装包大小为100M,如果现在用AssetBundle技术将后面90关的资源分离出去进行打包,那么你现在打包的游戏内容只有10个关卡的资源,安装包大小仅为10M,等玩家体验了前十关觉得还不错,当他想玩10关以后的游戏内容时,提示他需要下载资源包体验更多精彩内容,然后在unity中加载剩余的90关的资源包。这样做的话,你的游戏安装包仅仅10M大小,因为下载比较快,也比较省流量,可能会吸引更多的玩家下载体验你的游戏

可以用热更新修复游戏的Bug

经历千辛万苦,你的游戏终于上线了,突然收到玩家反馈,游戏第20关通关后无法进入到下一关,据查证,是原来打包时某个同事粗心大意把第21关的资源弄错了,导致加载21关时报错,,我们现在需要第一时间修复这个问题,如果是按照原来的打包方式,需要重新出一个100M的包,然后把重新出的包交给游戏平台审核,审核通过后,玩家需要卸载掉原来的游戏软件,重新下载你们新打出的安装包

如果按照另一种打包方式,我们在后面90关的AssetBundle包里修复这个问题,这时候通过服务器传输AssetBundle最新的包,会把有问题的资源进行修复,提示玩家bug已经修复,玩家进入游戏,发现可以把20关打通了,并且成功进入到下一关了,在这个游戏过程中,玩家不需要重新下载那100M的安装包,只需要打开游戏下载部分需要更新的资源,这部分资源一般会比较小,一般情况下可能是几十k的大小,就可以重新体验游戏了。这就是AssetBundle的第二个作用


AssetsBundle包的打包方式

设置资源标签

需要进行AssetsBundle打包的时候,需要先对要打包的资源的资源标签进行设置

调用Unity官方函数打出AssetsBundle包

对资源打包的设置完成后,通过在代码中调用Unity官方函数的方式,将所有设置了资源标签的资源打出AssetsBundle包

调用的函数为:

public static AssetBundleManifest BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform)

这个函数的功能为将所有设置了资源标签的资源打出AssetsBundle包

函数一共有三个参数:

第一个参数为打包出来文件的路径

第二个参数为设置打包资源的压缩方式,是枚举变量,其中比较常用的三个为:

BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快

BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩的包更小,但是加载时间更长,需要解压全部。
BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩,压缩率没有LZMA高,但是我们可以加载指定资源而不用解压全部。

这几种压缩方式中,LZ4比较常用

第三个参数为设置打包资源的应用平台,一般都使用

BuildTarget.StandaloneWindows64 //PC端

BuildTarget.Android //安卓端

BuildTarget.iOS //苹果端

示例代码:

BuildPipeline.BuildAssetBundles(Application.dataPath + "/AssetBundle", BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);

调用函数改变资源标签

改变资源标签的方式,除了在Unity编辑器中设置之外,还可以使用代码设置资源标签

string path = "Assets/MainPrefab.prefab";
AssetImporter importer = AssetImporter.GetAtPath(path);
importer.assetBundleName = "prefab"
importer.assetBundleVariant = "u3d";

这里面应用到的类是AssetImporter类,这个类型代表了AssetBundole资源。

获取AssetImporter类型变量的方法为AssetImporter.GetAtPath(string)方法

这个方法的参数是传入一个由Assets开头,直到文件的后缀名结束的路径,然后将这个文件AssetsBundle相关属性的AssetImporter类返回

然后通过AssetImporter类的assetBundleName改变文件的资源标签

然后通过AssetImporter类的assetBundleVariant改变文件的资源版本标签


加载AssetBundle包

AssetBundle.LoadFromFile 本地资源加载

通过加载本地文件的形式加载AssetBundle资源,场景适用的情况下效率最高

AssetBundle ab = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundle/1.1");

在方法中传入本地资源路径,最后要以AssetBundle包的文件名和后缀名为止,将路径下的AssetBundle包以AssetBundle类型的变量保存下来

AssetBundle.LoadFromFileAsync 本地资源加载(异步)

上面方法的异步版本,在加载过程中不会因为包体过大导致程序进入未响应,需要用到协程(不会协程用法的自己去网上学一下,或者翻我以前的博客)

    IEnumerator LoadAssetBundle(Action<AssetBundle> action){AssetBundleCreateRequest creat = AssetBundle.LoadFromFileAsync(Application.dataPath + "/AssetBundle/1.1");yield return creat;AssetBundle ab = creat.assetBundle;action(ab);}

AssetBundle.LoadFromFileAsync方法参数与同步版本相同,不过返回值由AssetBundle类型变为了AssetBundleCreateRequest类型,这个类型的变量可以作为yield return等待方法的参数,然后通过assetBundle属性获取AssetBundle类型变量

AssetBundle.LoadFromMemory 从数据流加载

通过数据流读取AssetBundle资源,这个方法读取本地文件的效率不如LoadFromFile,所以不要用这个方法加载本地文件的AssetBundle,这个方法应该大部分应用于通过网络协议传输的数据流上

AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes(Application.dataPath + "/AssetBundle/1.1"));

方法的参数为byte数组,返回一个AssetBundle类型的变量

AssetBundle.LoadFromMemoryAsync 从数据流加载(异步)

上述方法的异步版本,通过数据流加载速度相对较慢,比较建议使用异步

    IEnumerator LoadAssetBundle(Action<AssetBundle> action){AssetBundleCreateRequest creat = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(Application.dataPath + "/AssetBundle/1.1"));yield return creat;AssetBundle ab = creat.assetBundle;action(ab);}

与LoadFromFileAsync方法相同,返回一个AssetBundleCreateRequest类型的参数,这个类型的变量可以作为yield return等待方法的参数,然后通过assetBundle属性获取AssetBundle类型变量

UnityWebRequestAssetBundle.GetAssetBundle 从网络获取(异步)

从网址下载AssetBundle包并读取,因为从网络下载的过程都较长,所以这个方法只有异步版本

    IEnumerator LoadAssetBundle(Action<AssetBundle> action){string url = "file://" + Application.dataPath + "/AssetBundle/1.1";UnityWebRequest unityAb = UnityWebRequestAssetBundle.GetAssetBundle(url);yield return unityAb.SendWebRequest();AssetBundle ab = DownloadHandlerAssetBundle.GetContent(unityAb);action(ab);}

方法需要传入一个网址作为参数,将这个参数中的内容下载下来,这里传入了一个本地路径,本地路径也可以作为网址传入,方法返回一个UnityWebRequest类型的变量,这个类型的变量中SendWebRequest方法可以返回一个能够在yield return中应用的值,使协程等待至文件下载完毕,然后通过DownloadHandlerAssetBundle.GetContent方法,传入UnityWebRequest类型的参数,就能够返回AssetBundle类型的变量


从AssetBundle包中获取资源

单纯只是读取到AssetBundle类型的变量是无法直接使用的,需要将AssetBundle类型转换为平时使用的资源类型,比如GameObject,Material。Texture类型

AssetBundle.LoadAsset<>() 从包中读取单个文件

AssetBundle ab = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundle/1.1");
GameObject a = ab.LoadAsset<GameObject>("Cube");

AssetBundle.LoadAsset<>()方法分别有一个泛型类型和一个参数,方法的泛型类型中传入需要从方法中获取的返回值类型,参数为需要获取的类型的名字,上面代码中表示返回AssetBundle包中名为Cube的预设物并保存

AssetBundle.LoadAssetAsync<>() 从包中读取单个文件(异步)

    IEnumerator LoadGameObject(AssetBundle ab , Action<GameObject> action){AssetBundleRequest abr = ab.LoadAssetAsync<GameObject>("Cube");yield return abr;GameObject g = (GameObject)abr.asset;action(g);}

与AssetBundle.LoadAsset<>()方法的泛型和参数应用方式相同,但是返回值为AssetBundleRequest类型,这个类型可以直接传入yield return,并且可以通过asset属性获取保存的资源,不过返回的资源是Object类型,需要进行强制转换

AssetBundle.LoadAllAssets 从包中获取全部文件

AssetBundle ab = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundle/1.1");
UnityEngine.Object[] objs = ab.LoadAllAssets();

AssetBundle.LoadAllAssets 不需要任何参数,返回一个Objcet数组,这个数组包含AssetBundle包中包含的全部资源

AssetBundle.LoadAllAssetsAsync 从包中获取全部文件(异步)

    IEnumerator LoadGameObject(AssetBundle ab , Action<UnityEngine.Object[]> action){AssetBundleRequest abr = ab.LoadAllAssetsAsync();yield return abr;UnityEngine.Object[] objs = ab.LoadAllAssets();action(objs);}

使用方式和LoadAssetAsync相同,只不过是改为了使用LoadAllAssets()方法返回Object数组


卸载AssetBundle资源包

AssetBundle.Unlock 卸载AssetBundle包

        AssetBundle ab = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundle/1.1");ab.Unload(true);

调用AssetBundle类型变量的Unload方法,就能够从内存中卸载AssetBundle包的资源,其中参数的布尔值为是否释放场景中正在使用的AssetBundle包中的资源,一般默认都会传入true作为参数,卸载AssetBundle包时,场景中有涉及到包内资源的物体会报错,所以一般在切换场景或特定情况下使用

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

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

相关文章

Python基础11-字符串处理

连接字符串 要将字符串连接在一起&#xff1a; greeting "Hello" name "Alice" message greeting ", " name "!" print(message)使用 str.format 进行字符串格式化 要将值插入字符串模板&#xff1a; message "{}, {}…

Qt 创建控件的两种方式

目录 Qt 创建控件的两种方式 通过ui界面创建控件 通过代码方式创建控件 Qt 创建控件的两种方式 通过ui界面创建控件 这里当然我们是需要先有一个项目的&#xff0c;按照我们之前创建项目的步骤&#xff0c;我们可以先创建一个 Widget 的项目&#xff0c;但是 MainWindow 也…

SpringBoot源码阅读2-自动配置

SpringBoot源码阅读2-自动配置 在传统的Spring应用中&#xff0c;开发者需要手动配置一系列Web应用的核心组件&#xff0c;例如DispatcherServlet用于处理请求分发、ViewResolver用于视图解析、CharacterEncodingFilter用于字符编码过滤等。 然而在SpringBoot中只要引入了spr…

MySQL中的Performance Schema是什么?

MySQL中的Performance Schema是什么&#xff1f; Performance Schema 是 MySQL 的一个特性&#xff0c;主要用于监控 MySQL 服务器在运行时的性能和资源使用情况。它首次引入于 MySQL 5.5 版本&#xff0c;并在后续版本中得到增强。Performance Schema 提供了一种方式来收集数…

新药品注册分类5大类的注册标准

在医药行业的浩瀚海洋中&#xff0c;药品注册分类就如同一座明亮的航标灯&#xff0c;指引着每一款新药从实验室走向市场&#xff0c;从理论概念变成患者手中的生命希望。本文将深入探讨化学药、中药、生物药的药品注册分类标准&#xff0c;药品分类常见问题、以及如何高效查询…

吴恩达深度学习笔记:深度学习的 实践层面 (Practical aspects of Deep Learning)1.6-1.8

目录 第一门课&#xff1a;第二门课 改善深层神经网络&#xff1a;超参数调试、正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)第一周&#xff1a;深度学习的 实践层面 (Practical aspects of Deep Learning)…

12 JavaScript学习: 字符串

JavaScript 字符串 JavaScript 字符串是一种用于存储和操作文本数据的数据类型。字符串可以包含字母、数字、符号和空格等字符。在 JavaScript 中&#xff0c;字符串可以使用单引号&#xff08;&#xff09;或双引号&#xff08;"&#xff09;来定义。 例如&#xff1a;…

发那科FANUC机器人R-2000iB平衡缸维修攻略

在发那科机器人中&#xff0c;平衡缸扮演着稳定机械臂运动的关键角色。它通过内部的压力调节来平衡负载&#xff0c;保证机器人的精准定位和平稳操作。一旦出现法兰克机械手平衡缸故障或损坏&#xff0c;机器人的性能可能会大打折扣&#xff0c;因此及时且正确的FANUC机械手平衡…

初步认识Vscode

4.26初步认识Vscode &#xff08;一&#xff09;快捷键的使用 1. 打开控制端 ctrl ~2. 结束终端 ctrl c3. 多行同时对齐输出 按住shift alt 光标多选4. 多行同时任意位置输出 按住alt 光标单点你想要输入的位置5. 代码太长了&#xff0c;想混行编辑 alt z6. 打开设置控制…

链表基础(代码注释很多,帮助你更好理解)

概述&#xff1a; 什么是链表&#xff1f; 1、链表是物理存储单元上非连续的、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表的指针地址实现&#xff0c;有一系列结点&#xff08;地址&#xff09;组成&#xff0c;结点可动态的生成。 2、结点包括两个部分&…

003基于SSM的学生选课系统(学生信息管理系统)ssm+mysql

003基于SSM的学生选课系统/学生信息管理系统 开发环境&#xff1a; Eclipse/MyEclipse、Tomcat8、Jdk1.8 数据库&#xff1a; MySQL 前端&#xff1a;JavaScript、jQuery、bootstrap4、particles.js 后端&#xff1a;maven、SpringMVC、MyBatis、ajax、mysql读写分离、mybat…

【目标检测】基于深度学习的酒瓶表面瑕疵缺陷检测(yolov5算法,6个类别,附代码和数据集)

写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。(专栏订阅用户订阅专栏后免费提供数据集和源码一份,超级VIP用户不在服务范围之内) 路虽远,行则将至;事虽难,做…