Unity アセットバンドルに関する注意事項

 学習リソース 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の名前を確認しました。

おすすめ

転載: blog.csdn.net/qq_41225779/article/details/106153921