天天看點

【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載

大家好,我是佛系工程師☆恬靜的小魔龍☆,不定時更新Unity開發技巧,覺得有用記得一鍵三連哦。

一、前言

這幾天在研究AssetBundle資源打包盒解析加載,也踩過很多坑,參考過很多人的文章

發現很多人關于AssetBundle的文章不是API過時了不能用,就是有點亂

也不是有點亂,就是摸不着頭腦,讓人不能快速的get到這個東西如何使用

是以我特意在踩過坑之後把我這個學到的經驗分享給大家。

PS: 一把辛酸淚

二、參考文章

1.雨松大大的​​Unity3D研究院之Assetbundle的實戰(六十三)​​

2.​​Unity AssetBundle爬坑手記​​

3.​​Unity5自動命名Assetbundle并打包​​

4.​​5.0後版本的AssetBundle 使用​​

5.​​Unity AssetBundle爬坑手記​​

6.​​再詳細的介紹一下Unity5的AssetBundle​​

7.​​ Unity3D研究院之Assetbundle的實戰(六十一)​​

8.​​Unity5 新AssetBundle打包方式 BuildPipeline.BuildAssetBundles​​

9.​​Unity最新版打包AssetBundle和加載的方法​​

10.​​Unity中 BundleAsset資源的打包和解析加載​​

PS:從參考的文章就知道踩了多少坑了

三、AssetBundle打包方式

3.1 API

  1. BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);
  2. BuildAssetBundles(string outputPath,AssetBundleBuild[] builds,BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);

3.2 參數說明

outputPath:包Bundle後存儲的目錄,如:Assets/AssetBundles,這個檔案夾不會自動建立,如果它不存在的話,函數将會失敗

BuildAssetBundleOptions:Bundle打包方式,none沒有任何特殊選項,UncompressedAssetBundle在建構Bundle時不要壓縮資料等等

BuildTarget:建構平台,如iphone,windows,android等

AssetBundleBuild[]:這個類與BuildAssetBundles一起使用。指定一個Bundle包的名稱assetBundleName和它将包含的資源(如多張圖檔、音頻等)的名稱。

被傳遞給函數的AssetBundleBuild[]元素數組被稱為“建構映射”,并作為指定編輯器包内容的替代方法。

AssetBundleBuild[]變量:

addressableNames:傳回所有的addressableName數組

assetBundleName:AssetBundle的名字

assetBundleVariant:AssetBundle的擴充名如.unity

AssetBundle:指定屬于一個addressableName名字的所有資源名字,是一個數組,也就是一個addressableName名字下包含的所有資源名字

3.3 例子

  1. 建立一個腳本PackBundles.cs,放到Editor檔案夾中
    【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載
  2. 編輯代碼
    【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載
    源代碼:
using System.Collections.Generic;
using System.IO;
using UnityEditor;

