Unity3d進階學習(5)-- AssetBundle

一、AssetBundle定義和作用(後面簡稱AB)

官方介紹:https://docs.unity3d.com/Manual/AssetBundlesIntro.html

  1. AssetBundle是一個壓縮包包含模型、貼圖、預製體、聲音、甚至整個場景,可以在遊戲運行時被加載(熱更);
  2. AssetBundle自身保存着互相的依賴關係(模型包依賴貼圖包);
  3. 壓縮包可以使用LZMA和LZ4壓縮算法,減少包大小,更快的進行網絡傳輸
  4. 把一些可以下載內容放在AssetBundle裏面,可以減少安裝包的大小

二、什麼是AssetBundle

可歸爲兩點

  1. 它是一個存在於硬盤上的文件。可以稱之爲壓縮包。這個壓縮包可以認爲是一個文件夾,裏面包含了多個文件。這些文件可以分爲兩類:serialized file 和 resource files。(序列化文件和源文件)

    serialized file:資源(在遊戲場景中才能被識別如:模型、預製體)被打碎放在一個對象中,最後統一被寫進一個單獨的文件(只有一個
    resource files:某些二進制資源(可直接在電腦上讀取如:圖片、聲音)被單獨保存,方便快速加載

  2. 它是一個AssetBundle對象,我們可以通過代碼從一個特定的壓縮包加載出來的對象。這個對象包含了所有我們當初添加到這個壓縮包裏面的內容,我們可以通過這個對象加載出來使用。

三、AssetBundle使用流程(簡稱AB)

1. 指定資源的AssetBundle屬性

    1. 這兒 (xxx/Cube) == (xxx/cube)   是不區分大小寫的

這裏寫圖片描述

2. 構建AssetBundle包

  1. 根目錄Assets下創建一個Editor文件夾,再創建一個.cs文件使用下方代碼
  2. 點擊菜單欄 Assets -> Build AssetBundles,打包成功後在目錄【Assets/AssetBundles】中就能看到打包好的資源
public class CreateAssetBundles
{
        //相當於是拓展編譯器,在Assets下創建一個Build AssetBundles菜單
    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        //string assetBundleDirectory = Path.Combine(Application.streamingAssetsPath, "AssetBundles");//"Assets/AssetBundles";
        string assetBundleDirectory = "Assets/AssetBundles";
        if (!Directory.Exists(assetBundleDirectory))
        {
            Directory.CreateDirectory(assetBundleDirectory);
        }
        //打包的輸出路徑、打包方式、平臺
        /* BuildAssetBundleOptions
         * BuildAssetBundleOptions.None:使用LZMA算法壓縮,壓縮的包更小,但是加載時間更長。使用之前需要整體解壓。
         *          一旦被解壓,這個包會使用LZ4重新壓縮。使用資源的時候不需要整體解壓。在下載的時候可以使用LZMA算法,
         *          一旦它被下載了之後,它會使用LZ4算法保存到本地上。
         * BuildAssetBundleOptions.UncompressedAssetBundle:不壓縮,包大,加載快
         * BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4壓縮,壓縮率沒有LZMA高,但是我們可以加載指定資源而不用解壓全部。
         */
        BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
    }
}

3. 上傳AB包到服務器
一般都要在本地調試,等遊戲發佈時纔會上次到服務器

4. 加載AB包和包裏面的資源(本地、服務端)
這裏有個知識點協程http://www.cnblogs.com/neverdie/p/3792766.html#_nav_5

public class LoadFromFileExample : MonoBehaviour
{
    //LoadFromFile本地加載  LoadFromMemory加載字節流
    void Start() {
        //如果材質是獨立的一個包,就需要加載材質
        AssetBundle share = AssetBundle.LoadFromFile("Assets/AssetBundles/material.test");
        //加載模型
        AssetBundle ab = AssetBundle.LoadFromFile("Assets/AssetBundles/scene/sphere.test");
        //從內存加載
        //AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes(path));
        if (ab == null)
        {
            Debug.Log("Failed to load AssetBundle!");
            return;
        }
        var prefab = ab.LoadAsset<GameObject>("Sphere");
        GameObject.Instantiate(prefab);
    }


