Unity 3-7 AssetBundle从入门到掌握
任务1&2&3:课程介绍
AssetBundle -- 用于资源的更新
为了之后的xLua (Lua热更新的框架)打下基础
任务4&5:AssetBundle的定义和作用
AssetBundle的学习 -- 一手学习资源:UnityManual -> AssetBundles -> 教程式的文档
AssetBundle是一个压缩包(也可以认为是一个文件夹)
包含模型Model、贴图Texture、预制体Prefab、声音AudioClip、甚至整个场景
在游戏运行的时候可以被加载
这个压缩包被打包出来存在硬盘中,里面包含的文件可以分为两类:serialized file和resource files
serialized file:资源,如模型、预制体,被打碎放在一个对象中,最后统一被写进一个单独的文件
resource file:某些二进制资源,如图片、声音,被单独保存,方便快速加载
-- 一个单独的图片或声音就会被打包成一个.resource文件
压缩包可以使用LZMA和LZ4压缩算法,便于更快的进行网络传输 -- 区别之后会讲
为什么会用到网络传输呢?
1. 把一些可以下载的资源放在AssetBundle中,而不放在app中,而在需要的时候从网上直接加载资源
-- 减少安装包的大小
安装包过大:影响用户体验,或导致用户不想下载
2. 方便更新
-- 对于某些模型,如果进行某些活动更新,用户不需要更新安装包
进入游戏后,检查资源更新,从服务器上下载模型并加载即可
第一次启动后,或之后有更新时,下载更新包到本地,之后就不用下载了
AssetBundle自身保存着互相的依赖关系
比如一个包是专门保存模型的,而另一个包是专门保存贴图的,那这两个包之间就会有依赖关系
AssetBundle在加载时,作为一个AssetBundle对象,对象中包含的内容就是AssetBundle压缩包中的内容
任务6:AssetBundle使用流程
https://docs.unity3d.com/Manual/AssetBundles-Workflow.html
1. 指定资源的AssetBundle属性
2. 构建AssetBundle包
AssetBundle包可以有多个,每个AssetBundle包中可以有多个文件
Unity会搜寻项目中的资源,如果资源被标记了需要打包,则会被打包到AssetBundle包中
3. 上传AssetBundle包
一般情况下都会上传到服务器
4. 加载AssetBundle包及其中的资源
启动游戏之后,游戏会在服务器上检查更新,将更新包下载到本地,加载上面的资源
任务7&8:打包AssetBundle
1. 指定资源的AssetBundle属性
从AssetStore上搜索Material资源
创建一个Cube,拉伸成一个墙壁的形状,将mat资源附加上
制作成一个名为wall的prefab
修改wall prefab的AssetBundle标签,New -> Wall (不区分大小写)
前面也可以写成 aaa/bbb的格式,表示在aaa文件夹下生成名为bbb的assetbundle文件
比如:scene/wall
后缀写成assetbundle,不是必要的,随意填写都行
设置成相同的assetbundle属性的不同物品,会被打包到相同的assetbundle文件中
2. 使用Unity的API进行构建AssetBundle包
这个API是只有在Editor模式下才运行的
创建Editor文件夹
新建CreateAssetBundles.cs脚本
using UnityEditor;
不继承自MonoBehaviour
BuildPipeline.BuildAssetBundles(string outputPath, BuildAssetBundleOptions option, BuildTarget platform);
string path; // path是以工程的根目录为基础的 -- 输出目录需要已存在,Unity不会自动创建路径
因此需要进行路径是否存在的判断
using System.IO;
if(!Directory.Exists(path)) {
Directory.CreateDirectory(path);
}
BuildAssetBundleOptions.None // 表示不去设置该选项
BuildTarget.StandaloneWindows64 // 表示为了window64平台打包的
using UnityEditor;
using System.IO;
public class CreateAssetBundle {
[MenuItem("Assets/BuildAssetBundles")]
static void BuildAllAssetBundles() {
string path = "AssetBundles";
if (!Directory.Exists(path)){
Directory.CreateDirectory(path);
}
BuildPipeline.BuildAssetBundles(path,
BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
}}
[MenuItem("Assets/BuildAssetBundles")] // 表示这个方法在菜单栏Assets下创建子菜单BuildAssetBundles
Unity中,Assets -> 点击BuildAssetBundles,就会进行AssetBundle的打包了
Unity中的Project下没有任何变化,
在系统中打开工程根目录,会发现新建了一个AssetBundles文件夹
wall.assetbundle就是wall的prefab文件
wall.assetbundle.manifest记录了wall.assetbundle的依赖项
AssetBundles是为当前目录
AssetBundles.manifest当前目录生成了哪一些assetbundle文件
.manifest是文本文件,一个assetbundle文件对应一个manifest文件
记录了对应的assetbundle的依赖,详见任务14
如何删除不用的assetbundle名字呢
比如现在发现我们的assetbundle名写错了,重新生成一个assetbundle
但是设置assetbundle属性的菜单中,会发现原来的assetbundle名字没有被替换,依然存在
在设置资源的AssetBundle属性的地方,选择remove unused names
现在,在设置assetbundle属性的菜单里就找不到不用的assetbundle名了
任务9:AssetBundle的加载和使用
3. 上传AssetBundle包
因为在开发阶段,我们要重复对AssetBundle包进行修改,因此不会进行上传到服务器这一操作
开发阶段直接将AssetBundle包放在本地,再进行加载
4. 加载AssetBundle包
这里先讲解加载本地的AssetBundle包
加载本地的AssetBundle包和加载服务器上的AssetBundle包所用的API是不同的
现在,将我们的场景下的物品和Project中的prefab清空
为了更清楚地看到物体是从AssetBundle中加载出来的
创建一个空物体,命名LoadAssetBundle
添加脚本LoadAssetBundleFromLocal.cs
在Start()中进行加载操作
AssetBundle.LoadFromFile("AssetBundles/scene/wall.assetbundle");
// 需要加后缀
返回值为AssetBundle类型的对象 -- 见任务4&5:
AssetBundle在加载时,作为一个AssetBundle对象,对象中包含的内容就是AssetBundle压缩包中的内容
AssetBundle assetBundle = ...;
GameObject wallPrefab = assetBundle.LoadAsset("Wall");
// 对象类型为GameObject,名为"Wall",将加载到的资源赋值给GameObject对象
// 这里的名字"Wall"不能乱写,需要和打包前的名字相同 -- Case-insensitive
Instantiate(wallPrefab);
另一种方法是assetBundle.LoadAllAssets();
返回的是Object[],
可以通过foreach将所有Object[]中包含的prefabs都实例化出来
Siki_Unity_3-7_AssetBundle从入门到掌握