AssetBundle是一個存檔文件,其中包含平臺在運行時加載的特定資產(模型,紋理,預製,音頻剪輯,甚至整個場景)。AssetBundles能夠表示彼此之間的依賴關係;例如AssetBundle A中的一個材質能夠引用AssetBundle B中的一個紋理。爲了經過網絡進行有效的傳遞,能夠根據用例要求,選擇內置算法(LZMA和LZ4)來對AssetBundles進行壓縮。
AssetBundles可用於可下載內容(DLC),減小初始安裝大小,加載爲最終用戶平臺優化的資產,並下降運行時內存壓力。html
好的問題,實際上「AssetBundle」能夠指兩個不一樣但有關的事情。git
第一個是磁盤上的實際文件。咱們把這叫作AssetBundle存檔,或在本文檔只是短時間檔案。存檔能夠被認爲是一個容器,就像一個文件夾,在其中保存其餘文件。這些附加文件包括兩種類型:序列化文件和資源文件。序列化的文件將您的資產分紅各自的對象,並寫入這個文件。資源文件只是存儲在某些資產(紋理和音頻)中的二進制數據塊,容許咱們在另外一個線程上有效地將其從磁盤加載到內存。github
第二個是您經過代碼從特定存檔加載資源的實際的AssetBundle對象。此對象包含您添加到此存檔的資源的全部文件路徑的映射到屬於該資產的對象,該對象在須要時須要加載。(This object contains a map of all the file paths of the assets you added to this archive to the objects that belong to that asset that need to be loaded when you ask for it.)算法
要開始使用AssetBundles,請按照下列步驟操做。有關每一個工做流程的更詳細信息,請參見本部分文檔中的其餘頁面。網絡
要將一個給定的資產分配給一個AssetBundle,請按照下列步驟操做:優化
要了解有關AssetBundle分配和隨附策略的更多信息,請參閱Preparing Assets for AssetBundles的文檔。網站
在項目中的Assets文件夾下建立一個名爲Editor的文件夾,並在文件夾中放置如下內容的腳本:ui
using UnityEditor; public class CreateAssetBundles { [MenuItem("Assets/Build AssetBundles")] static void BuildAllAssetBundles() { string assetBundleDirectory = "Assets/AssetBundles"; if(!Directory.Exists(assetBundleDirectory) { Directory.CreateDirectory(assetBundleDirectory); } BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.Standalone); } }
該腳本將在Assets菜單的底部建立一個名爲「Build AssetBundles」的菜單項,該菜單項將執行與該標記關聯的功能中的代碼。當您單擊Build AssetBundles時,進度條將顯示一個構建對話框。這將使那些用AssetBundle名稱標記的全部資產打包進同一個文件,並將它們放在由assetBundleDirectory定義的路徑上的文件夾中。this
有關此代碼正在執行的更多詳細信息,請參閱有關Building AssetBundles的文檔。線程
這一步對於每一個用戶都是獨一無二的,而不是一步一步能夠告訴你如何作。若是您打算將AssetBundles上傳到第三方託管網站,請在此處進行。若是您正在嚴格執行本地開發,並打算將全部AssetBundles都放在磁盤上,請跳到下一步。
對於有意從本地存儲加載的用戶,您將對AssetBundles.LoadFromFile API感興趣。看起來像這樣:
public class LoadFromFileExample extends MonoBehaviour { function Start() { var myLoadedAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "myassetBundle")); if (myLoadedAssetBundle == null) { Debug.Log("Failed to load AssetBundle!"); return; } var prefab = myLoadedAssetBundle.LoadAsset.<GameObject>("MyObject"); Instantiate(prefab); } }
LoadFromFile
獲取包文件的路徑。
若是您本身託管AssetBundles而且須要將其下載到遊戲中,那麼您將對UnityWebRequest API感興趣。這裏有一個例子:
IEnumerator InstantiateObject() { string uri = "file:///" + Application.dataPath + "/AssetBundles/" + assetBundleName; UnityEngine.Networking.UnityWebRequest request = UnityEngine.Networking.UnityWebRequest.GetAssetBundle(uri, 0); yield return request.Send(); AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request); GameObject cube = bundle.LoadAsset<GameObject>("Cube"); GameObject sprite = bundle.LoadAsset<GameObject>("Sprite"); Instantiate(cube); Instantiate(sprite); }
GetAssetBundle(string, int)
獲取AssetBundle的位置的uri以及要下載的包的版本。在這個例子中,咱們仍然指向一個本地文件,可是字符串uri能夠指向你託管AssetBundles的任何URL。
UnityWebRequest具備處理AssetBundles的特定句柄(DownloadHandlerAssetBundle),DownloadHandlerAssetBundle從請求中獲取AssetBundle。
不管使用的方法如何,你如今均可以訪問AssetBundle對象。從該對象中加載資源,你將須要使用LoadAsset<T>(string)
方法,該方法中泛型類型T表示你所要加載的Asset的類型,方法參數爲所要加載的Asset對象的名稱。這將返回您從AssetBundle加載的任何對象。您能夠像Unity中的任何對象同樣使用這些返回的對象。例如,若是要在場景中建立一個GameObject,則只須要調用Instantiate(gameObjectFromAssetBundle)。
有關加載AssetBundles的API的更多信息,請參閱Using AssetBundles Natively文檔。
原文連接:
同系列文章
本文做者: Sheh偉偉
本文連接: http://davidsheh.github.io/2017/07/14/「翻譯」Unity中的AssetBundle詳解(一)/
版權聲明: 本博客全部文章除特別聲明外,均採用 CC BY-NC-SA 3.0 許可協議。轉載請註明出處!