2017年4月27日 星期四

[Unity]AssetBundleManager & AssetBundleGraphTool 之整合使用

AssetBundle Manager是官方提供的bundle管理器, 能夠方便的讀取, 以及模擬測試bundle, 可從Asset Store免費下載(https://www.assetstore.unity3d.com/en/#!/content/45836)


AssetBundleGraphTool 則是Unity日本開發的圖形化打包工具, 能夠很輕鬆的設計自動化打包流程, 也是開源免費(https://bitbucket.org/Unity-Technologies/assetbundlegraphtool)


AssetBundle Manager有附帶快速打包的工具, 但我們必須為要打包的物件設定包名(甚至variants)

這部分可以利用檔案位置以及命名原則來以腳本自動化處理, 但要自己處理邏輯與維護仍是麻煩


因此這邊推薦讀取的部分使用AssetBundle Manager, 打包的部分使用AssetBundleGraphTool, 這樣打包可以方便快速的設定, 且能夠滿足大部分的自動化需求(ex: 自動物件分類、自動更改import settings、自動創建prefab, etc...)
>>>>>>>>>
本篇將藉由製作一個簡單的範例來說明兩者的使用與整合, 內容涵括:

  • 使用AssetBundleGraphTool建立一個自動化打包設定
  • 在本地端進行輸出包的測試
  • variants測試


本篇使用的環境是OS: Windows7 SP1, Unity:5.5.3
理論上本篇內容在Unity5.4以上的5.X版本是通用的
1.建立測試用物件
1-1.首先開啟一個新的project, 將AssetBundle Manager以及AssetBundleGraphTool導入其中
1-2.創建"Test"資料夾, 並在其下創建資料夾"Material"、"Prefab"、"Scripts"、"Texture_v1"、"Texture_v2"
1-3.找兩張不一樣的圖分別放進"Texture_v1", "Texture_v2"資料夾, 將其皆命名為"UnityLogo"(這是為了之後的variants)
1-4.點選"Material"資料夾, 在裡面創建一個Material, 並將其命名為"Cube_Material"
1-5.將"Cube_Material"的shader設定為Unlit/Texture
1-6.按Select, 選擇步驟3所放進去的"UnityLogo", "Texture_v1"或"Texture_v2"裡的皆可
1-7.於Hierarchy面板創建一個Cube
1-8.將步驟4創建的"Cube_Material"指給Cube
1-9.將Cube拖進"Prefab"資料夾裡, 成為一個prefab, 然後刪掉場景裡的Cube
以上, 範例用的物件準備完成
>>>>>>
2.用AssetBundleGraphTool建置打包流程 & 輸出bundle包
2-1.點選Window->AssetBundleGraph->Open Graph Editor , 開啟編輯介面
2-2.在編輯介面中按滑鼠右鍵, 點選Create Loader Node, 產生一個Loader
=>
2-3.Loader是打包流程的進入點, 在Loader的Inspector上設定Load Path, 此為要包的資源的根目錄
以本範例而言, 就是"Test"資料夾, 因此輸入test(好像會自動轉小寫)
2-4.在編輯介面中按滑鼠右鍵, 點選Create Filter Node, 產生一個Filter
=>
2-5.Filter為篩選器, 可以用命名原則以及物件類型來篩選輸出的物件, 在Inspector面板中按"+"來增加篩選設定
在本範例中, 我們僅做物件類型的篩選
如下圖增加UnityEditor.TextureImporter、UnityEditor.Material、UnityEditor.GameObject
條件設定完成後, Filter會變成如下圖, 可以從圖形介面中直接看到所設定的條件
2-6.點選Loader上的接點, 拖曳至Filter的左邊, 便會出現一條線相連, 這表示兩個流程已建立連結
=>
P.S.點選接線上的數字, 可以在Inspector面板上看到此連線所包含的物件
=>
2-7.在編輯介面中按滑鼠右鍵, 點選Create BundleConfig Node, 產生三個BundleConfig
=>
2-8.BundleConfig是輸出包的名稱與variants設定器
點選BundleConfig, 分別在Inspector中將其Node Name改成"Texture"、"Material"、與"Prefab"
更改完成後會新名字也會反應在圖形介面中
=>
2-9.將"Material"與"Prefab"的Bundle Name Template分別更改為"material"與"prefab"
這個Bundle Name Template是指輸出的bundle名稱模板, 像我們設定了"material"與"prefab", 之後就會輸出名為"material"與"prefab"的bundle檔與manifest
Bundle Name Template可以用"*"做自動變數名稱, 但本範例只做單純的指名
"Texture"要做variants分類, 待會會特別處理
2-10.點選Filter右邊的點, 如圖將其拖曳至對應的BundleConfig左邊點
這樣表示將Filter篩選的檔案輸出給連線的BundleConfig
一樣點選接線上的數字可以在Inspector面板上看到該連線所包含的物件
接下來我們要為"Texture"設定連線, 因為"Texture"要做variants, 其下包含了同名但不同路徑的物件, 因此此範例會使用Grouping來做自動分類
2-11.在編輯介面中按滑鼠右鍵, 點選Create Grouping Node, 產生一個Grouping
=>
2-12.Grouping是群組器, 它可以依照設定的命名原則對輸入的物件作群組分類
在Inspector中將其Grouping Keyword設定為"Texture_v*"
*為萬用字元, 因為我們先前建立了"Texture_v1"&"Texture_v2"這兩個資料夾, 因此我們的分類命名原則是 Texture_v + 變數字, 以此用"Texture_v*"表示
2-13.擊點Texture, 至Inspector上勾選Use input group as variants, 這表示這個BundleConfig的variants設定將使用與他相連的group設定
然後將Bundle Name Template改為"texture"
2-15.將Filter的TextureImporter點連到Grouping左邊, Grouping右邊的點連到Texture左邊
我們可以看到Grouping與Texture的連線出現一個"2:2", 這表示 "總共2個物件":"2個群組"
點選其可以在Inspector面板上看到該連線所包含的物件與群組分類
2-16.在編輯介面中按滑鼠右鍵, 點選Create BundleBuilder Node, 產生一個BundleBuilder
BundleBuilder是要輸出的bundle資料設定, 我們可以在其Inspector勾選想要的設定, 例如不壓縮(Uncompressed AssetBundle)、不寫入TypeTree(Disable Write TypeTree)等等......
此範例中我們不用變更任何設定
2-17.將所有BundleConfig右邊的點連至BundleBuilder的左邊
2-18.在編輯介面中按滑鼠右鍵, 點選Create Exporter Node, 產生一個Exporter
2-19.Exporter是bundle檔的輸出相關設定
在Inspector中將其Export Option設定成"Automatically Create If No Export Directory Found", 這表示輸出時如果找不到我們設定的資料夾, 將會自動創建一個
在Inspector中將其Export Path欄位輸入"Bundle", 這個欄位是我們要輸出到的資料夾名稱, 其根目錄即為本專案的目錄(Assets資料夾的上一個目錄)
2-20.將BundleBuilder的右邊與Export相連
這樣自動化流程就算完成了, 完整的流程圖應該如下
2-21.點選編輯介面右上方的Build即可打包、輸出bundle
輸出後包會在專案目錄下的Bundle資料夾裡, 打開後會看到一個"Windows"資料夾, 而所有輸出的bundle檔就在裡面
這裡值得一提的是, 大部分的包名與manifest都與我們在BundleConfig設定的一致, 但texture的部分與我們原本設置的不同, 成了texture.1與texture.2
這是因為我們的texture是套用Grouing的命名原則來做variant分名的關係
"Windows"資料夾此為工具依所設定的輸出平台自動建置的資料夾, 因為本範例的輸出平台是使用預設的Windows Standalone, 因此會輸出至此
如果想要變跟輸出平台, 可點選編輯介面右上Platform與Build的中間來進行切換
以上, 自動建置流程與輸出完成
>>>>>>
3.在本地進行Bundle讀取測試與Variants切換
3-1.回到Unity, 點選Assets->AssetBundles->Simulation Mode, 將其有打勾的狀態點掉
這麼做是因為使用AssetBundleGraphTool打包bundle並不會在原物件上設定其包名與variants, 因此Simulation Mode是無效的(抓不到任何東西), 必須直接讀取本地端bundle檔來測試
3-2.打開AssetBundleManager/Resources/AssetBundleServerURL.bytes(可以用筆記本或Visual Studio開)
將其內容更改成file://"Bundle的資料夾位置"
例如我的Bundle資料夾在C:/Project/test/BundleTest_self/Bundle/, 因此就改為
3-3.在Scripts資料夾裡創建一個C# Script, 將其命名為"TestLoder"
3-4.打開TestLoder, 將其內容換至如下:

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


public class TestLoder : MonoBehaviour
{
    [SerializeField]
    private string[] variants;

    private IEnumerator Start()
    {
        //初始化bundle下載路徑
        AssetBundleManager.SetDevelopmentAssetBundleServer();

        //初始化AssetBundleManager
        var request = AssetBundleManager.Initialize();

        if (request != null)
            yield return StartCoroutine(request);

        //設定variants
        AssetBundleManager.ActiveVariants = variants;
        //讀取"prefab"這個bundle中的Cube
        AssetBundleLoadAssetOperation loadRequest = AssetBundleManager.LoadAssetAsync("prefab", "Cube", typeof(GameObject));
        if (loadRequest == null)
            yield break;

        yield return StartCoroutine(loadRequest);

        GameObject prefab = loadRequest.GetAsset();
        //如果讀取成功, 則創建實體
        if (prefab != null)
            GameObject.Instantiate(prefab);

        yield return new WaitForSeconds(5f);
        //釋放"prefab"這個bundle
        AssetBundleManager.UnloadAssetBundle("prefab");

    }
}


3-5.在Hierarchy中點選Main Camera, 在Inspector中點Add Component, 加入我們剛剛創建的TestLoder
3-6.在TestLoder的Variants的Size輸入1, 然後Element的值輸入1
3-7.擊點Play, 我們可以看到場景中生成了一個Cube, 這代表bundle讀取成功
=>
3-8.Stop play mode, 將TestLoder的Variants的Element值改為2, 再執行一次Play, 我們可以看到
Cube上的texture變成Texture_v2資料夾裡的UnityLogo, 這表示variants切換成功了
=> => =>
以上


>>>>>>
後記:
Unity自5版之後bundle的打包流程已簡化很多, 如今官方又提供了AssetBundleGraphTool與AssetBundle Manager這兩個工具來簡化打包與讀取的流程, 讓我們作業更加方便了~


希望這篇能對入bundle坑的朋友們有所幫助=w=


P.S.寫成網誌好麻煩阿, 要截圖、排版什麼的......下次還是錄影好了(懶  _(:3 」∠ )_

1 則留言: