1.AssetBundle 是一个压缩包,包含模型,贴图,预制体,声音,甚至整个场景,可以在游戏运行的时候被加载;
2.AssetBundle自身保存着相互的依赖关系;
3.压缩包可以使用LZMA和LZ4压缩算法,减少包大小,更快的进行网络传输;
4.把一些可以下载内容放在AssetBundle里面,可以减少安装包大小;
可以归为两点:
1.它是存在于硬盘上的文件,可以称为压缩包,也可以成为文件。这些文件分为:serialized file 和resource file(序列化文件和源文件)
serialized file:资源被打碎放在一个对象中,最后统一被写进一个单独的文件(只有一个)
resource file:某些二进制资源(图片,声音)被单独保存,方便快速加载。
2.它是一个AssetBundle对象,可以通过代码从一个特定的压缩包里加载出来的对象。
然后通过Editor展示:
using UnityEditor;using System.IO;public class creatAssetsBundles { [MenuItem("Assets/Build AssetBundles")]//创建菜单栏 static void BUildAllAssetBundles() { string dir = "AssetBundles"; if (Directory.Exists(dir) == false)//如果该路径不存在 { Directory.CreateDirectory(dir); } BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);//路径,压缩方式。对应平台 }}
会创建一个 AssetBundle的文件夹:
里面就是刚才打包的资源
可以分层操作:
把两个资源打包到同一个文件下:
加载资源:
using System.Collections;using System.Collections.Generic;using UnityEngine;public class LoadAssetFormFile : MonoBehaviour { // Use this for initialization void Start () { AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/scence/wall.unity3d");//给路径 GameObject wallprefab = ab.LoadAsset("Cube");//加载资源 Instantiate(wallprefab);//实例化出来 } }
依赖打包:
把共同的资源打成一个包,就不需要重复打包了,如:
材质,贴图
AssetBundle的使用流程:
BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);//路径,压缩方式。对应平台
原则上来说:加载的时候,如果有材质,要先加载材质,要不然就会材质丢失:(有依赖的,要先加载依赖的包)
正确做法:
using System.Collections;using System.Collections.Generic;using UnityEngine;public class LoadAssetFormFile : MonoBehaviour { // Use this for initialization void Start () { AssetBundle ab1 = AssetBundle.LoadFromFile("AssetBundles/scence/shear.unity3d");//加载材质 AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/scence/cube.unity3d");//给路径加载object GameObject wallprefab = ab.LoadAsset("Cube");//加载资源 Instantiate(wallprefab);//实例化出来 } }
AssetBundle的加载方式:
using System.Collections;using System.Collections.Generic;using UnityEngine;using System.IO;public class LoadAssetFormFile : MonoBehaviour { // Use this for initialization IEnumerator Start () { string path = "AssetBundles/scence/cube.unity3d"; //AssetBundle ab1 = AssetBundle.LoadFromFile(path);//加载材质 //AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/scence/cube.unity3d");//给路径加载object //GameObject wallprefab = ab.LoadAsset("Cube");//加载资源 //Instantiate(wallprefab);//实例化出来 //第一种加载方式 LoadFromMemoryAsync 异步从内存中加载 //AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path)); //yield return request; //AssetBundle ab = request.assetBundle; //同步加载方式 // AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes(path)); //第二种加载方式 LoadFormFile //AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path); //yield return request; //AssetBundle ab = request.assetBundle; //第三种加载方式 www while (Caching.ready == false) { yield return null; } //file:// file:/// WWW www = WWW.LoadFromCacheOrDownload(@"F:\project\AssetsBundle\AssetBundles\scence\cube.unity3d",5); yield return www; if (string.IsNullOrEmpty(www.error) == false) { Debug.Log(www.error); yield break; } AssetBundle ab = www.assetBundle;
//第四种加载方式 使用unitywebRequest 需要引用命名空间 using UnityEngine.Networking; string uri = @"F:\project\AssetsBundle\AssetBundles\scence\cube.unity3d";//如果要从服务器加载,就改为网址 UnityWebRequest request = UnityWebRequest.GetAssetBundle(uri); yield return request.Send(); //AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request); //也可以这样加载 AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
//使用里面的资源 GameObject wallprefab = ab.LoadAsset("Cube");//加载资源 Instantiate(wallprefab);//实例化出来
//通过manifest加载所依赖的包 AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles"); AssetBundleManifest manifest = manifestAB.LoadAsset("AssetBundleManifest"); string[] strs = manifest.GetAllDependencies("scence/cube.unity3d"); foreach (string name in strs) { print(name);//打印所依赖的包的名字 AssetBundle.LoadFromFile("AssetBundles/" + name); }
}}
第四种加载方式:
具体参考API