    //UnityWebRequest 服務端或者本地加載
    IEnumerator Start()
    {
        //服務器地址
        string uri = @"http://localhost//AssetBundles/scene/sphere.test";
        //本地地址
        //string uri = @"file://D:/Unity3d/APlan_Siki/09_AssetBundleProject/Assets/AssetBundles/scene/sphere.test";
        UnityEngine.Networking.UnityWebRequest request = UnityEngine.Networking.UnityWebRequest.GetAssetBundle(uri, 0);
        yield return request.Send();//開始下載到緩存
        AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);
        var prefab = ab.LoadAsset<GameObject>("Sphere");
        GameObject.Instantiate(prefab);
    }
}

四、AssetBundle分組策略 (僅供參考)

  1. 邏輯實體分組
    a. 一個UI界面或者所有UI界面一個包(這個界面裏面的貼圖和佈局信息一個包)
    b. 一個角色或者所有角色一個包(這個角色裏面的模型和動畫一個包)
    c. 所有的場景所共享的部分一個包(包括貼圖和模型)
  2. 按照類型分組
    所有聲音資源打成一個包,所有shader打成一個包,所有模型打成一個包,所有材質打成一個包
  3. 按照使用分組
    把在某一時間內使用的所有資源打成一個包。可以按照關卡分,一個關卡所需要的所有資源包括角色、貼圖、聲音等打成一個包。也可以按照場景分,一個場景所需要的資源一個包

  4. 把經常更新的資源放在一個單獨的包裏面,跟不經常更新的包分離

  5. 把需要同時加載的資源放在一個包裏面
  6. 依賴打包:可以把其他包共享的資源放在一個單獨的包裏面(避免同一份資源跟多個依賴的perfab打包在一起)
  7. 把一些需要同時加載的小資源打包成一個包
  8. 如果對於一個同一個資源有兩個版本,可以考慮通過後綴來區分 v1 v2 v3 unity3dv1 unity3dv2

五、通過Manifest文件得到某個包所有的依賴

//AssetBundles的路徑  獲取AssetBundles
AssetBundle assetBundle = AssetBundle.LoadFromFile("Assets/AssetBundles/AssetBundles");
//固定不變   得到AssetBundles.manifest
AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//哪個的包?  得到這個包的所有依賴
string[] dependencies = manifest.GetAllDependencies("scene/sphere.test"); 
foreach (string dependency in dependencies)
{
     AssetBundle.LoadFromFile(Path.Combine("Assets/AssetBundles", dependency));//加載這個包的依賴
}

六、AssetBundle的卸載

  • 卸載有兩個方面: 1.減少內存使用 2.有可能導致丟失
  • 所以什麼時候去卸載資源: 1.關卡切換、場景切換 2.資源沒被用的時候 調用
  • 個別資源怎麼卸載: 1.通過 Resources.UnloadUnusedAssets. 2.場景切換的時候
  • AssetBundle.Unload(true)卸載所有資源,即使有資源被使用着
  • AssetBundle.Unload(false)卸載所有沒用被使用的資源

七、關於文件校驗 CRC MD5 SHA1

  • 相同點
    1. 都是通過對數據進行計算,來生成一個校驗值,該校驗值用來校驗數據的完整性
  • 不同點
    1. 算法不同。CRC採用多項式除法,MD5和SHA1使用的是替換、輪轉等方法;
    2. 校驗值的長度不同。CRC校驗位的長度跟其多項式有關係,一般爲16位或32位;MD5是16個字節(128位);SHA1是20個字節(160位);
    3. 校驗值的稱呼不同。CRC一般叫做CRC值;MD5和SHA1一般叫做哈希值(Hash)或散列值;
    4. 安全性不同。這裏的安全性是指檢錯的能力(數據有誤,但生成的校驗值確和原來一樣,則檢錯能力低),即數據的錯誤能通過校驗位檢測出來。CRC的安全性跟多項式有很大關係,相對於MD5和SHA1要弱很多;MD5的安全性很高,不過大概在04年的時候被山東大學的王小云破解了;SHA1的安全性最高。
    5. 效率不同,CRC的計算效率很高;MD5和SHA1比較慢。
    6. 用途不同。CRC一般用作通信數據的校驗;MD5和SHA1用於安全(Security)領域,比如文件校驗、數字簽名等。

八、AssetBundles瀏覽工具

官網介紹:https://docs.unity3d.com/Manual/AssetBundles-Browser.html
工具Git地址:https://github.com/Unity-Technologies/AssetBundles-Browser
將Editor導入我們的工程,然後點擊 Window–>AssetBundle Browser 就會彈出工具界面,可以對打包的資源一目瞭然。


發佈了39 篇原創文章 · 獲贊 11 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章