AssetBundle资源打包和加载在对于Unity开发者是非常重要的,这里我做了一下比较全面的笔记。从AssetBundle资源打包和加载以及从本地服务器进行加载大概有四步,为了学习方便,我把第三步放在第四步之后了,感兴趣的可以耐心看完。
1.指定资源的AssetBundle属性,打标签(xxxa/xxx yyy),其中yyy的标签是可以不打的,打的话会在xxx的名称后面加上.yyy。如将预制体Cube的ab标签改为girl unity3d,SkyCar的标签改为scene/car unity3d。
2.代码创建打包工具构建AssetBundle包,其目的是将资源中的资源文件打包成压缩文件。
using UnityEngine;
using UnityEditor;
using System.IO;
public class AssetBundleTool
{
[MenuItem("Tools/AssetBundles/BuildAssetBundles")]
public static void BuildAssetBundles()
{
Debug.Log("开始打包");
string outPath = Application.dataPath + "/AssetBundleTest/AssetBundles";
//如果当前文件夹不存在,创建这个文件夹
if (Directory.Exists(outPath) == false)
{
Directory.CreateDirectory(outPath);
}
//每次打包前,可以删除当前路径下的文件(文件,文件夹)
DeleteOldDirData(outPath);
//进行AssetBundle打包,并且将已经打标签的assetbundle都进行压缩打包,打包到outPath路径下
//无特殊压缩要求 win平台
BuildPipeline.BuildAssetBundles(outPath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
}
///
/// 传入一个路径,用来删除老的文件及文件夹
///
///
private static void DeleteOldDirData(string path)
{
try
{
//实例化一个文件类,连接path这个路径
DirectoryInfo dr = new DirectoryInfo(path);
//获取当前文件夹下的子文件或者文件夹
FileSystemInfo[] fileSystemInfos = dr.GetFileSystemInfos();
//遍历所有的子文件和文件夹
foreach (FileSystemInfo item in fileSystemInfos)
{
//如果当前子文件是文件夹
if (item is DirectoryInfo)
{
DirectoryInfo subDir = new DirectoryInfo(item.FullName);
subDir.Delete(true); //recursive布尔值为true表示删除后不保存
}
//如果是文件,直接删除
else
{
File.Delete(item.FullName);
}
}
}
catch (System.Exception)
{
throw;
}
}
}
unity3d,打包后会生成如下文件:
&emsp**;4**.解压AB包的中的压缩文件,将其加载出来,这里我列举出了四种加载方式(下面我为了方便把ab标签中的scene这个去掉了,把资源中的预制体打在了同级目录下):
加载方式一:
using UnityEngine;
///
/// 解压AB包的中的压缩文件,将其加载出来
///
public class AssetBundleLoader : MonoBehaviour
{
void Start()
{
//ab文件中的car的文件路径
string abCarPath = Application.dataPath + "/AssetBundleTest/AssetBundles/car.unity3d";
//加载ab文件
AssetBundle abCar = AssetBundle.LoadFromFile(abCarPath);
//压缩文件进行解压
//GameObject car = abCar.LoadAsset("SkyCar") as GameObject;//或者
GameObject car = abCar.LoadAsset<GameObject>("SkyCar");
//复制
GameObject car1 = Instantiate(car);
car1.name = "smallCar";
}
}
该文件是从文件夹中car.unity3d.manifest这个文件中加载出来的
第二种加载方式,异步加载:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///
/// 解压AB包的中的压缩文件,将其加载出来
///
public class AssetBundleLoader : MonoBehaviour
{
///
/// ab加载的第二种方法
///
///
private IEnumerator Start() //在继承Monobehaviour的时候,这个方法和Start方法是一样的
{
string path = Application.dataPath + "/AssetBundleTest/AssetBundles/cube.unity3d";
//异步加载资源
AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path);
yield return request;
//abCar加载过来的ab文件
AssetBundle abCube = request.assetBundle;
//从压缩文件中提取资源文件
Instantiate(abCube.LoadAsset<GameObject>("Cube"));
}
}
第三种加载方式,www网络加载:
//ab加载的第三种方法,www加载 网络下载的
string path = Application.dataPath + "/AssetBundleTest/AssetBundles/cube.unity3d";
// 从缓存或者网络上进行下载 //路径 版本号
WWW www = WWW.LoadFromCacheOrDownload(@"file:/" + path, 1);
加载或者下载完之后,返回出来
yield return www;
如果www的错误日志不为空的话,那就是报错了
if (!string.IsNullOrEmpty(www.error))
{
Debug.LogError(www.error);
yield break;
}
获取压缩文件
AssetBundle abCube = www.assetBundle;
解压压缩文件并实例化
Instantiate(abCube.LoadAsset("Cube") as GameObject);
第四种加载方式,UnityWebRequest网络加载,unity官方后面会逐渐的用这个取代www:
//ab加载的第四种方法 网络方面的下载 UnityWebRequest,unity官方后面会逐渐的用这个取代www
string path = Application.dataPath + "/AssetBundleTest/AssetBundles/cube.unity3d";
//引入UnityEngine.Networking命名空间
//通过UnityWebRequest来加载ab文件
UnityWebRequest request = UnityWebRequest.GetAssetBundle(path);
yield return request.Send();
AssetBundle abCube = DownloadHandlerAssetBundle.GetContent(request);
Instantiate(abCube.LoadAsset("Cube") as GameObject);
3.上传AB包的中的压缩文件到本地服务器和从本地服务器中加载AB包
首先先下载NetBox2这个本地服务器,东西很小,才六百多K,(链接:https://pan.baidu.com/s/1985qjF7nSZ5gBSJwfSMsBQ
提取码:lif5 )将NetBox2这个文件放在任一文件路径之下,打开NetBox2.exe,然后把打包出来的AssetBundle包文件放在和NetBox2.exe同级目录下,如图:
运用WWW从本地服务器进行加载:
WWW www = WWW.LoadFromCacheOrDownload(@"http://localhost/AssetBundles/cube.unity3d", 1);
//加载或者下载完之后,返回出来
yield return www;
//如果www的错误日志不为空的话,那就是报错了
if (!string.IsNullOrEmpty(www.error))
{
Debug.LogError(www.error);
yield break;
}
//获取压缩文件
AssetBundle abCube = www.assetBundle;
//解压压缩文件并实例化
Instantiate(abCube.LoadAsset("Cube") as GameObject);
运用UnityWebRequest从本地服务器进行加载:
//在本机服务器地址上下载ab资源
// 本机服务器的AssetBundles下的cube.unity3d文件
string url = @"http://localhost/AssetBundles/cube.unity3d";
//引入UnityEngine.Networking命名空间
//通过UnityWebRequest来加载ab文件
UnityWebRequest request = UnityWebRequest.GetAssetBundle(url);
yield return request.Send();
AssetBundle abCube = DownloadHandlerAssetBundle.GetContent(request);
Instantiate(abCube.LoadAsset("Cube") as GameObject);
注意:从本地服务器加载ab包的时候本地服务器一定要打开