1. 程式人生 > >【Unity3D】5.0版本之後的AssetBundle資源的打包和解析載入

【Unity3D】5.0版本之後的AssetBundle資源的打包和解析載入

一、前言

這幾天在研究AssetBundle資源打包盒解析載入,也踩過很多坑,參考過很多人的文章
發現很多人關於AssetBundle的文章不是API過時了不能用,就是有點亂
也不是有點亂,就是摸不著頭腦,讓人不能快速的get到這個東西如何使用
所以我特意在踩過坑之後把我這個學到的經驗分享給大家。

PS: 一把辛酸淚

二、參考文章

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資料夾中
    在這裡插入圖片描述
  2. 編輯程式碼
    在這裡插入圖片描述
    原始碼:
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的圖片
在這裡插入圖片描述
在這裡插入圖片描述
點選PackBundles
在這裡插入圖片描述
這就將Texture中的123.jpg打包到123.unity3d中了

第二種,全部打包AllPackBundles
需要先在編輯器設定好引數
在這裡插入圖片描述在這裡插入圖片描述
在這裡插入圖片描述
然後打包
在這裡插入圖片描述
這就將名字為Cube的預製體打包進入cube.unity3d

四、AssetBundle解析載入

4.1 API講解

4.1.1 載入AssetBundle的API

在這裡插入圖片描述
在這裡插入圖片描述
//載入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 從網上下載資源

在這裡插入圖片描述
原始碼:

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 從本地下載資源

在這裡插入圖片描述
原始碼:

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檔案中
    編輯指令碼
    ![
  2. 新建指令碼LoadBundles.cs隨意放那個資料夾都行
    編輯指令碼:
    在這裡插入圖片描述
  3. 打包資源
    在這裡插入圖片描述
    在這裡插入圖片描述
  4. 把載入指令碼LoadBundles.cs掛載在場景中的任意物體上
    在這裡插入圖片描述
  5. 成功載入生成
    在這裡插入圖片描述

PS:途中的Cube是我設定好的Cube預製體,加上了一個材質

OK,文章結束

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