AB包定义作用
1.压缩大小
2.热更新使用
使用流程
对要打包的资源进行设置
C#脚本不能打成AB包,因为C#在Unity中会编译成中间文件。
参数相关
Build的路径(随意只要是在硬盘上都可以的)
BuildAssetBundleOptions
BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩的包更小,但是加载时间更长。使用
之前需要整体解压。一旦被解压,这个包会使用LZ4重新压缩。使用资源的时候不需要整体解压。
在下载的时候可以使用LZMA算法,一旦它被下载了之后,它会使用LZ4算法保存到本地上。
BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快
BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩,压缩率没有LZMA高,但是
我们可以加载指定资源而不用解压全部注意使用LZ4压缩,可以获得可以跟不压缩相媲美的加载速度,而且比不压缩文件要小。
BuildTarget选择build出来的AB包要使用的平台
创建AB包
创建AB包,使用BuildPipeline类中的方法
private static readonly string AbPath = Application.streamingAssetsPath;
[MenuItem("Tools/CreateAB")]
static void CreateAbPack()
{
BuildPipeline.BuildAssetBundles(AbPath, BuildAssetBundleOptions.UncompressedAssetBundle, BuildTarget.Android);
AssetDatabase.Refresh();
}
清除文件中的AB包
[MenuItem("Tools/ClearABFile")]
static void ClearAbPack()
{
DirectoryInfo directoryInfo = new DirectoryInfo(AbPath);
FileSystemInfo[] fileSystemInfo = directoryInfo.GetFileSystemInfos();
foreach (FileSystemInfo item in fileSystemInfo)
{
if(item is DirectoryInfo)
{
DirectoryInfo d = new DirectoryInfo(item.FullName);
d.Delete(true);
}
else
{
item.Delete();
}
}
AssetDatabase.Refresh();
}
读取AB包
1.直接记载一个单独的物体(无依赖)
通过AssetBundle的LoadFromFile方法获取AB包,在通过LoadAsset的泛型方法获得GameObject
private string path;
void Start () {
path = Application.streamingAssetsPath;
AssetBundle ab = AssetBundle.LoadFromFile(path + "/prefab");
//print(ab);
GameObject go = ab.LoadAsset<GameObject>("Sphere");
Instantiate(go);
}
2.通过依赖加载,从本地进行加载
path = Application.streamingAssetsPath;
//从文件中加载StreamingAssets文件
AssetBundle assetBundle = AssetBundle.LoadFromFile(path + "/StreamingAssets");
//从StreamingAssets文件中获得AssetBundleManifest对象
AssetBundleManifest assetBundleManifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//从AssetBundleManifest中加载一个AssetBundle对象的全部依赖
string[] dps = assetBundleManifest.GetAllDependencies("prefab");
//遍历依赖,加载所有的依赖
for (int i = 0; i < dps.Length; i++)
{
AssetBundle ab1 = AssetBundle.LoadFromFile(path + "/" + dps[i]);
}
AssetBundle ab = AssetBundle.LoadFromFile(path + "/prefab");
GameObject go = ab.LoadAsset<GameObject>("Sphere");
Instantiate(go);
3.异步加载从文件中
if (GUILayout.Button("异步加载"))
{
StartCoroutine(LoadAB(AbLoadBP));
}
IEnumerator LoadAB(Action action)
{
path = Application.streamingAssetsPath;
AssetBundleCreateRequest assetBundle = AssetBundle.LoadFromFileAsync(path + "/prefab");
yield return assetBundle;
action();
}
4.从内存中加载
异步:
IEnumerator LoadFromMemoryAsync()
{
string path = Application.streamingAssetsPath + "/" + "prefab";
//byte by = byte.Parse(path);
AssetBundleCreateRequest createRequest = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));
yield return createRequest;
AssetBundle bundle = createRequest.assetBundle;
GameObject prefab = bundle.LoadAsset<GameObject>("Cube");
Instantiate(prefab);
}
同步:
private void LoadFromMemory()
{
string path = Application.streamingAssetsPath + "/" + "prefab";
AssetBundle bundle = AssetBundle.LoadFromMemory(File.ReadAllBytes(path));
GameObject prefab = bundle.LoadAsset<GameObject>("Cube");
Instantiate(prefab);
}
5.从本地获得网络加载WWW.LoadFromCacheOrDownload
通过URL进行加载
IEnumerator LoadFromCacheOrDownLoadExample ()
{
while (!Caching.ready)
{
yield return null;
}
var www = WWW.LoadFromCacheOrDownload("http://192.168.0.250/prefab.unity3d", 5);
//var www = WWW.LoadFromCacheOrDownload(@"D:\the9git\the9_09\UnityProject\UnityBase04\Assets\StreamingAssets\prefab", 5);
yield return www;
if (!string.IsNullOrEmpty(www.error))
{
Debug.Log(www.error);
yield return null;
}
AssetBundle myLoadedAB = www.assetBundle;
GameObject prefab = myLoadedAB.LoadAsset<GameObject>("Cube");
Instantiate(prefab);
//var asset = myLoadedAB.mainAsset;
}
6.通过UnityWebRequest加载AB包
IEnumerator InstantiateObject()
{
//string uri = "file:///" + Application.streamingAssetsPath + "/prefab";
string uri = "http://192.168.0.250/StreamingAssets/perfab.unity3d";
using (UnityWebRequest webRequest = UnityWebRequest.GetAssetBundle(uri))
{
yield return webRequest.SendWebRequest();
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(webRequest);
GameObject cube = bundle.LoadAsset<GameObject>("Cube");
Instantiate(cube);
}
string uri2 = "http://192.168.0.250/StreamingAssets/StreamingAssets";
using (UnityWebRequest webRequest2 = UnityWebRequest.GetAssetBundle(uri2))
{
yield return webRequest2.SendWebRequest();
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(webRequest2);
AssetBundleManifest assetBundleManifes = bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
string[] dps = assetBundleManifes.GetAllDependencies("perfab.unity3d");
for (int i = 0; i < dps.Length; i++)
{
string uri3 = "http://192.168.0.250/StreamingAssets/" + dps[i];
using (UnityWebRequest webRequest3 = UnityWebRequest.GetAssetBundle(uri3))
{
yield return webRequest3.SendWebRequest();
AssetBundle ab = DownloadHandlerAssetBundle.GetContent(webRequest3);
}
}
}
}
卸载有两个方面
1,减少内存使用
2,有可能导致丢失
所以什么时候去卸载资源
AssetBundle.Unload(true)将使全部InstanceID对应的GUID和localID无效,即使有资源被使用着,所有资源将显示为Missing。
(1,在关切切换、场景切换2,资源没被用的时候 调用)
AssetBundle.Unload(false)卸载所有没用被使用的资源
个别资源怎么卸载1,通过 Resources.UnloadUnusedAssets. 2,场景切换的时候
AssetBundle卸载