Unity进阶学习之——AssetBundle的打包,以及本地和网络加载

时间:2024-03-28 07:21:08

本篇内容

  • 1.什么是AssetBundle?
  • 2.AssetBundle和Resources
  • 3.Assetbundle的打包操作
  • 4.AssetBundle的本地和网络加载

习惯性开场白
最近在学习的过程中,发现了两种动态的加载方式Resources,Load和Asset Bundle(后面简称AB)两种方式,通过查询资料,发现两种加载方式都差不多,但是AB更加适合大型项目,以及项目优化,最重要的一点,是可以结合Lua进行热更新,我们都知道,中国的游戏市场是更趋向于网游的,而热更新技术,可以让你通过下载资源包的方式,就可以为我们已经发布的程序提供修复Bug的可能,以及活动相关资源的推送,而不用重新下载客户端安装包,然后重新安装游戏,当然,在单机游戏里也可以通过这种方式,来推送Bug的修复。

什么是Asset Bundle?

我们先来看一下官方说明:
Unity进阶学习之——AssetBundle的打包,以及本地和网络加载
AssetBundles允许您通过UnityWebRequest类流式传输其他资源,并在运行时实例化这些资源。AssetBundle是通过buildPipeline.buildAssetBundle创建的。AB包在平台之间不兼容。为任何独立平台构建的包只能加载到该平台上,而不能加载其他平台。此外,为iOS构建的捆绑包与Android不兼容,反之亦然。比如渲染器的纹理。

简单说,AB就是我们用Unity通过LZMA压缩技术压缩的包,我们通过对这种压缩包的解析,来得到其中的游戏资源,让其加载到我们的内存流中,然后我们可以通过实例化的方式,让其加载到游戏场景中。AB在创建时可以设定依赖关系,比如两个物体AB,如果你在A上面挂了一个脚本,上面需要有B,那么我们就说,A就会依赖于B,那么当我们在加载A的时候,B也会被加载。

Assetbundle的打包操作:

把我们的物体拖进资源试图,然后设置AB选项:
Unity进阶学习之——AssetBundle的打包,以及本地和网络加载

然后我们新建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:资源包编译选项

  1. None:空
  2. UncompressedAssetBundle :不压缩AB包,会导致AB包很大,但是加载和打包过程会很快
  3. CollectDependencies :包含依赖关系
  4. CompleteAssets :强制打包全部资源
  5. DisableWriteTypeTree :不包含类型信息
  6. DeterministicAssetBundle :使其拥有一个唯一的hash id
  7. ForceRebuildAssetBundle :强制重新打包
  8. IgnoreTypeTreeChanges :忽略TypeTree变化
  9. AppendHashToAssetBundleName :附加hashid到AB名中
  10. ChunkBasedCompression :使用Lz4格式压缩
  11. StrictMode :严谨模式,出现任何差错都不会打包成功
  12. DisableLoadAssetByFileName :不适用文件名来加载

BuildTarget :目标设备

点击我们创建的菜单选项:
Unity进阶学习之——AssetBundle的打包,以及本地和网络加载
随后,我们看看是否常见成功:
Unity进阶学习之——AssetBundle的打包,以及本地和网络加载
我们会发现资源视图多了一个文件夹,我们创建的文件就在里面,test.cube就是我们的AB主文件,那么manifest是什么呢?
我们可以用记事本打开:
Unity进阶学习之——AssetBundle的打包,以及本地和网络加载

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 = "成功读取";
        }
        
    }
}

最终结果:
Unity进阶学习之——AssetBundle的打包,以及本地和网络加载

AssetBundle网络加载:

这里博主随便创建了一张图片,配置如下:
Unity进阶学习之——AssetBundle的打包,以及本地和网络加载
后缀名为jpg,这里博主只是做了一个实验,让后缀为常见格式,但是这里并不建议大家这么做!!要按照工程资源分类来设置后缀。

打包,把其放置到服务器端:
Unity进阶学习之——AssetBundle的打包,以及本地和网络加载
修改代码如下:

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 = "加载失败!";
            }
        }
        
    }
}

最终结果:
Unity进阶学习之——AssetBundle的打包,以及本地和网络加载
关于AB包就先讲到这里,后续会持续更新。