1. 程式人生 > >Unity引擎的AssetBundle(資源管理技術)

Unity引擎的AssetBundle(資源管理技術)

一、Unity引擎的AssetBundle(資源管理技術)的介紹

    ①Unity引擎的AssetBundle(資源管理技術)是通過動態載入與解除安裝資源,極大節約遊戲所佔空間,且實現遊戲釋出後關於資源的後續更新與完善的實時更新技術。

    ② AssetBundles可以將Unity中所建立的檔案或任何資源匯出成為一種特定的檔案格式,這些檔案匯出後使用的是一種特定的檔案型別(.assetbundle/.unity3d),這些特定格式的檔案能夠在需要的時候載入到場景中。(這些特定格式的檔案可以是:模型、貼圖、聲音檔案;甚至是場景檔案)。

    ③AssetBundle可以分為四個部件

         《1》建立AssetBundles資源

         《2》上傳資源伺服器端

         《3》下載AssetBundles資源

         《4》載入與解除安裝AssetBundles資源

 

二、建立AssetBundle

①定位需要打包與載入的資源,可以是任意型別(如貼圖、材質、音訊、預設等),如下所示:

②編寫打包指令碼(BuildAssetBundles.cs) ,必須將該指令碼放置在"Editor"的特殊資料夾下

/***
 *
 *  Title: "AssetBundle工具包"專案
 *         給AssetBundle目錄(資源)打包
 *
 *  Description:
 *        功能:[本指令碼的主要功能描述] 
 *
 *  Date: 2018
 * 
 *  Version: 1.0
 *
 *  Modify Recorder:
 *     
 */

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

public class BuildAssetBundle{
    /// <summary>
    /// 打包生成所有AssetBundles
    /// </summary>
    [MenuItem("AssetBundleTools/BuildAllAssetBundles")]
    public static void BuildAllAB()
    {
        //(打包)AB的輸出路徑
        string strABOutPathDIR = string.Empty;

        strABOutPathDIR = Application.streamingAssetsPath;
        if (!Directory.Exists(strABOutPathDIR)){
            Directory.CreateDirectory(strABOutPathDIR);
        }
        //打包生成
        BuildPipeline.BuildAssetBundles(strABOutPathDIR,BuildAssetBundleOptions.None,
            BuildTarget.StandaloneWindows64);
    }

}//Class_end

③單機“BuildAllAssetBundles”後開始打包,大約幾秒後再專案檢視的StreamingAssets目錄下看到我們打包好的檔名稱

 

 

三、下載AssetBundle資源(採用“非快取機制”)

《1》Unity2017中具有3種不同的方法來載入已經下載的資料資源

         ①assetBundle.LoadAsset();             通過指定assetBundle包名稱載入資源

         ②assetBundle.LoadAssetAsync();   通過指定assetBundle包名稱非同步載入資源(載入過程中不會阻礙主執行緒的執行)

         ③assetBundle.LoadAllAsset();         載入所有的assetBundle中包含的資源物件

《2》下載AssetBundle資源(載入與解除安裝指令碼)

/***
 *
 *  Title: 
 *           AssetBundle資源動態載入技術
 *                  演示AssetBundle基本載入
 *
 *  Description:
 *        功能:
 *            演示載入AssetBundle且顯示資源,一共分兩種情形。
 *            1: 非“物件預設”資源載入與顯示。
 *            2: “物件預設”資源載入與顯示。 
 *            
 *        說明: 
 *            1: 這裡所謂的“基本載入”即在不使用自定義“AssetBundle框架”情況下載入“物件預設”。
 *            2: 這裡AssetBundle資源,是提前已經打包好的。
 *
 *  Date: 2018
 * 
 *  Version: 1.0
 *
 *  Modify Recorder:
 *     
 */

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

public class AssetBundleLoadDemo:MonoBehaviour {
    //顯示的方位
    public Transform TraShowPosition;
    //測試更改貼圖
    public GameObject goCube_ChangeTxt;
    /*  URL與材質名稱  */
    //第1組,測試顯示“預設體”
    private string _ABURL_1;                                
    private string _AssetName_1;
    //第2組,測試改變貼圖
    private string _ABURL_2;
    private string _AssetName_2;

