Unity之AB包的创建加载

一、加载效果

在现实生活中我们传输某一个大文件的时候,一般都会对大文件进行压缩,然后使用压缩包进行传输,这回大大提高传输速度(因为文件体积变小了),unity中的Ab包也可以理解为是对大模型的一种压缩,这样可以减小我们程序打包过后的体积过大问题。

 二、创建AB包

1.注意事项:

1.AB包的创建只能在unity的编辑器下创建,所以无法打包exe程序来创建

2.ab包创建脚本(CreateAssetBundles.cs)必须要放在Editor文件夹下,否则打包失败,(因为使用了using UnityEditor;程序集)

 1.AB包压缩类型

BuildAssetBundleOptions.None:构建assetBundle没有任何特殊的选项

BuildAssetBundleOptions.UncompressedAssetBundle:在创建资产包时不要压缩数据

BuildAssetBundleOptions.CollectDependencies:包括所有依赖项

BuildAssetBundleOptions.CompleteAssets:强制包含整个资产。

BuildAssetBundleOptions.DisableWriteTypeTree:不要在AssetBundle中包含类型信息。

BuildAssetBundleOptions.DeterministicAssetBundle:使用存储在资产包中的对象id的哈希值构建一个资产包

BuildAssetBundleOptions.ForceRebuildAssetBundle:强制重建资源包。

BuildAssetBundleOptions.IgnoreTypeTreeChanges:在执行增量构建检查时,忽略类型树的更改。 

BuildAssetBundleOptions.AppendHashToAssetBundleName:将散列附加到assetBundle名。

BuildAssetBundleOptions.ChunkBasedCompression:在创建AssetBundle时使用基于块的LZ4压缩。 

BuildAssetBundleOptions.StrictMode:如果在构建期间报告任何错误,则不允许构建成功。

BuildAssetBundleOptions.DryRunBuild:做一个演练构建

BuildAssetBundleOptions.DisableLoadAssetByFileName:通过文件名禁用资产包LoadAsset。

BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtension:通过扩展名禁用资产包LoadAsset 

BuildAssetBundleOptions.AssetBundleStripUnityVersion:移除存档文件和序列化文件头中的Unity版本号 在构建。

2.创建一个 Editor 文件夹,将CreateAssetBundles脚本放入

using UnityEngine;
using UnityEditor;
using System.IO;

/// <summary>
/// AB包创建
/// </summary>
public class CreateAssetBundles : MonoBehaviour
{
    [MenuItem("AssetBundles/Build AssetBundles")] //特性
    static void BuildAssetBundle()
    {
        string dir = Application.streamingAssetsPath + "/AssetBundles"; //相对路径
        if (!Directory.Exists(dir))   //判断路径是否存在
        {
            Directory.CreateDirectory(dir);
        }
        BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
    }
}

2.设置要创建成ab包的模型

这里注意 :

1.ab包的名称和后缀名可以随便写,尽量采用英文或数字(中文没试过),

2.ab包的后缀名不能写成unity场景资源的后缀,例如:将后缀名改为Unity,就会出现问题,因为Unity这个后缀名是代表了场景的意思,所以无法创建

3.打包ab包完成后,注意要把原模型删除(不删的话我们压缩模型就没有意义了,因为原来的模型还在,再加上ab包文件 体积变更大了)

4.模型、图片、视频音乐等要打ab包的资源不能放在StreamingAssets文件夹下 否则打包失败

 3.创建AB包

第一步创建脚本后,菜单栏会出现如下图的菜单选项,点击就可以自动创建了 

创建后的效果 

三、加载AB包脚本

 加载所有ab包的脚本

using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEngine.Events;
using System.IO;

/// <summary>
/// 加载所有ab模型
/// </summary>
public class LoadABController : MonoBehaviour
{
    bool isDown; //是否加载完毕
    Object[] objArray=new Object[] { }; //ab包类型

    //封装
    public Object[] ObjArray {
        get {
            if (isDown)return objArray;
            else return null;
            }
    }


    //单例
    static LoadABController intance;
    public static LoadABController GetIntance()
    {
        return intance;
    }
    private void Awake()
    {
        intance = this;
    }


    /// <summary>
    /// 加载所有ab包物体
    /// </summary>
    /// <param name="abFile">ab包路径 如:C:/abName.model</param>
    /// <param name="action">加载完毕要执行的方法</param>
    /// <returns></returns>
    public IEnumerator LoadAllModel(string abFile, UnityAction action = null)
    {
        if (File.Exists(abFile))
        {

            isDown = false;
            AssetBundle ab = AssetBundle.LoadFromFile(abFile);//注意名字要相同
                                                              //加载所有
            objArray = ab.LoadAllAssets();
            isDown = true;

            //不为空执行
            action?.Invoke();
        }
        else
            Debug.Log(abFile + " 文件不存在");


        yield return null;
    }
}

四、使用方法

我这里将一个模型和一个视频(AudioClip)打成了一个包,所以这里演示如何根据不同类型物体,执行不同操作

1.主界面脚本 

using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using UnityEngine.Video;

/// <summary>
/// 主界面管理器
/// </summary>
public class MainManager : MonoBehaviour
{
    //加载按钮和视频播放器
    [SerializeField] Button loadBtn;
    [SerializeField] VideoPlayer videoPlayer;

    void Start()
    {
        //按钮监听
        loadBtn.onClick.AddListener(Load);
    }

    //监听方法
    private void Load()
    {
        //调用协会
        IEnumerator ie = LoadABController.GetIntance().LoadAllModel(Application.streamingAssetsPath+ $"/AssetBundles/1.model", LoadAllObject);
        //开启协程
        StartCoroutine(ie);
    }

    //加载所有物体(物体加载完毕后,会调用这个方法,这里可以理解为将这个方法作为参数传递)
    void LoadAllObject()
    {
        Object[] objArray = LoadABController.GetIntance().ObjArray;
        for (int i = 0; i < objArray.Length; i++)
        {
            Object obj= objArray[i];
            //通过类型判断加载
            switch (obj.GetType().ToString())
            {
                case "UnityEngine.GameObject":
                    Instantiate(obj); //模型创建
                    break;
                case "UnityEngine.Video.VideoClip":
                    //视频加载
                    VideoClip clip = obj as VideoClip;
                    videoPlayer.clip = clip;
                    videoPlayer.Play();
                    break;
                default:
                    break;
            }
        }
    }
}

 2.场景布局

1.创建RenderTexture用于接收视频播放的画面

修改RenderTexture的Size属性为视频的像素比例

 2.在场景创建一个VideoPlayer,视频播放器

 设置属性

3.场景创建一个RawImage,用于在场景中将播放的画面展示

 设置属性

 

4.创建加载按钮

 将LoadABController和MainManager脚本拖给按钮

五、使用AB包前后加载 

AB1是使用了AB包压缩后打包出来的项目大小

NoAB是没有使用ab包压缩的项目大小

 很明显看出来,压缩后减少了一半的体积

猜你喜欢

转载自blog.csdn.net/qq_42345116/article/details/125653571