AssetBundle 的简单认识
首先 AssetBundle是什么: 是把一些资源文件或场景文件以某种紧密的方式保存在一起的文件, 包含模型文件、纹理材质、场景 等
AssetBundle中不能包含c#的脚本文件,一般获取它包含的文件,用作热更新
加载AssetBundle包的方法
一、加载的AB包的路径
1、加载AB包, 参数: 加载的AB包的路径
AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + " ");
2、从AB包中加载所需要的资源 (泛型指定:需要加载的资源类型 , 参数: 资源的名字)
GameObject bgPrefab = ab.LoadAsset<GameObject>("Bg");
3、实例化
二、使用www加载本地资源
1、注意 需要在路径前加: file://
WWW www = new WWW("file://" + Application.streamingAssetsPath + "/AssetBundle11111/prefab");
2、从www中获取加载到的AB包
AssetBundle ab = www.assetBundle;
3、加载AB包中的资源
4、实例化
注意事项: AB包不能重复的加载,在卸载前只能加载一次
可能问题:1、检查路径是否正确 。 2、检查你加载的资源的名字是否正确。
因为依赖的特性 :注意:要同时把AB包依赖的AB包也加载进来,否则可能会出现资源的丢失。
获取AB包的依赖
加载单一的特殊的AB包。
从特殊的AB包中去获取AssetBundleManifest类型的文件
通过AssetBundleManifest文件去获取指定名字的AB包的所有的依赖
string[] all_arr = singleManifest.GetAllAssetBundles(); // 获取所有AB 包的名字,返回一个字符串数组
string[] dep_arr = singleManifest.GetAllDependencies(" "); // 通过参数输入的名字,获取所有的依赖包
AB包的卸载
Ab.Unload() 参数是true或false
True:卸载AB包的同时把从AB包中加载的资源也同时卸载掉。
False:只卸载AB包,不卸载从AB包中加载的资源。
打包AssetBundle
首先需要引用UnityEditor命名空间
1. 先把资源在Editor下修改AssetBundle的名字
( 修改的位置 就在 打开要打包的物体的 Inspentor面板的最下方 手动设置名字)
2.利用下面代码BuildPipeline创建AssetBundle(选择一个文件路径,可以使用特性在[MenuItem("/")] 在上方创建一个选项)
BuildPipeline. BuildAssetBundles(outPutPath,BuildAssetBundleOptions . ForceRebuildAssetBundle,BuildTarget. StandaloneWindow64);
参数: 1、 AB包的输出路径, 2、 打包的相关选项 , 3、 AB包使用的平台
2 打包选项:BuildAssetBundleOptions
CollectDependencies:包含所有的依赖项(默认开启)
DeterministicAssetBundle:构建一个资源包(默认开启)
UncompressedAssetBundle:在构建AB包时不压缩数据
ChunkBasedCompression:在构建AB包时压缩数据(LZ4)
ForceRebuildAssetBundle:强制性的重新进行打包
AppendHashToAssetBundleName:把哈希码附加到名字的后面
打包注意事项:
1、检查路径是否在工程中存在或是否路径出错
2、检查打包平台是否有问题
3、AB包的名字里不能含有与打包输出文件夹的名字一致的(不区分大小写)
4、有使用了UnityEditor命名空间脚本未放在Editor文件夹下。
Unity 支持 AssetBundle的压缩模式
LZMA 、 LZ4 、 不压缩
AssetBundle构建后的组成
AB包文件 + 该AB包所对应的Manifest文件
Manifest文件 CRC: 循环冗余码 Assets:包含的资源的路径 Dependencies:依赖的AB包的路径
注意: Manifest文件记录了所有的AB包的名字和其AB包的依赖信息
方便的单例 获取AB包 脚本 :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
* 1. 防止AB包的重复加载
* 2. 对加载进来的AB包进行管理
* 3. 对外提供一个加载AB包的方法
* 4. 对外提供与一个卸载AB包的方法
* 5. 对外提供一个获取加载完成的AB包的方法
* 6. 对外提供一个从任意的AB包中加载资源的方法
*
* */
public class AssetBundleManager
{
#region 提供一个单例
//1. 先定义一个静态私有的AssetBundleManager的一个对象
private static AssetBundleManager instance;
//2. 私有构造函数, 防止外部对齐进行实例
private AssetBundleManager()
{
LoadSingleManifest();//把加载单一的Mnifest文件写构造力,只调用一次
}
//3. 创建一个静态方法或者是只读的静态属性对instance进行保护,以供外部调用一个非空的对象
public static AssetBundleManager _Instance
{
get {
if (instance == null)
{
instance = new AssetBundleManager();
}
return instance;
}
}
#endregion
#region 变量
/// <summary>
/// 存储了所有AB包的依赖的Manifest文件
/// </summary>
private AssetBundleManifest singleManifest = null;
/// <summary>
/// 提供一个字典去存储加载进来的AB包。键是AB包的名字,值是AB包
/// </summary>
private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();
/// <summary>
/// 所有AB包的存储路径
/// </summary>
private string abPath = Application.streamingAssetsPath + "/AssetBundle/";
/// <summary>
/// 单一的AB包的路径
/// </summary>
private string singleABPath = Application.streamingAssetsPath + "/AssetBundle/AssetBundle";
#endregion
#region 方法
/// <summary>
/// 加载单一的Manifest文件
/// 把加载单一的Mnifest文件写构造力,只调用一次
/// </summary>
private void LoadSingleManifest()
{
if (singleManifest == null)
{
//单一的Manifest文件需要从单一的AB包中去加载
AssetBundle single = AssetBundle.LoadFromFile(singleABPath);
//从ab包中加载manifest文件
singleManifest = single.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//单一的ab包只需要加载manifest文件,完成之后就卸载掉
single.Unload(false);
}
if (singleManifest == null)
{
Debug.LogError("加载Mnifest文件失败,请检查路径是否正确!");
}
}
/// <summary>
/// 加载指定的AB包的所有依赖项
/// </summary>
/// <param name="abName">ab包的名字</param>
private void LoadDependencies(string abName)
{
//加载所有依赖,先获取所有的依赖项
if (singleManifest != null)
{
//先获取所有的依赖
string[] deps = singleManifest.GetAllDependencies(abName);
//循环加载依赖项
for (int i = 0; i < deps.Length; i++)
{
//因为我们本身提供一个加载AB包的方法,那么可以直接调用该方法来加载有依赖项
LoadAssetBundle(deps[i]);
}
}
else
{
Debug.LogError("单一的Mnifest文件为null,请先加载");
}
}
/// <summary>
/// 加载AB包的方法
/// </summary>
/// <param name="abName">ab包的名字, 所有的AB包都是统一的路径</param>
public void LoadAssetBundle(string abName)
{
//加载AB包, 先判断该名字的AB包是否加载了
//因为我们是通过字典对加载进来的AB包做管理的,所有只需要判断字典中是否有该ab包名字的键来判断是否加载过该AB包
if (!abDic.ContainsKey(abName))
{
//判断字典中未加载该AB包,所有需要加载AB包
//加载AB包之前,先把依赖加载进来
LoadDependencies(abName);//自己的方法
AssetBundle ab = AssetBundle.LoadFromFile(abPath + abName);
//需要把加载进来的ab包,添加到字典中
abDic.Add(abName, ab);
}
}
/// <summary>
/// 卸载指定的AB包
/// </summary>
/// <param name="abName">ab包的名字</param>
/// <param name="isUnloadAllLoadedObjects">是否把从AB包中加载到的资源全部卸载</param>
public void UnloadAssetBundle(string abName, bool isUnloadAllLoadedObjects)
{
//卸载指定的AB包
//先判断是否加载过
if (abDic.ContainsKey(abName))//键存在证明加载过
{
//从字典访问AB包,并且卸载它
abDic[abName].Unload(isUnloadAllLoadedObjects);
//卸载完成之后,需要把该键值对从字典中移除
abDic.Remove(abName);
}
}
/// <summary>
/// 卸载所有的AB包
/// </summary>
public void UnloadAllAssetBundle()
{
//卸载所有AB包,就是遍历字典,把字典里所有的AB包卸载
//实际的AB包在字典中是值的存在,所有只需要遍历字典的值
foreach (AssetBundle ab in abDic.Values)
{
ab.Unload(true);//卸载AB包
}
//清空字典
abDic.Clear();
}
/// <summary>
/// 获取指定的AB包
/// </summary>
/// <param name="abName">ab包的名字</param>
/// <returns></returns>
public AssetBundle GetAssetBundle(string abName)
{
//获取AB 包之前需要判断是否加载过AB包
if (!abDic.ContainsKey(abName))
{
//未加载过AB包
LoadAssetBundle(abName);//自己本身的加载AB包的方法
}
return abDic[abName];//从字典中获取AB包
}
/// <summary>
/// 从指定的AB包中加载指定的资源资源
/// </summary>
/// <typeparam name="T">需要加载的资源的类型</typeparam>
/// <param name="abName">ab包的名字</param>
/// <param name="assetName">需要加载的资源的名字</param>
/// <returns></returns>
public T LoadAsset<T>(string abName, string assetName) where T : Object
{
//从指定的AB包中加载指定的资源,
//先获取指定的AB包
AssetBundle ab = GetAssetBundle(abName);//自己提供的获取AB包的方法
//从ab包中获取资源 T是调用的外部指定的类型
T asset = ab.LoadAsset<T>(assetName);
return asset;
}
/// <summary>
/// 从指定的AB包中加载指定的资源
/// </summary>
/// <param name="abName">ab包的名字</param>
/// <param name="assetName">资源的名字</param>
/// <returns></returns>
public Object LoadAsset(string abName, string assetName)
{
//先获取指定的AB包
AssetBundle ab = GetAssetBundle(abName);//自己提供的获取AB包的方法
//从ab包中获取资源
Object obj = ab.LoadAsset(assetName);
return obj;
}
#endregion
}
上一篇: Maven的简单认识
下一篇: Python GUI之Tkinter