1) AssetBundle是一种经过Unity引擎处理了的资源包
2) 已经序列化的资源
3) 具有针对平台的特性
4) 外部不相干,使用同样加密方式的包,可以互相调用
1) 一个场景打成一个AB包,使用的时候,是将场景加载到游戏中
2) 松散资源包,一堆可复用的资源打成一个包,使用的时候,是按需载入包
1) 最小化APP安装包
1) 增量更新
3) 更好的控制实时的内存消耗
4) 选择性的提供不同的内容
5) 减少打包和迭代时间
打包方法: BuildPipeline.BuildAssetBundles()
我们看到BuildAssetBundles() unity提供了两种重载方法,先来说第一种
public static AssetBundleManifest BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);
这里有三个参数,第一个是输出路径,第二个打包的配置选项(一般选压缩格式),第三个是打包的目标平台
注:assetbundle的压缩格式有3中:
1)LZMA --> BuildAssetBundleOptions.None 包最小,加载最慢
2)LZ4 --> BuildAssetBundleOptions.ChunkBasedCompression 包比不压缩小,加载比不压缩略慢
1)不压缩 --> BuildAssetBundleOptions.UncompressedAssetBundle 包最大,加载最快
这种方法主要是根据我们在Inspector面板中对物体设置的assetbundle名进行打包,比如
扩展编辑器的打包代码,Directory.CreateDirectory(savePath); 把文件保存在asset的同级目录。
using UnityEditor;
using System.IO;
public class BuildAssetBundle : Editor
{
private static string savePath = "AssetBundles";
[MenuItem("Tools/BuildAssetBundle")]
public static void BuildAssetBunlde()
{
if (Directory.Exists(savePath) == false)
{
Directory.CreateDirectory(savePath);
}
BuildPipeline.BuildAssetBundles(savePath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
AssetDatabase.Refresh();
}
}
还有根据路径打包
public static AssetBundleManifest BuildAssetBundles(string outputPath, AssetBundleBuild[] builds, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);
这个方法多了一个参数AssetBundleBuild[] builds
我们可以看到是Unity封装的一个打包结构体
必须设置assetBundleName和assetNames,其它可设可不设
assetBundleName即为打出的assetbundle名
assetNames为你要打包的资源路径,这里使用相对路径,它是一个数组,说明可以把多个对象打成一个assetbundle。
第二种打包方法代码
if (Directory.Exists(savePath) == false)
{
Directory.CreateDirectory(savePath);
}
List builds = new List();
AssetBundleBuild build = new AssetBundleBuild();
build.assetBundleName = "Micro_Wizard.unity3d";
build.assetNames = new string[] { "Assets/Toon/Micro_Wizard.prefab" };
builds.Add(build);
BuildPipeline.BuildAssetBundles(savePath, builds.ToArray(), BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
AssetDatabase.Refresh();
public void LoadFromFile()
{
AssetBundle assetBundle = AssetBundle.LoadFromFile(Application.dataPath + "/../AssetBundles/Micro_Wizard.unity3d");
Instantiate(assetBundle.LoadAsset("Micro_Wizard.prefab"));
}
public void LoadFromMemory()
{
AssetBundle assetBundle = AssetBundle.LoadFromMemory(File.ReadAllBytes(Application.dataPath + "/../AssetBundles/Micro_Wizard.unity3d"));
Instantiate(assetBundle.LoadAsset("Micro_Wizard.prefab"));
}
public void LoadFromStream()
{
var fileStream = new FileStream(Application.dataPath + "/../AssetBundles/Micro_Wizard.unity3d", FileMode.Open, FileAccess.Read);
AssetBundle assetBundle = AssetBundle.LoadFromStream(fileStream);
Instantiate(assetBundle.LoadAsset("Micro_Wizard.prefab"));
}
public void WebRequest()
{
StartCoroutine(WaitWebRequest());
}
IEnumerator WaitWebRequest()
{
UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(Application.dataPath + "/../AssetBundles/Micro_Wizard.unity3d");
yield return request.SendWebRequest();
//AssetBundle assetBundle = DownloadHandlerAssetBundle.GetContent(request);
AssetBundle assetBundle = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
Instantiate(assetBundle.LoadAsset("Micro_Wizard.prefab"));
}
注:从2018版本后,这个方法已过时,使用UnityWebRequest方法代替
public void WWWLoad()
{
StartCoroutine(WaitWWWLoad());
}
IEnumerator WaitWWWLoad()
{
while (Caching.ready == false)
yield return null;
WWW www = WWW.LoadFromCacheOrDownload(Application.dataPath + "/../AssetBundles/Micro_Wizard.unity3d", 1);
yield return www;
if (!string.IsNullOrEmpty(www.error))
{
Debug.Log(www.error);
yield break;
}
AssetBundle assetBundle = www.assetBundle;
Instantiate(assetBundle.LoadAsset("Micro_Wizard.prefab"));
}
常用于资源引用为0时调用
参数为true时,所有在当前场景中使用的引用物体都会被销毁,所有有引用的话,也会丢失。
参数为false时,assetbundle会被释放,而从中实例化出来的物体,会切断与原assetbundle的引用关系。(所以在使用这种情况下,当再次加载时即会产生资源冗余)
在实际使用中无论参数时true还是false似乎都不能很好的满足我们的需求,所以这里我们可以设计一个引用计数法来处理。
1.记录引用次数:
1)有某个包依赖,次数+1
2)有某个内容被实例化创建出来,次数+1
3)依赖包卸载,次数-1
4)实例化出来的物体被回收,次数-1
2.使用计次:当引用次数为0时,且一段时间没有再被引用时就可以使用AssetBundle.Unload(false)进行安全卸载。
作用如名所诉卸载没有被调用的资源,这时一个异步方法,但也挺消耗性能。
常用于关卡切换,场景切换时调用。