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章