AssetBundle是unity提供的一个特定平台的归档文件(archive file),可以在运行时加载。

AssetBundle包可以明确的表示互相之间的依赖关系,如a包中的材质引用了b包中的贴图。

为了在网络上高效的传输,AssetBundle可以更具实际需求选择内置的压缩算法。

AssetBundle对下载DLC(扩展包)很有用,可以减少安装包大小,优化终端平台的资源加载,减少运行时的内存压力。

总结:游戏资源更新,减少游戏安装包大小,优化资源加载。

 

AssetBundle策略

1.把经常更新的资源放在一个单独的包,不经常更新的放在一个包。

2.需要同时加载的资源放一个包。

3.共享的资源单独放一个包。

4.一个场景可以内用的资源可以放一个包。

AssetBundle可以把多个游戏的对象或者资源二进制文件封装。可以按类型分为五大部分:界面、模型、特效、声音、场景、脚本

 

如何使用AssetBundle

一、给对象设置AssetBundle属性

首先AssetBundle可以对所有的资源进行打包(预制体,音频,贴图,材质,甚至场景),当选中对象时,如果Inspector上有AssetBundle属性的设置,就说明可以打包。

unity 安卓AssetDatabase_依赖关系

第一个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)

unity 安卓AssetDatabase_加载_02

 

三、打包

直接选择AssetsBundle,选中Build AssetBundles点击。然后会在项目的根目录生成一个AssetBundles文件夹,打开后会看到

unity 安卓AssetDatabase_加载_03

从后缀上看,一种是我们设置的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中