学习资源 https://www.bilibili.com/video/BV1Et411Z76x?p=11
AssetBundles打包
需要打包的两个资源,一个prefab、一个material,prefab引用了material
两个功能,删除AssetBundles文件夹,和不删除AssetBundles里面的东西进行打包,打包两次则会有两倍同样东西
/*
* Author :
* Time : 2020.5
* Title :
* Description:
*
*
*/
using System.IO;
using UnityEditor;
using UnityEngine;
static class BuildAssetBundles
{
/// <summary>
/// 在AssetBundles(和Asset同级)下创建所有ab包
/// </summary>
[MenuItem("Assets/Build AssetBundles(Dont Delete Exist AssetBundles)")]
static void Build()
{
if (!Directory.Exists("AssetBundles"))
Directory.CreateDirectory("AssetBundles");
BuildPipeline.BuildAssetBundles("AssetBundles",
BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows64);
}
/// <summary>
/// 删除AssetBundles文件下的所有东西(包括该文件夹)
/// </summary>
[MenuItem("Assets/Delete All AssetBundles")]
static void DeleteAll()
{
Delete("AssetBundles");
}
/// <summary>
/// 删除路径下的所有文件夹,包括该文件夹
/// </summary>
/// <param name="path"></param>
static void Delete(string path)
{
DirectoryInfo dir = new DirectoryInfo(path);
FileSystemInfo[] files = dir.GetFileSystemInfos();
//因为是文件信息集合不是文件集合所以可以用foreach迭代
foreach (var file in files)
{
if (file is DirectoryInfo)
Delete(file.FullName);
else
file.Delete();
}
dir.Delete();
}
}
打包后的AssetBundles
可以看到wall包很小,这是因为Cube引用的material也被打包,如果只打包cube,两个cube就有两份material的大小
方法后两个参数分别为,打包压缩方式,打包平台
UnityWebRequest加载本地、服务器AssetBundles
UnityWebRequest加载本地、服务器资源。服务器用的是Tomcat,在Tomcat文件夹的webapp中创建了Unity文件夹,把上面上面上面代码生成的AssetBundles文件夹copy过去
wall依赖于material
如果不加载(GetContent)依赖包中的资源,则无法正常显示material,跟加载顺序无关。
/*
* Author :
* Time : 2020.5
* Title :
* Description:
*
*
*/
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class Example : MonoBehaviour
{
private void Start()
{
//AssetBundle wallAB = AssetBundle.LoadFromFile("AssetBundles/wall.unity3d");
//AssetBundle materialAB = AssetBundle.LoadFromFile("AssetBundles/material.unity3d");
//GameObject prefab = wallAB.LoadAsset<GameObject>("Cube");
//Instantiate(prefab);
print(Application.dataPath);
string path = @"D:/Documents/Unity/Project/TestProject/AssetBundles/";
string url = "localhost:8080/Unity/AssetBundles/";
StartCoroutine(LoadCoroutine(url));
}
IEnumerator LoadCoroutine(string path)
{
print("begin");
UnityWebRequest wallRequest = UnityWebRequestAssetBundle.GetAssetBundle(path + "wall.unity3d");
UnityWebRequest shareRequest = UnityWebRequestAssetBundle.GetAssetBundle(path + "material.unity3d");
wallRequest.timeout = 10;
shareRequest.timeout = 10;
yield return wallRequest.SendWebRequest();
print("down1");
yield return shareRequest.SendWebRequest();
print("down2");
//如果不获取依赖包,则无法正常加载
DownloadHandlerAssetBundle.GetContent(shareRequest);
AssetBundle wallAB = DownloadHandlerAssetBundle.GetContent(wallRequest);
GameObject wallPrefab = wallAB.LoadAsset<GameObject>("Cube");
Instantiate(wallPrefab);
}
}
这么写也是可以的,先实例化在加载material,材质在两秒后再加载出来
获取manifest,得到ab包依赖信息
void LoadLocally()
{
AssetBundle wallAB = AssetBundle.LoadFromFile(@"AssetBundles/wall.unity3d");
AssetBundle mainAB = AssetBundle.LoadFromFile(@"AssetBundles/AssetBundles");
AssetBundleManifest manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
string[] wallABDependencies = manifest.GetAllDependencies("wall.unity3d");
foreach (var s in wallABDependencies)
{
AssetBundle.LoadFromFile(@"AssetBundles/" + s);
}
GameObject prefab = wallAB.LoadAsset<GameObject>("Cube");
Instantiate(prefab);
}
不用知道Cube所需要Material的ab名字就能加载了
上面的mainAB和manifest的名字是确定的