Unity5.x新的AssetBundle機(jī)制01——構(gòu)建

1前言

unity_cover.png

Unity在5.0中推出了新的AssetBundle管理機(jī)制,本文將對此進(jìn)行介紹并完成簡單實(shí)踐。

2什么是AssetBundles?

AssetBundles是一堆從你的Unity項(xiàng)目中導(dǎo)出的文件,這些文件以特殊的格式組織,并能夠在你的項(xiàng)目中按需加載。AssetBundles通過后綴名支持所有Unity支持的文件類型。如果你想包含一些自定義的二進(jìn)制數(shù)據(jù),可以將使用.bytes作為后綴。Unity在導(dǎo)入時將把此類文件當(dāng)作一個TextAsset。

3工作流

3.1創(chuàng)建

開發(fā)階段,開發(fā)者將AssetBundles上傳至至服務(wù)器


這就有兩個階段:

3.1.1你需要通過編輯器構(gòu)建AssetBundles。

3.1.2上傳至服務(wù)器。

3.2使用

程序運(yùn)行階段,客戶端從服務(wù)器下載AssetBundles,并按需操作每個AssetBundle中的資源。


即如下兩個階段:

3.2.1客戶端運(yùn)行時下載AssetBundles。

3.2.2從AssetBundles中加載對象。

4實(shí)踐

4.1構(gòu)建AssetBundles

4.1.1準(zhǔn)備工作

我們事先準(zhǔn)備一些簡單的資源:
簡單的創(chuàng)建兩個矩形,兩個球形。

create_obj.png

選中一個Cube,在Inspector視口中的下方,有一個預(yù)覽窗口。在預(yù)覽窗口中,我們可以新建并指定資源將被打包進(jìn)的AssetBundle(默認(rèn)是None,這表示該資源不被打包進(jìn)任何AssetBundle,而是被打包進(jìn)主工程本身),如圖:

new_assetbundle.png

圖中有兩個下拉框,左邊的用于指定AssetBundle的名字,后邊的用于指定AssetBundle Variants的名字(后文介紹)。

我們新建一個名為shape/cube的AssetBundle,將兩個Cube資源指定到其中。新建一個名為shape/sphere的AssetBundle,將兩個Sphere資源指定其中(對應(yīng)的meta文件也將被指定到該AssetBundle)。AssetBundle的命名必須小寫(即便寫成大寫也會被轉(zhuǎn)換成小寫),并且支持'/',這樣可以在界面上開辟子目錄。如圖:

assetbundle_name.png

如果你創(chuàng)建了一些沒有指定任何資源的AssetBundle,Remove Unused Names 按鈕可以將其全部清除。

4.1.2導(dǎo)出AssetBundle

我們在項(xiàng)目中新建Editor文件夾,并在其中創(chuàng)建一個腳本:

BuildAssetBungle.cs

using UnityEditor;

public class BuildAssetBundle
{

    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        BuildPipeline.BuildAssetBundles("Assets/MyAssetBundles");
    }
}

這樣在菜單欄中,就會創(chuàng)建對應(yīng)的按鈕讓我們執(zhí)行構(gòu)建操作。如圖:

build_btn.png

在點(diǎn)擊之前需要在Assets目錄下創(chuàng)建AssetBundles文件夾。點(diǎn)擊之后將彈出一個進(jìn)度條對話框,完成后就生成了對應(yīng)的AssetBundles:

assetbundles.png

可以看到這些AssetBundles是按照我們此前在編輯器中新建的AssetBundle的目錄結(jié)構(gòu)生成的。并且有這相關(guān)的以.manifest為后綴的文件。一個manifest文件是描述了對應(yīng)資源文件的循環(huán)冗余碼(CRC)和資源依賴(asset dependencies)的文本文件。

另外,你還會看到在MyAssetBundles文件夾下有一個MyAssetBundles文件和對應(yīng)的manifest文件。每當(dāng)構(gòu)建AssetBundles時,就會創(chuàng)建這兩個文件。

4.1.3其他工具

添加下面這個腳本Editor中,可以使你獲取所有AssetBundles的名字:

GetAssetBundleNames.cs:

using UnityEditor;
using UnityEngine;

public class GetAssetBundleNames
{

    [MenuItem("Assets/Get AssetBundle names")]
    static void GetNames()
    {
        var names = AssetDatabase.GetAllAssetBundleNames();
        foreach (var name in names)
            Debug.Log("AssetBundle: " + name);
    }

}

添加下面這個腳本Editor中,可以使你在改變AssetBundle時得到通知:

MyPostprocessor.cs:

using UnityEngine;
using UnityEditor;

public class MyPostprocessor : AssetPostprocessor
{

    void OnPostprocessAssetbundleNameChanged(string path,
            string previous, string next)
    {
        Debug.Log("AB: " + path + " old: " + previous + " new: " + next);
    }
}

