文章目录
- AB包
- AB包和Resources区别
- AB包创建
- 导出
- 加载资源
- 替换
- 压缩
- 依赖关系
- 导出选项
- 多平台
- 依赖加载
- 资源异步加载
- 内存分析
- 内存回收文章
AB包
- AssetBundle加载游戏中后,加载绿色的区域,在被引用
- AB包应该是独立与游戏的文件
AB包和Resources区别
- AB包不能包含C#文件,AssetBunble可以配合Lua实现资源和游戏更新
AB包创建
- 多选素材,或者图集
- 右下角,new一个取名字,把这些素材归纳到一个AB包中
- 需要打开图集
导出
- 找一个AB目录再Asset外面,然后导出
- 做AB包时资源不要放在Resouces中
/****************************************************
文件:ExportAB.cs
作者:别离或雪
邮箱: 2946952974@qq.com
日期:#CreateTime#
功能:导出AB
*****************************************************/
using UnityEngine;
using UnityEditor;
using System.IO;
public class ExportAB : MonoBehaviour
{
[MenuItem("AB包/导出")]
public static void Export(BuildTarget platform) {
//项目Assets路径
string path = Application.dataPath;
//C:/Users/sonw/Desktop/unity/Astar RandomTileMap/ab
path = path.Substring(0,path.Length-6)+"ab";//不要Assets
if (!Directory.Exists(path)){
Directory.CreateDirectory(path);
}
Debug.Log(path);
//导出核心代码
//参数一:ab包文件存储路径
//参数二:导出选项
//参数三:平台,不同平台AB包不一样的
BuildPipeline.BuildAssetBundles(
path,
BuildAssetBundleOptions.None,
BuildTarget.StandaloneWindows
);
}
}
加载资源
/****************************************************
文件:SimpLoad.cs
作者:别离或雪
邮箱: 2946952974@qq.com
日期:#CreateTime#
功能:加载AB包
*****************************************************/
using UnityEngine;
public class SimpLoad : MonoBehaviour
{
private void Start() {
//第一步:加载AB文件
AssetBundle ab= AssetBundle.LoadFromFile(Config.ABpath + "/img");
//第二步:加载资源
Sprite sp=ab.LoadAsset<Sprite>("BG 1");
transform.GetComponent<SpriteRenderer>().sprite = sp;
ab.Unload(false);//释放AB包
}
}
public class Config {
//AB包存储路径
public static string ABpath = Application.dataPath.Substring(0, Application.dataPath.Length - 6) + "ab";
}
替换
- 原名替换资源后,再打包
- 两版资源不放在一个包中
- 重新加载新的路径
- 导入到AB中的资源,包内部不存在目录
压缩
- 不压缩
- LZMA压缩
- LZ4压缩
依赖关系
- 第一个包中依赖另一个包中的东西
- 例:一包是图片,二包是预制体引用一包图片,就是依赖
- 右键编辑可以看到依赖关系
- 如果要处理依赖关系,必须加载主AB包,因为依赖关系的存储,都在主AB包配置文件中
导出选项
多平台
[MenuItem("AB包导出/iOS")]
public static void ForiOS() {
Export(BuildTarget.iOS);
}
[MenuItem("AB包导出/Andorid")]
public static void ForAndorid() {
Export(BuildTarget.Android);
}
[MenuItem("AB包导出/Mac")]
public static void ForMac() {
Export(BuildTarget.StandaloneOSX);
}
依赖加载
- 加载主AB包
- 获取主AB包中的配置文件
- 分析预制体所在AB包,依赖哪些AB包
- 加载的AB包
- 加载预制体所在的AB包
- 加载预制体
- 同一个ab包不能加载两次,需要卸载再加载
public class Config {
//AB包存储路径
public static string ABpath = Application.dataPath.Substring(0, Application.dataPath.Length - 6) + "ab";
}
public class Load:MonoBehaviour {
private void Start() {
//- 加载主AB包
AssetBundle main = AssetBundle.LoadFromFile(Config.ABpath + "ab");
//- 获取主AB包中的配置文件
AssetBundleManifest manifest = main.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//- 分析预制体所在AB包,依赖哪些AB包
//deps存储所有依赖ab包的名字
string[] deps = manifest.GetAllDependencies("test2");
//- 加载的AB包
for (int i = 0; i < deps.Length; i++) {
AssetBundle.LoadFromFile(Config.ABpath + "/" + deps[i]);
}
//- 加载预制体所在的AB包
AssetBundle test2 = AssetBundle.LoadFromFile(Config.ABpath + "/test2");
//- 加载预制体
Object prefabe = test2.LoadAsset("Image");
GameObject img = Instantiate(prefabe) as GameObject;
}
}
资源异步加载
//异步加载
public class AsyncLoad:MonoBehaviour {
private void Start() {
//同步
GameObject.Find("Img").GetComponent<Image>().sprite = Resources.Load<Sprite>("");
//异步,通过协同,开启一个异步Resource加载资源
StartCoroutine(LoadImage());
//ab包同步
AssetBundle ab = AssetBundle.LoadFromFile(Config.ABpath + "/big");
GameObject.Find("Img").GetComponent<Image>().sprite = ab.LoadAsset<Sprite>("参考图");
//ab包异步
StartCoroutine(LoadAB((AssetBundleCreateRequest abcr) => {
GameObject.Find("Img").GetComponent<Image>().sprite = abcr.assetBundle.LoadAsset<Sprite>("参考图");
}));
}
IEnumerator LoadImage() {
//开启一个异步加载
ResourceRequest rr = Resources.LoadAsync<Sprite>("参考图");
//协同会在加载资源成功后,继续执行(第层呢个封装了线程加载资源)
yield return rr;
//将加载成功的资源,显示出来
GameObject.Find("Img").GetComponent<Image>().sprite = rr.asset as Sprite;
}
IEnumerator LoadAB(Action<AssetBundleCreateRequest> cb) {
AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(Config.ABpath + "/big");
yield return abcr;
cb(abcr);
}
}
内存分析
- profiler内存工具
- 加载到场景中时会占用内存,文件不算(没有加载到内存)
- 文件加载不会占用内存,加载资源才会占用内存
- 只有释放资源才会减少内存占用、
- 需要回收
- Destory并不回收内存,Unity是懒回收
public void RecyCle() {
//将所有没有在使用的资源回收,回收游离资源,尽量在场景切换时调用
Resources.UnloadUnusedAssets();
}