赞
踩
首先 AssetBundle是什么: 是把一些资源文件或场景文件以某种紧密的方式保存在一起的文件, 包含模型文件、纹理材质、场景 等
AssetBundle中不能包含c#的脚本文件,一般获取它包含的文件,用作热更新
1、加载AB包, 参数: 加载的AB包的路径
AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + " ");
2、从AB包中加载所需要的资源 (泛型指定:需要加载的资源类型 , 参数: 资源的名字)
GameObject bgPrefab = ab.LoadAsset<GameObject>("Bg");
3、实例化
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包中加载的资源。
首先需要引用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
-
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。