一:设置AssetBundle属性
在编辑器预览窗口的右下角有一个AssetBundle的属性设置
第一栏是AB包的属性名字,第二栏是AB包的属性变体(后缀)
——AB包的变体可以不设置(后缀不能为unity,会报空指针)
——AB包的属性和后缀是不区分大小写的
——AB包的名称是可以指定目录路径的(例如:prefab/cube或者prefab\cube)
设置属性需要注意的地方:如果想要将几个资源打包到同一个包中,则资源的路径要相同,变体也要相同。如果名字相同,变体不相同仍会打到不同的包里
二:构建AB包
两种方式:
——通过资源的ab包属性打包(手动设置或者代码设置),之后通过打包函数进行打包
——传入一个AssetBundleBuild对象的数组(AssetBundleBuild中的assetNames必须是以Assets/开头的路径),之后通过打包函数进行打包
using UnityEngine;
using UnityEditor;
using System.IO;
public class ABEditor
{
[MenuItem("AB/Build AB1")]
private static void BuildAB1()
{
string outputPath = Application.dataPath + "/AssetBundles";
if (!Directory.Exists(outputPath))
{
Directory.CreateDirectory(outputPath);
}
BuildPipeline.BuildAssetBundles(outputPath, BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);
AssetDatabase.Refresh();
}
[MenuItem("AB/Build AB2")]
private static void BuildAB2()
{
string outputPath = Application.dataPath + "/AssetBundles";
if (!Directory.Exists(outputPath))
{
Directory.CreateDirectory(outputPath);
}
List<AssetBundleBuild> abBuilds = new List<AssetBundleBuild>();
foreach (var v in abAssetDict.Values)
{
AssetBundleBuild bundle = new AssetBundleBuild
{
assetBundleName = v.abName,
assetNames = new string[] { v.assetPath },
};
abBuilds.Add(bundle);
}
BuildPipeline.BuildAssetBundles(outputPath, abBuilds.ToArray(), BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);
}
}
BuildAssetBundleOptions:打包选项
1.BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩的包更小,但是LZMA只支持顺序读取,使用时需要将整个包进行解压缩,加载时间变得更长,解压后的包会通过LZ4算法重新压缩存储在磁盘上
2.BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快,但是下载速度会慢
3.BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4算法压缩,压缩后的包比LZMA算法压缩的包大,但是加载速度快
打包时注意,例如A和B都使用了同一个材质,将材质单独打成一个AB包,则打包后,A和B的包中就不会包含材质资源而是存了一份材质包的引用路径,减少了AB包的大小
同样的,一个文件夹中有AB两个资源,给A资源设置了AB包属性,B资源没有设置AB包属性,同时给文件夹也设置了AB包属性,则A资源会单独打一个包,B资源会打进文件夹的AB包中,A资源就不会打进文件夹的AB包中
三:上传AB包——使用NetBox2模拟服务器
使用NetBox2可以快速搭建一个本地服务器,它的根目录就是当前NetBox的目录
——运行程序
双击运行之后发现出现了403 Forbidden,这是因为我们没有默认的首页(可以用html写一句话当作主页)
"http://localhost:64283/"就是我们的服务器网址,后面再加上打包的路径就是AB包的服务器地址(http://localhost:64283/AssetBundles/cube)
——上传文件
将打包好的文件夹整个拖入NexBox的根目录下(与NetBox可执行文件同级)
四:加载AB包
——从本地加载资源
using UnityEngine;
using System.Collections;
public class Test : MonoBehaviour
{
private string path = "/Users/liu/Desktop/testproject/AssetBundles/cube";
private void Awake()
{
LoadAB_Sync();
//StartCoroutine(LoadAB_Async());
}
private void LoadAB_Sync()
{
AssetBundle ab = AssetBundle.LoadFromFile(path);
Instantiate(ab.LoadAsset("cube"));
}
private IEnumerator LoadAB_Async()
{
AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path);
yield return request;
AssetBundle ab = request.assetBundle;
Instantiate(ab.LoadAsset("cube"));
}
}
——从内存加载资源
using UnityEngine;
using System.Collections;
using System.IO;
public class Test : MonoBehaviour
{
private string path = "/Users/liu/Desktop/testproject/AssetBundles/cube";
private void Awake()
{
LoadAB_Sync();
//StartCoroutine(LoadAB_Async());
}
private void LoadAB_Sync()
{
AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes(path));
Instantiate(ab.LoadAsset("cube"));
}
private IEnumerator LoadAB_Async()
{
AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));
yield return request;
AssetBundle ab = request.assetBundle;
Instantiate(ab.LoadAsset("cube"));
}
}
——使用UnityWebRequest加载资源
using UnityEngine;
using System.Collections;
using System.IO;
using UnityEngine.Networking;
public class Test : MonoBehaviour
{
//本地路径需要加file:///
private string path = @"file:////Users\liu\Desktop\testproject\AssetBundles\cube";
private void Awake()
{
StartCoroutine(LoadAB_Async());
}
private IEnumerator LoadAB_Async()
{
UnityWebRequest request = new UnityWebRequest(path);
yield return request.SendWebRequest();
AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);
Instantiate(ab.LoadAsset("cube"));
}
}
五:卸载
——assetbundle.Unload(bool unloadAllLoadedObjects)
如果为true,则会卸载当前包所有资源,包括正在被其他包依赖的资源
如果为false,则会卸载当前包未被依赖的资源,被其他包依赖的资源不会被卸载
——AssetBundle.UnloadAllAssetBundles(bool unloadAllObjects)
如果为true,则会卸载所有AB资源,包括正在被其他包依赖的资源
如果为false,则会卸载未被依赖的AB资源,被其他包依赖的资源不会被卸载
六:注意事项
——Unity加载的AB包,即使游戏中没有对该assetbundle的引用,不主动调用Unload或UnloadAllAssetBundles的话,该AB包是不会被释放掉的,指向该assetbundle的弱引用也不会变为空,可以隔一段时间调用一次Resources.UnloadUnusedAssets
——如果依赖的资源在使用下被卸载了,再次加载出依赖的资源并不会建立起引用,因为卸载之后它们的引用就断开了,就算再次加载出依赖的资源也不会与之前的预制体所连接,除非同时再次加载出预制体和资源