Unity资源打包(一):AssetBundle使用-2020更新
正所谓:自古套路得人心,学会AssetBundle开发,成就更精简游戏包。
- 欢迎关注公众号:雷潮课堂
###AssetBundle打包
一、课程内容
1-1游戏套路
1-2什么是AssetBundle
1-3AssetBundle的作用
二、使用AssetBundle打包
2-1版本5.0前后打包
2-2版本5.0前后解压
2-3手动打包2020版本
三、加载AssetBundle
3-1加载本地AssetBundle(模型,图片)
3-2网络加载AssetBundle(网络加载(UnityWebRequest))
3-3 AssetBundle打包路径问题(不同平台Android、iOS、PC)
四、打包工具的开发
4-1 批量命名打包
4-2 官方Demo案例介绍
1-1、游戏套路
我们经常下载一些游戏App,如果Wifi情况下,App大小就无关紧要。但是如果是流量呢?一看到App的大小,直接就不下了。但是游戏公司怎么会不知道?所以采用热更新,或者直接下载完毕后,再进行加载的行为进行笼络用户。当然这也是产品要求的结果。这里不说游戏的好玩,只讨论这种套路是什么手段进行的。
1-2、什么是AssetBundle?
资源需要打包发布,所以Unity提供的打包策略,也就是AssetBundle。这个的方式有自己的压缩格式(LZMA\压缩),其实就是精简你的资源。简称AB,几乎所有的资源都可以打包程AB,AB可以存放Unity可识别的任何资源类型,具体取决于文件的扩展名。例如:导入的文件后缀为“.byte”,Unity会将这些文件作为文本(TextAssets)导入。导入的文件后缀为“.spine”,Unity会将这些文件作为动画导入。
可以通过官方的Demo来进行学习:Unity5 AssetBundle Demo
1-3、AssetBundle的作用
由于我们要将模型资源放在远程的服务器端,但如果直接放fbx模型是不可以加载的,所以我们可以将fbx做成预设或者是直接将其打包成assetbundle格式的,然后通过www来加载获取。
如果将上述流程反过来,就是加载服务器数据包
2、使用AssetBundle
在打包的时候,可能会重复打包,造成资源包很大。可以将资源拆分细致后,独立打包。
比如:一个模型的网格Mesh,材质Material,贴图Texture.
2-1 Unity5.0之前旧版AB打包
本先扫描所有要打包的资源,然后AssetDatabase.GetDespendencie获得所有的依赖,自己记录起来,由于怕资源名称相同,所以使用AssetDatabase。AssetPathToGUID获得资源的唯一id,然后存起来。
获得所有依赖关系之后,再使用BuildPipeline.PushAssetDependencies和BuildPipeline.PopAssetDependencies按照层级和顺序来打包。这样打出来的资源就完全保留了依赖关系,文件会被拆散,不会重复打包。
2-2 Unity5.0之后,AB打包
BulidPipeline.BuildAssetBundles(outputPath,BuildAssetBundleOptions,BuildTarget)
BuildAssetBundleOptions.None:默认构建AssetBundle的方式。使用LZMA算法压缩,此算法压缩包小,但是加载时间长,而且使用之前必须要整体解压。解压以后,这个包又会使用LZ4算法重新压缩,这样这种包就不要对其整体解压了。(也就是第一次解压很慢,之后就变快了。
BuildAssetBundleOptions.UncompressedAssetBundle:不压缩数据,包大,但是加载很快。
BuildAssetBundleOptions.ChunkBaseCompression:使用LZ4算法压缩,压缩率没有LZMA高,但是加载资源不必整体解压。这种方法中规中矩,我认为比较常用。
以上是常用的三种,接下来会对你其余的几种做简单的介绍
BuildAssetBundleOptions.DisableWriteTypeTree:不会在AssetBundle中包含类型信息。
BuildAssetBundleOptions.DeterministicAssetBundle:使用存储在Asset Bundle中的对象的id的哈希构建Asset Bundle。
BuildAssetBundleOptions.ForceRebuildAssetBundle:强制重建Asset Bundles。
BuildAssetBundleOptions.IgnoreTypeTreeChanges:执行增量构建检查时忽略类型树更改。
BuildAssetBundleOptions.AppendHashToAssetBundleName:将哈希附加到assetBundle名称。
BuildAssetBundleOptions.StrictMode:如果在其中报告任何错误,则不允许构建成功。
BuildAssetBundleOptions.DryRunBuild:不实际构建它们。
BuildAssetBundleOptions.DisableLoadAssetByFileName:通过文件名禁用Asset Bundle的加载。
BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtension:通过带扩展名的文件名禁用Asset Bundle 的加载。
StandaloneWindows: 打包32位windows平台上的包。
StandaloneWindows64: 打包64位windows平台上的包。
iOS: 打包iOS平台上的包。
Android : 打包Android平台上的包。
每一个资源可以设置一个assetBundleName。只要调用这个方法,那么所有已经设置过AB的资源,就会自动打包。
2-3、手动打包2020版本
3-1 加载AssetBundle 这里要使用编辑器开发,请点击另一篇文章
public class AssetBundle : Editor
{[MenuItem("Tools/CreatAssetBundle")]public static void CreatAssetBundle(){string filePath = "AssetBundle"; // 文件名为“AsssetBundle”if (Directory.Exists(filePath) == false) // 判断是否存在,不存在创建{Directory.CreateDirectory(filePath); // 根据文件夹路径创建文件夹} // 可以使用这个ApI (打包输出的路径,压缩格式(枚举),编译平台)BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);}
}
// 加载模型AssetBundle ab = AssetBundle.LoadFromFile("AssetBundle/cube.unity");GameObject go = ab.LoadAsset<GameObject>("Cube");GameObject cube = Instantiate(go);
if (img == null) // 如果Img没有赋值{img = GameObject.Find("Image").GetComponent<Image>(); // 寻找图片所在的物体,并获取身上的组件Image}AssetBundle ab = AssetBundle.LoadFromFile("AssetBundle/img"); // 加载AB资源包Sprite s = ab.LoadAsset<Sprite>("1213"); // 加载资源包中的1212图片img.sprite = s; //将加载的图片进行赋值
3-2、网络加载AssetBundle(UnityWebRequest)
1.引用using UnityEngine.Networking.
2. - UnityWebRequest.GetAssetBundle(URL)获取assetBundle资源,返回资源的函数SendWebRequest()
- DownloadHandlerAssetBundle.GetContent()获取assetBundle资源包
- LoadAsset<>()加载,实例化。
void Start () {
StartCoroutine(Load());
}
private IEnumerator Load()
{string url = "";//此为AssetBundle资源路径,可为本地,也可以是服务端UnityWebRequest request= UnityWebRequest.GetAssetBundle(url);yield return request.SendWebRequest ();// AssetBundle ab = DownloadHandlerAssetBundle.GetContent (request );AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;GameObject ao = ab.LoadAsset<GameObject>("Cube");Instantiate(ao);
}
- 加载音乐
IEnumerator LoadABWeb()
{UnityWebRequest request = UnityWebRequest.GetAssetBundle(path);yield return request.SendWebRequest();Debug.Log(request.error);AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);audio.clip = bundle.LoadAsset<AudioClip>("music01");audio.Play();
}
3-3、AssetBundle打包路径问题(不同平台Android、iOS、PC)
官方的讲解
1.首先要讲一下不同平台下的一个StreamingAssets路径,这是不同的。
//不同平台下StreamingAssets的路径是不同的,这里需要注意一下。public static readonly string PathURL =
#if UNITY_ANDROID //安卓"jar:file://" + Application.dataPath + "!/assets/";
#elif UNITY_IPHONE //iPhoneApplication.dataPath + "/Raw/";
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR //windows平台和web平台"file://" + Application.dataPath + "/StreamingAssets/";
#elsestring.Empty;
#endif
这就获取到了不同平台的一个路径,我们可以将打包的文件放在这些路径下,然后再从这路径去读取资源,前提要手动创建一个StreamingAssets文件夹
2.关于打包assetbundle的脚本
using UnityEngine;
using System.Collections;
using UnityEditor;public class Test : Editor
{//打包单个[MenuItem("Custom Editor/Create AssetBunldes Main")]static void CreateAssetBunldesMain (){//获取在Project视图中选择的所有游戏对象Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);//遍历所有的游戏对象foreach (Object obj in SelectedAsset) {//本地测试:建议最后将Assetbundle放在StreamingAssets文件夹下,如果没有就创建一个,因为移动平台下只能读取这个路径//StreamingAssets是只读路径,不能写入//服务器下载:就不需要放在这里,服务器上客户端用www类进行下载。string targetPath = Application.dataPath + "/StreamingAssets/" + obj.name + ".assetbundle";if (BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)) {Debug.Log(obj.name +"资源打包成功");} else {Debug.Log(obj.name +"资源打包失败");}}//刷新编辑器AssetDatabase.Refresh (); }[MenuItem("Custom Editor/Create AssetBunldes ALL")]static void CreateAssetBunldesALL (){ Caching.CleanCache ();string Path = Application.dataPath + "/StreamingAssets/ALL.assetbundle"; Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);foreach (Object obj in SelectedAsset) {Debug.Log ("Create AssetBunldes name :" + obj);} //这里注意第二个参数就行if (BuildPipeline.BuildAssetBundle (null, SelectedAsset, Path, BuildAssetBundleOptions.CollectDependencies)) {AssetDatabase.Refresh ();} else { }}[MenuItem("Custom Editor/Create Scene")]static void CreateSceneALL (){//清空一下缓存Caching.CleanCache();string Path = Application.dataPath + "/MyScene.unity3d";string []levels = {"Assets/Level.unity"};//打包场景BuildPipeline.BuildPlayer( levels, Path,BuildTarget.WebPlayer, BuildOptions.BuildAdditionalStreamedScenes);AssetDatabase.Refresh ();}
}
3.读取资源,这里只举例从本地读取,跟从网络读取是一样的,可以参考官方文档:
本地读取
using UnityEngine;
using System.Collections;
public class MyAssetBundleRun : MonoBehaviour
{//不同平台下StreamingAssets的路径是不同的,这里需要注意一下。public static readonly string PathURL =
#if UNITY_ANDROID"jar:file://" + Application.dataPath + "!/assets/";
#elif UNITY_IPHONEApplication.dataPath + "/Raw/";
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR"file://" + Application.dataPath + "/StreamingAssets/";
#elsestring.Empty;
#endifvoid OnGUI(){if(GUILayout.Button("Main Assetbundle")){//StartCoroutine(LoadMainGameObject(PathURL + "Prefab0.assetbundle"));//StartCoroutine(LoadMainGameObject(PathURL + "Prefab1.assetbundle"));StartCoroutine(LoadMainCacheGameObject(PathURL + "Prefab0.assetbundle"));StartCoroutine(LoadMainCacheGameObject(PathURL + "Prefab1.assetbundle"));}if(GUILayout.Button("ALL Assetbundle")){StartCoroutine(LoadALLGameObject(PathURL + "ALL.assetbundle"));}if(GUILayout.Button("Open Scene")){StartCoroutine(LoadScene());}}//读取一个资源private IEnumerator LoadMainGameObject(string path){WWW bundle = new WWW(path);yield return bundle;//加载到游戏中yield return Instantiate(bundle.assetBundle.mainAsset);bundle.assetBundle.Unload(false);}//读取全部资源private IEnumerator LoadALLGameObject(string path){WWW bundle = new WWW(path); yield return bundle; //通过Prefab的名称把他们都读取出来Object obj0 = bundle.assetBundle.Load("Prefab0");Object obj1 = bundle.assetBundle.Load("Prefab1");//加载到游戏中 yield return Instantiate(obj0);yield return Instantiate(obj1);bundle.assetBundle.Unload(false);}private IEnumerator LoadMainCacheGameObject(string path){WWW bundle = WWW.LoadFromCacheOrDownload(path,5); yield return bundle; //加载到游戏中yield return Instantiate(bundle.assetBundle.mainAsset); bundle.assetBundle.Unload(false);}private IEnumerator LoadScene(){WWW download = WWW.LoadFromCacheOrDownload ("file://"+Application.dataPath + "/MyScene.unity3d", 1); yield return download;var bundle = download.assetBundle;Application.LoadLevel ("Level");}
}
4-1、批量命名自动打包
项目中的资源涉及方方面面,我们不可能每个都进行修改名字并打包,所以需要一个工具,来帮助我们批量命名自动打包
这里是核心代码块,也是游戏核心开发人员的必备技能涉及自定义编辑器工具模块,可以在最下方购买哦我们的课程。
4-2 官方Demo案例介绍
- 可以加群134688909 将Demo下载下来,因为接下来全部使用这个进行。
我们可以测试一下打包成程序
会输出一个文件,你可以选择一个文件夹进行输出。
我们实际这样做了,发现输出控制台有如下输出
我们可以将寻找一下是那个代码中输出的这个话
顺藤摸瓜之后其实我们发现就是我们的当前项目中的场景没有加载进去
- 运行后,发现与我们手动打包出来的程序一模一样,也就是说我们可以程序的手段进行编译打包。那么这个代码在哪?我们是不是可以直接使用呢?
StreamingAssets它下面的所有资源不会被加密,然后是原封不动的打包到发布包中
然后我们就可以开始玩耍游戏中的所有场景了,因为资源已经OK了。可以寻找并加载了。
- 欢迎购买本课程:
腾讯课堂
网易云课堂
Unity资源打包(一):AssetBundle使用-2020更新相关推荐
- Unity资源打包之Assetbundle
本文原创版权归 csdn janeky 所有,转载请详细注明原创作者及出处,以示尊重! 作者:janeky 原文:http://blog.csdn.net/janeky/article/details ...
- Unity资源打包之Asset Bundle(学习笔记)
Asset Bundle的作用: 1.AssetBundle是一个压缩包包含模型.贴图.预制体.声音.甚至整个场景,可以在游戏运行的时候被加载: 2.AssetBundle自身保存着互相的依赖关系: ...
- Unity资源处理机制(Assets/WWW/AssetBundle/...)读取和加载资源方式详解
Unity资源机制 1.概述 本文意在阐述Unity资源机制相关的信息,以及一些关于个人的理解与试验结果.另外还会提及一些因机制问题可能会出现的异常以及处理建议.大部分机制信息来源于官方文档,另外为自 ...
- Unity游戏开发客户端面经——热更新(初级)
前言:记录了总6w字的面经知识点,文章中的知识点若想深入了解,可以点击链接学习.由于文本太多,按类型分开.这一篇是 热更新 常问问题总结,有帮助的可以收藏. 1. 热更新的原理 1.1 为什么使用Lu ...
- 一、创建Assetbundle 在unity3d开发的游戏中,无论模型,音频,还是图片等,我们都做成Prefab,然后打包成Assetbundle,方便我们后面的使用,来达到资源的更新。
一.创建Assetbundle 在unity3d开发的游戏中,无论模型,音频,还是图片等,我们都做成Prefab,然后打包成Assetbundle,方便我们后面的使用,来达到资源的更新. 一个Asse ...
- [FairyGUI][Unity]FGUI资源打包AssetBundle
参考资料3 将发布后的文件打包为两个AssetBundle,即定义文件和资源各打包为一个bundle(desc_bundle+res_bundle).这样做的好处是一般UI的更新都是修改元件位置什么的 ...
- Unity骚操作:Spine动画打包成AssetBundle资源到安卓平台时,材质丢失的问题解决方案
目录 Spine动画打包成AssetBundle资源到安卓平台时,材质丢失. 如果真的特别需要在u3d编辑器中显示为正常,可以手动在编辑器中的右边Inspector面板重新选择一下材质球的shader ...
- 资源打包Assetbundle .
在手游的运营过程中,更新资源是比不可少的.资源管理第一步是资源打包.传统的打包可以将所有物件制成预设Prefab,打包成场景.今天我们来一起学习官方推荐的Assetbundle,它是Unity(Pro ...
- Unity资源热更新--资源管理、Addressable
实习前理解错了mentor的意思,任务没完成TAT,火速学习一下addressable,另外狠狠吐槽北京健康宝弹窗. 资源打包方式 可热更资源类型:预制件.材质.贴图.模型.场景.shader.动画与 ...
最新文章
- 北京大学纳家勇治研究组在《美国国家科学院院刊》发文阐明时序记忆的神经机制
- 《深入解析Android 5.0系统》——第1章,第1.2节安装开发包
- Linux内核的namespace机制分析
- ASP调用sql server 存储过程详解-附带实例-
- C++虚继承(三) --- C++ 对象的内存布局(下)(陈皓)
- java分页数据导出excel
- add-apt-repository cloud-archive:liberty
- python跳过错误_Pandas之read_csv()读取文件跳过报错行的解决
- 【干货】推荐技术分享-多业务融合推荐实践与思考.pdf(附50页ppt下载链接)
- MD(d)、MT(d)编译选项的区别
- git把当前修改提交合并到上一条提交如何操作
- 2022年申请亳州市发明专利材料,专利说明书摘要写作技巧
- STEAM 正在检查可用更新 ,失败
- 北京智能机器人为游客指路;日本研发出可识别背影的人工智能
- 一条SQL语句在MySQL中执行过程全解析
- windows xp 提示系统是盗版图标右下角有个五角星图标
- (性能测试压箱底知识点)LR性能测试---结果(样例)分析
- 无需会员将有道云笔记脑图转换xmind
- 矩阵特征值和特征向量求解——特征值分解
- 8255A控制八位七段LED数码管
热门文章
- Windows10系统中怎么使用32位IE浏览器?
- 神经网络收敛是什么意思,算法的收敛速度的计算
- asp.net 中根据sessionid 获取或删除session
- Xception详解
- 微信小程序 - 引入使用 MD5 加密
- 5年前流行的某棋牌游戏大厅源码
- 如何将Word表格内的文字居中对齐
- 安装ngtpy踩坑记录(C++打包Python的一些小坑)
- ffmpeg 多个视频先去掉声音合并后,再添加文字与音频
- DeCAF: A Deep Convolutional Activation Featurefor Generic Visual Recognition阅读报告(1)