AssetBundle是unity提供的一个特定平台的归档文件(archive file),可以在运行时加载。
AssetBundle包可以明确的表示互相之间的依赖关系,如a包中的材质引用了b包中的贴图。
为了在网络上高效的传输,AssetBundle可以更具实际需求选择内置的压缩算法。
AssetBundle对下载DLC(扩展包)很有用,可以减少安装包大小,优化终端平台的资源加载,减少运行时的内存压力。
总结:游戏资源更新,减少游戏安装包大小,优化资源加载。
AssetBundle策略
1.把经常更新的资源放在一个单独的包,不经常更新的放在一个包。
2.需要同时加载的资源放一个包。
3.共享的资源单独放一个包。
4.一个场景可以内用的资源可以放一个包。
AssetBundle可以把多个游戏的对象或者资源二进制文件封装。可以按类型分为五大部分:界面、模型、特效、声音、场景、脚本
如何使用AssetBundle
一、给对象设置AssetBundle属性
首先AssetBundle可以对所有的资源进行打包(预制体,音频,贴图,材质,甚至场景),当选中对象时,如果Inspector上有AssetBundle属性的设置,就说明可以打包。
第一个None是包名,也可以是目录/包名(可以创建目录),第二个None是后缀。这两个属性都是可以自定义的。(注意命名都是强制小写)
二、创建打包工具
新建一个Editor(在Assets目录下)文件夹CreateAssetbundles (这个是必须的),然后在目录下创建C#脚本:
using UnityEditor;
using System.IO;
public class CreateAssetbundles : Editor
{
[MenuItem("AssetsBundle/Build AssetBundles")]
static void BuildAllAssetBundles()//进行打包
{
string dir = "AssetBundles";
//判断该目录是否存在
if (Directory.Exists(dir) == false)
{
Directory.CreateDirectory(dir);//在工程下创建AssetBundles目录
}
//参数一为打包到哪个路径,参数二压缩选项 参数三 平台的目标
BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
}
}
Directory.Exists(路径):类方法 判断给定的路径是否是已经存在的目录 是返回true 反之false
Directory.CreateDirectory(路径):类方法 在指定路径下创建一个目录
BuildPipeline.BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform):类方法 在编辑器模式下打包所有指定的AssetBundle对象
outputPath:输出目录(只能输出到现有目录中)
assetBundleOptions:包的构建方式(使用那种压缩算法)
targetPlatform:目标平台(AssetBundle包不是跨平台的,只能在指定平台使用)
返回值: AssetBundleManifest类型文件 包含了所有AssetBundle包的列表和依赖关系
这里再设置一个预制体AssetBundle属性(包名是cube,后缀是u3d)
三、打包
直接选择AssetsBundle,选中Build AssetBundles点击。然后会在项目的根目录生成一个AssetBundles文件夹,打开后会看到
从后缀上看,一种是我们设置的u3d的后缀结尾的文件,一种是Manifest后缀结尾的文件。
.u3d 结尾的文件是Assetbundle包本体
.Manifest 结尾的文件是给人看的,让我们查看包的属性,这个文件可以直接用记事本打开,可以查询效验码、包里包含的资源对象,包的依赖关系,
AssetBundle.Manifest 中包含的是所有包的信息 给人看的
AssetBundle 这个种也包含的是所有包的信息 只不过这个文件是计算机看的 就是打包方法BuildPipeline.BuildAssetBundles的返回值
四、使用AssetBundle包
可以从本地加载也可以从服务器加载的一种方法
UnityWebRequest 异步方法
先创建一个脚本,然后把脚本挂在一个空物体上,然后编辑脚本
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class LoadAssetBundleFile : MonoBehaviour
{
private void Start()
{
StartCoroutine("UWR");
}
//异步加载方法需要使用协程
IEnumerator UWR()
{
//路径 可以本地也可以服务器 本地需要加前缀file:///
string path = @"file///D:\UnityProject\200727\AssetBundles\cube.u3d";
//创建下载资源请求
UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(path);
//开始异步下载资源并等待完成
yield return request.SendWebRequest();
//取得下载好的资源中的AB包(第一种) DownloadHandlerAssetBundled.GetContent方法
AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);
//取得下载好的资源种的AB包(第二种) 格式转换
//AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
//使用AB包 LoadAsset<对象类型>(对象名)
GameObject cube = ab.LoadAsset<GameObject>("Cube");
Instantiate(cube);
}
}
由于材质是单独打包的,所以需要添加依赖关系
//取得AB包的依赖关系
//首先拿到AssetBundles文件 (这是最简单的加载AB包方式,返回值就是加载的ab包 属于同步加载)
AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");
//拿到AssetBundles文件中的manifest文件
AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//取得对应AB包的依赖关系
//GetAllDependencies(AB包名) 返回值是这个AB包所依赖的所有AB包包名
string[] strs = manifest.GetAllDependencies("cube.u3d");
foreach (string name in strs)
{
//加载cubeAB包所依赖的所有资源,这里就只有一个材质资源
AssetBundle.LoadFromFile("AssetBundles/" + name);
}
封装场景AssetBundle中技巧:
场景中公用的部分和私有部分统统放入Unity,然后烘培整个场景。当场景烘培完后把公用的模型部分再拿出来,场景只保留私有的模型,还可以做一个工具将公用模型再场景中的坐标保存在xml中(每个场景文件会对应一个公用模型的xml信息),最后再将公用的模型分别封装在别的AssetBundle中