public class PackBundles : Editor
{
    //標明資源打包
    [MenuItem("PackBundles/PackBundles")] 
    static void PutBundleAssetes()
    {
        //初始化一個AssetBundleBuild表
        List<AssetBundleBuild> buildMap = new List<AssetBundleBuild>();
        AssetBundleBuild build = new AssetBundleBuild();
        //設定AssetBundleBuild的名字和資源路徑
        build.assetBundleName = "123.unity3d";
        build.assetNames = new[] { "Assets/Textures/123.jpg" };
        //添加進表
        buildMap.Add(build);

        //将這些資源包放在一個名為ABs的目錄下        
        string assetBundleDirectory = "Assets/ABs";
        //如果目錄不存在,就建立一個目錄        
        if (!Directory.Exists(assetBundleDirectory))
        {
            Directory.CreateDirectory(assetBundleDirectory);
        }
        //資源打包
        BuildPipeline.BuildAssetBundles(assetBundleDirectory, buildMap.ToArray(), BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
    }

    //全部打包
    [MenuItem("PackBundles/AllPackBundles")] 
    static void PutBundleAssetesAll()
    {
        //将這些資源包放在一個名為ABs的目錄下        
        string assetBundleDirectory = "Assets/ABs";
        //如果目錄不存在,就建立一個目錄        
        if (!Directory.Exists(assetBundleDirectory))
        {
            Directory.CreateDirectory(assetBundleDirectory);
        }
        BuildPipeline.BuildAssetBundles(assetBundleDirectory,BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
    }
}      

3.運作

首先Textures檔案夾中存放一張123.jpg的圖檔

【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載
【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載

點選PackBundles

【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載

這就将Texture中的123.jpg打包到123.unity3d中了

第二種,全部打包AllPackBundles

需要先在編輯器設定好參數

【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載
【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載
【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載

然後打包

【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載

這就将名字為Cube的預制體打包進入cube.unity3d

四、AssetBundle解析加載

4.1 API講解

4.1.1 加載AssetBundle的API

【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載
【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載

//加載AssetBundle包

public static AssetBundle LoadFromFile(string path );

public static AssetBundle LoadFromFile(string path ,uint crc = 0);

public static AssetBundle LoadFromFile(string path ,uint crc = 0, ulong offset= 0);

4.1.2 參數說明

path: 讀取AssetBundle的目錄

crc : 校驗用參數

offset: 這個值指定從哪裡開始讀取AssetBundle

//從網上加載AssetBundle包

public static UnityWebRequest GetAssetBundle(string uri, uint crc);

public static UnityWebRequest GetAssetBundle(string uri, uint version, uint crc);

public static UnityWebRequest GetAssetBundle(string uri, Hash128 hash, uint crc);

public static UnityWebRequest GetAssetBundle(string uri, CachedAssetBundle cachedAssetBundle, uint crc);

4.1.3 參數說明

uri:AssetsBundle包的網絡位址:(可以是本地file:)

crc:0如果不為0,将會進行校驗

version:一個整數版本号

hash:一個版本散列

cachedAssetBundle:用于将給定版本的AssetBundle下載下傳到自定義緩存路徑的結構

4.2 加載包中資源API

//加載AssetBundle包的資源

public Object LoadAsset(string name);

public Object LoadAsset( string name, Type type);

public T LoadAsset( string name);

public Object[] LoadAllAssets( Type type);

public Object[] LoadAllAssets();

public T[] LoadAllAssets();

public Object LoadAllAssetsAsync();

public Object LoadAssetAsync( string name);

4.2.1 參數說明

name:從AssetBundle包中加載名字為name的資源,傳回object

Type:加載包内所有類型為type的資源

LoadAllAssets:加載包中所有資源

LoadAssetAsync: 異步加載包中所有資源

4.3 其他API

Path.Combine(string, string) 連接配接兩個字元串

Application.streamingAssetsPath輸出

E:/UnityProject/ARVR/Workspace/MyCharacter/Assets/StreamingAssets

Application.dataPath輸出

E:/UnityProject/ARVR/Workspace/MyCharacter/Assets

4.2 從網上下載下傳資源

【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載

源代碼:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LoadBundles : MonoBehaviour
{
    GameObject go;
    void Start()
    {
        StartCoroutine(Load());
    }

    IEnumerator Load()
    {
        //從遠端伺服器上進行下載下傳和加載
        WWW www = new WWW("ftp://123.778.1.128/cube.unity3d");
        //等待檔案下載下傳完畢
        yield return www;
        //加載資料并指派給AssetBundle
        AssetBundle bundle = www.assetBundle;
        //LoadAssetAsync異步加載包中資源傳遞給request,request中存放的是名字為Cube.prefab的資料
        AssetBundleRequest request = bundle.LoadAssetAsync("Cube.prefab", typeof(GameObject));
        go = Instantiate(request.asset as GameObject, new Vector3(0f, 0f, 0f), Quaternion.identity) as GameObject;
        yield return request;
        //釋放資源
        www.Dispose();
    }
}      

4.3 從本地下載下傳資源

【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載

源代碼:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LoadBundles : MonoBehaviour
{
    GameObject go;
    void Start()
    {
        StartCoroutine(Load());
    }

    IEnumerator Load()
    {
        //從本地檔案中加載
        WWW www = new WWW("file://D:/Frank/UnityProject/Demo-1/Assets/ABs/cube01.unity3d");
        //等待檔案下載下傳完畢
        yield return www;
         //加載資料并指派給AssetBundle
        AssetBundle bundle = www.assetBundle;
        //LoadAssetAsync異步加載包中資源傳遞給request,request中存放的是名字為Cube.prefab的資料
        AssetBundleRequest request = bundle.LoadAssetAsync("Cube.prefab", typeof(GameObject));
        go = Instantiate(request.asset as GameObject, new Vector3(0f, 0f, 0f), Quaternion.identity) as GameObject;
        yield return request;
        www.Dispose();
    }
}      

五、測試例子

##步驟:

  1. 建立腳本PackBundles.cs放在Editor檔案中

    編輯腳本

    【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載
  2. 建立腳本LoadBundles.cs随意放那個檔案夾都行

    編輯腳本:

    【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載
  3. 打包資源
    【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載
    【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載
  4. 把加載腳本LoadBundles.cs挂載在場景中的任意物體上
    【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載
  5. 成功加載生成
    【Unity3D日常開發】5.0版本之後的AssetBundle資源的打包和解析加載
PS:途中的Cube是我設定好的Cube預制體,加上了一個材質

OK,文章結束

PS:如果想要加載網上資源,就把打包好的包放到伺服器上,然後通過位址,WWW類下載下傳下來,解析加載就行了。

繼續閱讀