4.1.4AssetBundle Variants

AssetBundle Variants是Unity5的新特性。你可以將兩組不同的資源指定為同一個AssetBundle但是指定不同的Variants,這樣,你可以根據(jù)平臺的不同加載不同的資源(例如支持高清資源的設(shè)備加載hd的Variants,不支持高清資源的設(shè)備加載sd的Variants)??墒鞘褂?a target="_blank" rel="nofollow">AssetImporter.assetBundleVariant設(shè)置Variants。

4.1.5編碼建議

1.標(biāo)記AssetBundle

使用AssetImporter.assetBundleName來設(shè)置AssetBundle的名字。

2.使用函數(shù)BuildPipeline.BuildAssetBundles()構(gòu)建AssetBundle

函數(shù)原型:

public static AssetBundleManifest BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions = BuildAssetBundleOptions.None, BuildTarget targetPlatform = BuildTarget.WebPlayer);

3.操縱Asset database中的AssetBundle names接口:

AssetDatabase.GetAllAssetBundleNames()

AssetDatabase.GetAssetPathsFromAssetBundle

AssetDatabase.RemoveAssetBundleName()

AssetDatabase.GetUnusedAssetBundleNames()

AssetDatabase.RemoveUnusedAssetBundleNames()

AssetPostProcessor.OnPostprocessAssetbundleNameChanged

4.構(gòu)建AssetBundle選項(xiàng)(BuildAssetBundleOptions)

CollectDependenciesDeterministicAssetBundle 選項(xiàng)總是啟用的。

CompleteAssets 如果我們總是從assets開始而不是objects,該項(xiàng)將被忽略。它默認(rèn)是完整的。

ForceRebuildAssetBundle 即便你沒有改變資源,但是通過設(shè)置該項(xiàng)你可以強(qiáng)制從新構(gòu)建資源。

IngoreTypeTreeChanges 即便你改變了type tree你也可以通過設(shè)置該項(xiàng)忽略掉。

DisableWriteTypeTreeIngoreTypeTreeChanges是沖突的,如果你將type tree設(shè)置為不啟用則無法忽略。

5.Manifest file

每個AssetBundle都有一個manifest文件,包含如下信息:

CRC(循環(huán)冗余碼)
資源文件的哈希碼。在該AssetBundle中的所有資源有一個單一的哈希碼,用于檢查增量的構(gòu)建。

Type tree哈希碼。在該AssetBundle中所有類型有一個單一的哈希碼,用于檢查增量的構(gòu)建。

Class types。該AssetBundle中所有的類類型。當(dāng)為type tree做增量構(gòu)建檢查時將產(chǎn)生一個新的哈希碼。

Asset names。該AssetBundle中所有明確包含的資源名字。依賴的AssetBundle的名字。依賴于該AssetBundle的其他AssetBundles。
manifest文件僅用于檢查增量構(gòu)建,運(yùn)行時不需要。因此不需要打包進(jìn)正式發(fā)行的游戲中。

6.Single manifest file

一個單一的manifest文件一般包含以下信息:
所有的AssetBundles。
所有AssetBundles的依賴信息。

7.Single manifest AssetBundle

一個AssetBundleManifest對象有如下APIs:

GetAllAssetBundles() 返回本次構(gòu)建的所有AssetBundles名字。

GetDirectDependencies() 返回直接依賴的AssetBundle名字。

GetAllDependencies() 返回所有依賴的AssetBundle名字。

GetAssetBundleHash(string) 返回指定的AssetBundle的哈希碼。

GetAllAssetBundlesWithVariant() 返回所有AssetBundles帶Variant的名字。

8.AssetBundle 加載APIs

Unity5.x改為如下APIs:

AssetBundle.GetAllAssetNames() 返回該AssetBundle中的所有資源名。

AssetBundle.GetAllScenePaths() 如果該AssetBundle是一個場景文件,返回該場景中所有資源的路徑。

AssetBundle.LoadAsset() 從該AssetBundle中加載資源。

AssetBundle.LoadAllAssets() 從該AssetBundle中加載所有資源。

AssetBundle.LoadAssetWithSubAssets() 通過名字加載該AssetBundle中的資源及子資源。
還有對應(yīng)的異步接口也有提供。
組件類型不在返回了,你可以在加載了GameObject之后從其獲取。

9.Typetrees

每個AssetBundle中都默認(rèn)寫入了一個typetree。只有Metro(Windows Store Apps)例外,它有不同的序列化方案。


參考鏈接:

http://docs.unity3d.com/Manual/AssetBundlesIntro.html

http://docs.unity3d.com/Manual/BuildingAssetBundles.html

http://docs.unity3d.com/ScriptReference/BuildPipeline.BuildAssetBundles.html


下一篇:
Unity5.x新的AssetBundle機(jī)制02——壓縮

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容