前言
- AssetBundle是unity中的一种资源打包方式
- 在对资源进行打包后,会有一些相应的文件manifest
如何打包
- 在对任何资源的inspector下面标注名字与后缀【名字可以多层嵌套,打包的时候会根据名字生成对应的文件夹结构】
- 在BuildAssetBundleOptions.None中指定AssetBundle指定压缩方式,Unpressed不压缩,ChunkBasedCompression LZ4压缩算法,None使用LZMA算法
- 在实际开发中使用None比较多
string path = Application.dataPath + "/AssetBundles";
BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
打包文件
- 打包出来的文件分为两部分
- Assetbundle文件
- 配套的manifest文件
- CRC校验码,类似于MD5,用于校验出该资源的一个特殊信息标识

- classTypes列表,当前资源用到了unity中的哪些组件,以编号索引的形式存在,每个编号对应一个类文件

- .meta文件属于unity环境的产物,对于每个资源都会生成这个文件存储该资源的一些信息
- 在打包出来的根文件夹下有一个与文件夹同名的manifest文件,这个manifest文件可以称之为AssetBundle目录文件,存储了打包出来的所有的AssetBundle文件的索引信息
- 【通过它可以找到所有的AssetBundle文件】
- 【还有一个与根文件夹同名的AssetBundle文件】


AssetBundle资源加载介绍
- 留在项目工程当中,当成普通的资源进行使用
- 上传到服务器,第一次运行的时候从服务器下载这些文件,缓存到本地,然后进行使用
第一种
AssetBundle ab = AssetBundle.LoadFromFile("AB包完整路径")
- 从完整的路径位置加载AB资源包到内存,返回一个AssetBundle对象
T resName = ab.LoadAsset<T>("游戏资源名称")
- 通过获取的AssetBundle对象获取对应的游戏物体资源,并且返回该资源
- 注意StreamingAssets文件夹内的资源,会在项目打包过程中直接把该文件夹及文件夹内部的所有资源一起原封不动的打包到最终项目成品中
- Android直接打包到APK中
- Windows直接打包到“XXX_Data”文件夹下
AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/music.re");
GameObject temp = ab.LoadAsset<GameObject>("Cube");
GameObject.Instantiate<GameObject>(temp, Vector3.zero, Quaternion.identity);
第二种 从服务器加载
using UnityEngine.Networking
//创建一个获取Assetbundle文件的web请求
UnityWebRequest request = UnityWebRequest.GetAssetBundle(url)
//发送这个web请求
yield return request.Send();
//从web请求中获取内容,返回一个AssetBundle类型的数据
AssetBundle ab = DownloadHanderAssetBundle.GetContent(request);
private string AssetBundlePath = @"http://192.168.0.105/AssetBundles/AssetBundles";
private string AllBundlePath = @"http://192.168.0.105/AssetBundles/";
private void Start()
{
StartCoroutine("LoadAsset");
}
private IEnumerator LoadAsset()
{
UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(AssetBundlePath);
yield return request.SendWebRequest();
AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);
//从主AssetBundle文件中获取manifest文件
AssetBundleManifest manifest = ab.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//获取所有AssetBundle文件的路径
string[] names = manifest.GetAllAssetBundles();
for (int i = 0; i < names.Length; i++)
{
Debug.Log(names[i]);
//开启下载单个AssetBundle文件的协程 通过组拼路径
StartCoroutine("LoadSingleFileByWWW", AllBundlePath + names[i]);
}
}
- 下载单个assetbundle文件
GetFileNameWithoutExtension()
截取路径地址中的文件名,且无后缀名,需要引入System.IO命名空间
private IEnumerator LoadSingleFile(string uri)
{
UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uri);
yield return request.SendWebRequest();
AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);
//request.bytes
string[] names = ab.GetAllAssetNames();
for (int i = 0; i < names.Length; i++)
{
// Debug.Log(names[i]);
string cons = Path.GetFileNameWithoutExtension(names[i]);
GameObject asset = ab.LoadAsset<GameObject>(cons);
GameObject.Instantiate<GameObject>(asset, Vector3.zero, Quaternion.identity);
}
}
存储文件到本地
- 我暂时还没有找到unitywebrequest里面的api将Assetbundle转换为字节数组
private IEnumerator LoadSingleFileByWWW(string uri)
{
WWW request = new WWW(uri);
yield return request;
if (request.isDone)
{
SaveAssetsBundle(Path.GetFileName(uri), request.bytes, request.bytes.Length);
}
}
//存储AssetBundle为本地文件
private void SaveAssetsBundle(string name, byte[] bytes, int count)
{
FileInfo fileInfo = new FileInfo(Application.streamingAssetsPath + "//" + name);
FileStream fs = fileInfo.Create();
fs.Write(bytes, 0, count);
fs.Flush();
fs.Close();
fs.Dispose();
}