学習リソース https://www.bilibili.com/video/BV1Et411Z76x?p=11
アセットバンドルのパッケージ化
パッケージ化する必要があるリソースは 2 つあり、1 つはプレハブ、もう 1 つはマテリアルです。
AssetBundles フォルダーを削除する機能と、AssetBundles の内容を削除せずにパッケージ化する機能の 2 つで、2 回パッケージ化すると同じ内容が 2 回存在します。
/*
* 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();
}
}
パッケージ化されたアセットバンドル
Wall パッケージが非常に小さいことがわかります。これは、Cube によって参照されるマテリアルもパッケージ化されているためです。Cube のみがパッケージ化されている場合、2 つの Cube はマテリアルの 2 つのコピーのサイズになります。
メソッドの最後の 2 つのパラメーターは、パッケージ化および圧縮方法とパッケージ化プラットフォームです。
UnityWebRequest はローカルおよびサーバーの AssetBundle をロードします
UnityWebRequest はローカルおよびサーバーのリソースを読み込みます。サーバーは Tomcat を使用しているので、Tomcat フォルダーの Web アプリ内に Unity フォルダーを作成し、上記のコードで生成された AssetBundles フォルダーをコピーします。
壁は素材によって異なります
依存パッケージ内のリソースを読み込み(GetContent)しないと、読み込み順序に関係なく素材が正常に表示されません。
/*
* 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);
}
}
このように書くことも可能ですが、インスタンス化してから素材をロードすると、2秒後に素材がロードされます。
マニフェストを取得し、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 がロードするために必要なマテリアルの ab 名を知る必要はありません。
上記のmainABとmanifestの名前を確認しました。