本篇内容
- 1.什么是AssetBundle?
- 2.AssetBundle和Resources
- 3.Assetbundle的打包操作
- 4.AssetBundle的本地和网络加载
习惯性开场白
最近在学习的过程中,发现了两种动态的加载方式Resources,Load和Asset Bundle(后面简称AB)两种方式,通过查询资料,发现两种加载方式都差不多,但是AB更加适合大型项目,以及项目优化,最重要的一点,是可以结合Lua进行热更新,我们都知道,中国的游戏市场是更趋向于网游的,而热更新技术,可以让你通过下载资源包的方式,就可以为我们已经发布的程序提供修复Bug的可能,以及活动相关资源的推送,而不用重新下载客户端安装包,然后重新安装游戏,当然,在单机游戏里也可以通过这种方式,来推送Bug的修复。
什么是Asset Bundle?
我们先来看一下官方说明:
AssetBundles允许您通过UnityWebRequest类流式传输其他资源,并在运行时实例化这些资源。AssetBundle是通过buildPipeline.buildAssetBundle创建的。AB包在平台之间不兼容。为任何独立平台构建的包只能加载到该平台上,而不能加载其他平台。此外,为iOS构建的捆绑包与Android不兼容,反之亦然。比如渲染器的纹理。
简单说,AB就是我们用Unity通过LZMA压缩技术压缩的包,我们通过对这种压缩包的解析,来得到其中的游戏资源,让其加载到我们的内存流中,然后我们可以通过实例化的方式,让其加载到游戏场景中。AB在创建时可以设定依赖关系,比如两个物体AB,如果你在A上面挂了一个脚本,上面需要有B,那么我们就说,A就会依赖于B,那么当我们在加载A的时候,B也会被加载。
Assetbundle的打包操作:
把我们的物体拖进资源试图,然后设置AB选项:
然后我们新建C#脚本:
using UnityEngine;
using UnityEditor;
using System.IO;
public class CreateSb
{
[MenuItem("Assets/CreateAB")] //在Asset菜单栏下创建“CreateAB”功能项
static void Createab()
{
string dir = Application.streamingAssetsPath; //定义AB包路径:工程目录下的StreamingAssets
if (Directory.Exists(dir) == false)//如果不存在文件夹,那么新建一个
{
Directory.CreateDirectory(dir);
}
BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.Android); //开始打包
AssetDatabase.Refresh(); //刷新资源列表
}
}
对BuildPipeline.BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform) 参数的解析:
outputPath:AB包的目标路径
BuildAssetBundleOptions:资源包编译选项
- None:空
- UncompressedAssetBundle :不压缩AB包,会导致AB包很大,但是加载和打包过程会很快
- CollectDependencies :包含依赖关系
- CompleteAssets :强制打包全部资源
- DisableWriteTypeTree :不包含类型信息
- DeterministicAssetBundle :使其拥有一个唯一的hash id
- ForceRebuildAssetBundle :强制重新打包
- IgnoreTypeTreeChanges :忽略TypeTree变化
- AppendHashToAssetBundleName :附加hashid到AB名中
- ChunkBasedCompression :使用Lz4格式压缩
- StrictMode :严谨模式,出现任何差错都不会打包成功
- DisableLoadAssetByFileName :不适用文件名来加载
BuildTarget :目标设备
点击我们创建的菜单选项:
随后,我们看看是否常见成功:
我们会发现资源视图多了一个文件夹,我们创建的文件就在里面,test.cube就是我们的AB主文件,那么manifest是什么呢?
我们可以用记事本打开:
AssetBundle本地加载:
实现了AB包创建,我们就可以来加载他了:
添加如下代码,把其挂载到空物体上:
using UnityEngine;
using UnityEngine.UI;
public class Test : MonoBehaviour
{
public Text t; //用来显示是否加载成功
void Start()
{
AssetBundle obj = AssetBundle.LoadFromFile(Application.streamingAssetsPath+"/test.cube"); //加载我们的AB包
if (obj== null)
{
t.text = "加载失败!";
return;
}
else
{
GameObject a = obj.LoadAsset<GameObject >("cube"); //加载我们资源包里名为cube的文件
Instantiate(a); //实例化读取到的对象
obj.Unload(false); //释放已经读取的对象,如果为True则释放全部资源
t.text = "成功读取";
}
}
}
最终结果:
AssetBundle网络加载:
这里博主随便创建了一张图片,配置如下:
后缀名为jpg,这里博主只是做了一个实验,让后缀为常见格式,但是这里并不建议大家这么做!!要按照工程资源分类来设置后缀。
打包,把其放置到服务器端:
修改代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Test : MonoBehaviour
{
public Text t;
public Image TT;
IEnumerator Start()
{
//AssetBundle obj = AssetBundle.LoadFromFile(Application.streamingAssetsPath+"/test.bg");
WWW obj = new WWW("http://127.0.0.1/GameBG/test.jpg");
yield return obj;
if (obj== null)
{
t.text = "加载失败!";
}
else
{
AssetBundle bg = obj.assetBundle;
Sprite a = bg.LoadAsset<Sprite>("201703081610271071653-1");
TT.sprite = a;
bg.Unload(false);
//obj.Unload(false);
t.text = "成功读取";
if (a == null)
{
t.text = "加载失败!";
}
}
}
}
最终结果:
关于AB包就先讲到这里,后续会持续更新。