Unity使用AssetBundle(AB包)實作資源的打包,加載和卸載
- 一、為什么專案開發一般要使用AssetBundle對資源進行打包,加載和卸載?
- 二、使用Unity 的AssetBundle打包資源
- 三、Unity 加載和卸載AssetBundle
一、為什么專案開發一般要使用AssetBundle對資源進行打包,加載和卸載?
為什么專案開發一般要使用AssetBundle對資源進行打包,加載和卸載?
主要原因有以下幾點:
- 游戲資源一般來說只有在被使用到或即將被使用到時才應該被加載進記憶體中,不應該一直出現在場景里,很容易理解,我剛打開游戲的第一關,我需要將第10關的BOSS提前在記憶體中加載好嗎?這無疑是對記憶體空間的極大浪費,所以我們要對資源進行合理的加載和卸載,使用時加載,用完后卸載,
- Unity對資源進行加載和卸載主要有兩種方式:Resources和AssetBundle,AssetBundle相比于Resources來說,最主要的優勢就是對于游戲的資源熱更新,比如說,我現在有一個安裝包1G大小的手游,現在有一個1M大小的資源A出問題了,我將這個資源A替換成了另一個同樣1M大小的資源B,此時差距就出現了:
(1)如果我使用Resources管理資源,資源是全部存盤在安裝包中的,那么我替換完成后,為了讓用戶同步到這次的資源更新,我得再重新將整個游戲打一個新的包,也就是說,僅僅是替換了一個1M的資源,用戶卻必須重新下載1G的新包進行安裝,這無論是從效率上還是用戶體驗上來說都是非常差勁的,
(2)如果我使用AssetBundle管理資源,資源是和安裝包分離,單獨打包的,而且一個游戲的資源一般會按照型別或是邏輯分成很多小包,游戲運行時需要用到什么資源就從對應的包中讀取相應的資源,如此一來,當我們替換資源A后,只需要將A資源所在的包(bundle)進行更新,重新將這個bundle發布給用戶,直接覆寫原先的bundle即可,替換一個1M的資源可能只需要用戶下載2-10M即可完成,基本保證了用戶無需下載未改動的部分,
再說的形象點,我現在有一副畫

說現在需求改了,得在后面加畫個太陽,

如果用Resource就是再拿一張白紙出來重新畫一張一模一樣的圖但是畫的時候加了個太陽,而用 AssetBundle就是把需要畫太陽的部分切下來,畫個太陽,再放回去,
3.使用AssetBundle可以顯著減少安裝包的大小,因為Unity編譯打包是將整個Asset檔案夾打包壓縮,我們可以將游戲后期才需要的資源(AB包)不放入asset中,等玩家玩到的時候再去下載,安裝包越小玩家對游戲的接受程度就越高,
二、使用Unity 的AssetBundle打包資源
1.首先點擊需要打包的資源檔案(注意不能選擇場景里的物體,只能在Asset目錄下選擇,如果一定要場景里的物體請先保存為prefab存盤下來),可以是任何格式的檔案,沒有限制,在Inspect面板最下方可以看到AssetBundle的兩個選項

第一個選項是該檔案所在的包名,選擇new自己起一個名字,第二個選項是這個包的后綴名,也可以隨意取,但注意后綴名不能是像txt,rar,jpg這種,讀取的時候會出錯,包名和后綴都相同的資源就會被打在同一個包里,

2.Unity本身支持AssetBundle,有寫好的API,直接使用即可,無需安裝任何插件,唯一麻煩的一點是Unity只提供了API,沒有提供一鍵打包的選項,需要手動書寫一個工具腳本呼叫內置的打包命令,這里本人已經寫好了三端都可以打包的腳本,需要的自取,
如果想要自己學習如何書寫打包腳本,請移步AssetBundle的使用方法詳解,視頻詳細描述了打包的細節和讀取的方法,
注意:必須在Asset下創建一個叫Editor的檔案夾,腳本必須放在Editor檔案夾下才能使用,Windows平臺的路徑可以隨意選擇,Andriod和IOS的存盤路徑是約定好不能變更的,
using UnityEditor;
using System.IO;
public class AssetBuldle : Editor
{
[MenuItem("Tools/CreatAssetBundle for Android")]
static void CreatAssetBundle()
{
string path = "Assets/StreamingAssets";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.UncompressedAssetBundle, BuildTarget.Android);
UnityEngine.Debug.Log("Android Finish!");
}
[MenuItem("Tools/CreatAssetBundle for IOS")]
static void BuildAllAssetBundlesForIOS()
{
string dirName = "AssetBundles/IOS";
if (!Directory.Exists(dirName))
{
Directory.CreateDirectory(dirName);
}
BuildPipeline.BuildAssetBundles(dirName, BuildAssetBundleOptions.CollectDependencies, BuildTarget.iOS);
UnityEngine.Debug.Log("IOS Finish!");
}
[MenuItem("Tools/CreatAssetBundle for Win")]
static void CreatPCAssetBundleForwINDOWS()
{
string path = "AB";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
UnityEngine.Debug.Log("Windows Finish!");
}
}
將該腳本放入Editor檔案夾下之后,上方選單欄就會出現Toos的選項,
此時在勾選好需要打包的資源后選擇對應的平臺就可以一鍵打包了,比如點擊Windows的打包,等待一會,下方日志就會顯示

此時可以去看其所在的路徑,該腳本Windows的存盤路徑在工程檔案下的AB檔案夾中

可以看到我們的資源成功打包了,下方的texture是我以前設定的另一個包,和上方的jojo無關,每個資源包被打出來后都會有一個同名的manifest檔案,這個檔案記錄了這個資源包中的資源資訊,

可以看到Asset下的兩個資源名就是我們打包時的資源,說明沒有問題,此時打包的作業就此結束,
三、Unity 加載和卸載AssetBundle
加載和卸載直接在腳本中使用相關API即可,下面是一個簡單的小測驗,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ABtest : MonoBehaviour
{
string path = "AB/jojo.czh";//包體的路徑
private AssetBundle asset;//宣告一個AB包
void Update()
{
if (Input.GetKeyDown(KeyCode.L))
{
asset = AssetBundle.LoadFromFile(path);
asset.LoadAsset("jojo");//通過資源名加載單個資源
asset.LoadAsset("Giorno");
//asset,LoadAllAsset() 加載全部資源
Debug.Log("Load AssetBundle");
}
if (Input.GetKeyDown(KeyCode.U))
{
asset.Unload(true);//卸載全部資源
Debug.Log("Unload AssetBundle");
}
}
}
注意:Andriod和IOS的路徑寫法特殊,建議先查閱相關資料,直接寫會出錯,之后如果有時間本人單獨寫一下路徑的注意事項,
將腳本掛載到一個空物體,運行起來,觀察profiler

目前是無操作時的記憶體情況,接著我們點擊L鍵進行讀取:

出現了! jojo.czh包中的兩張圖被加載進了記憶體里,
我們再點擊U鍵進行卸載:

Texture不見了,說明卸載也成功了,
至此,AssetBundle的打包,加載和卸載都已完成,當然其中還有很多的細節沒有說明,本文旨在介紹使用AssetBundle的流程,給剛接觸的朋友一個簡單的了解,如果有問題或是建議請評論或私聊,謝謝!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/258099.html
標籤:其他
上一篇:python抽卡人生游戲
下一篇:Codeforces Round #700 (Div. 2)-B. The Great Hero-題解-一行實作向上取整
