一、加载效果
在现实生活中我们传输某一个大文件的时候,一般都会对大文件进行压缩,然后使用压缩包进行传输,这回大大提高传输速度(因为文件体积变小了),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包压缩的项目大小
很明显看出来,压缩后减少了一半的体积