    private void Awake(){        
        //物件預設資源路徑
        _ABURL_1 = "file://" + Application.streamingAssetsPath + "/prefabab.ab";
        _AssetName_1 = "SpherePink";
        //物件貼圖資源路徑
        _ABURL_2 = "file://" + Application.streamingAssetsPath + "/texturesab";
        _AssetName_2 = "unitychan_tile3";
    }

    private void Start(){
        //實驗1: 載入AB包,顯示簡單“預設體”
        StartCoroutine(LoadPrefabsFromAB(_ABURL_1, _AssetName_1, TraShowPosition));

        //實驗2: 載入AB包,顯示貼圖(材質、音訊等)
        //StartCoroutine(LoadNonObjFromAB(_ABURL_2, goCube_ChangeTxt,_AssetName_2));
    }

    /// <summary>
    /// (下載且)載入“預設”資源
    /// </summary>
    /// <param name="ABURL">AssetBundle URL</param>
    /// <param name="AssetName">資源名稱</param>
    /// <param name="showPos">例項化克隆體顯示方位</param>
    /// <returns></returns>
    IEnumerator LoadPrefabsFromAB(string ABURL,string assetaName="",Transform showPos=null)
    {
        //引數檢查
        if (string.IsNullOrEmpty(ABURL))
            Debug.LogError(GetType()+ "/LoadPrefabsFromAB()/ 輸入引數‘AssetBundle URL’為空,請檢查!");
        using (WWW www=new WWW(ABURL)){
            yield return www;
            AssetBundle ab = www.assetBundle;
            if (ab!=null){
                if (assetaName == ""){
                    //例項化主資源
                    if (showPos!=null){
                        //確定顯示方位
                        GameObject tmpClonePrefabs=(GameObject)Instantiate(ab.mainAsset);
                        tmpClonePrefabs.transform.position = showPos.transform.position;
                    }
                    else {
                        Instantiate(ab.mainAsset);
                    }
                }
                 else {
                    //例項化指定資源
                    if (showPos != null){
                        //確定顯示方位
                        GameObject tmpClonePrefabs = (GameObject)Instantiate(ab.LoadAsset(assetaName));
                        tmpClonePrefabs.transform.position = showPos.transform.position;
                    }
                    else{
                        Instantiate(ab.LoadAsset(assetaName));
                    }
                }
                //解除安裝資源(只解除安裝AssetBundle 包本身)
                ab.Unload(false);
            }
            else {
                Debug.LogError(GetType()+ "/LoadPrefabsFromAB()/WWW 下載出錯,請檢查 AssetBundle URL :"+ABURL+" 錯誤資訊: "+www.error);
            }
        }
    }

    /// <summary>
    /// (下載且)載入"非GameObject"資源
    /// </summary>
    /// <param name="ABURL">AssetBundle URL</param>
    /// <param name="AssetName">資源名稱</param>
    /// <returns></returns>
    IEnumerator LoadNonObjFromAB(string ABURL, GameObject goShowObj,string AssetName = "")
    {
        //引數檢查
        if (string.IsNullOrEmpty(ABURL) || goShowObj==null)
        {
            Debug.LogError(GetType() + "/LoadTextureFromAB()/ 輸入的引數為空,請檢查!");
        }

        using (WWW www = new WWW(ABURL))
        {
            yield return www;
            AssetBundle ab = www.assetBundle;
            if (ab != null)
            {
                if (AssetName=="")
                {
                    goShowObj.GetComponent<Renderer>().material.mainTexture = (Texture)ab.mainAsset;
                }
                else {
                    goShowObj.GetComponent<Renderer>().material.mainTexture = (Texture)ab.LoadAsset(AssetName);
                }
                //解除安裝資源(只解除安裝AssetBundle 包本身)
                ab.Unload(false);
            }
            else
            {
                Debug.LogError(GetType() + "/LoadTextureFromAB()/WWW 下載出錯,請檢查 AssetBundle URL :" + ABURL + " 錯誤資訊: " + www.error);
            }
        }
    }

}//Class_end

 

注:本內容來自《Unity3D/2D遊戲開發從0到1》29章