資源打包Assetbundle .


在手游的運營過程中,更新資源是比不可少的。資源管理第一步是資源打包。傳統的打包可以將所有物件制成預設Prefab,打包成場景。今天我們來一起學習官方推薦的Assetbundle,它是Unity(Pro)提供的資源打包策略。利用AssetBundle,可以將幾乎所有的資源都打包封裝,便於客戶端更新下載新的資源。

(轉載請注明原文出處http://blog.csdn.net/janeky/article/details/17652021)

  • 創建AssetBundle

1.創建一個空的Prefab,命名Cube,然后創建一個Cube,將其拉到剛創建好的Prefab
2.新建一個腳本ExportAssetBundles.cs(代碼來自官方文檔),保存在Asset/Editor目錄下

    //在Unity編輯器中添加菜單
    [MenuItem("Assets/Build AssetBundle From Selection")]
    static void ExportResourceRGB2()
    {
        // 打開保存面板,獲得用戶選擇的路徑
        string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "assetbundle");

        if (path.Length != 0)
        {
            // 選擇的要保存的對象
            Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
            //打包
            BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, BuildTarget.StandaloneWindows);
        }
    }

這時我們將看到Asset下面出現Build AssetBundle From Selection和Build Scene
3.選中預設Cube,運行Build AssetBundle From Selection。這時會彈出一個保存框,將其命名為cube.unity3d(這里為了測試方便,放在c盤。實際項目中,我們是需要將他們放在web服務器,供所有客戶端下載更新)
4.新建一個場景scene1.unity,上面放置幾個模型,然后保存

5.選中該場景,在之前的ExportAssetBundles.cs腳本中添加打包場景的函數,運行Assets->Build Scene,保存為scene1.unity3d(這里為了測試方便,也放在c盤)

 

    [MenuItem("Assets/Save Scene")]
    static void ExportScene()
    {
          // 打開保存面板,獲得用戶選擇的路徑
        string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");

        if (path.Length != 0)
        {
            // 選擇的要保存的對象
            Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
            string[] scenes = {"Assets/scene1.unity"};
            //打包
            BuildPipeline.BuildPlayer(scenes,path,BuildTarget.StandaloneWindows,BuildOptions.BuildAdditionalStreamedScenes);
        }
    }

注意事項
a.AssetBundle的保存后綴名可以是assetbundle或者unity3d
b.BuildAssetBundle要根據不同的平台單獨打包,BuildTarget參數指定平台,如果不指定,默認的webplayer

  • 加載AssetBundle

我們通過一個簡單的代碼來演示如何加載assetbundle,包括加載普通asset和場景。

 

using System;
using UnityEngine;
using System.Collections;

public class Load: MonoBehaviour
{
    private string BundleURL = "file:///C:/cube.assetbundle";
    private string SceneURL = "file:///C:/scene1.unity3d";

    void Start()
    {
        //BundleURL = "file//"+Application.dataPath+"/cube.assetbundle";
        Debug.Log(BundleURL);
        StartCoroutine(DownloadAssetAndScene());
    }

    IEnumerator DownloadAssetAndScene()
    {
        //下載assetbundle,加載Cube
        using (WWW asset = new WWW(BundleURL))
        {
            yield return asset;
            AssetBundle bundle = asset.assetBundle;
            Instantiate(bundle.Load("Cube"));
            bundle.Unload(false);
            yield return new WaitForSeconds(5);
        }
        //下載場景,加載場景
        using (WWW scene = new WWW(SceneURL))
        {
            yield return scene;
            AssetBundle bundle = scene.assetBundle;
            Application.LoadLevel("scene1");
        }
       
    }
}

注意事項
a.LoadFromCacheOrDownload 可以指定版本,如果本地版本是新的,將不會從服務器讀取
b.如果是多個資源打包在一起,我們要通過bundle.Load(),加載特定的資源
c.掛載在模型上的腳本也可以一起打包,但是保證腳本在原目錄也要存在,否則加載出來無法運行。關於如何更新腳本,我將放在以后的章節中闡述。

  • AssetBundle依賴關系

如果一個公共對象被多個對象依賴,我們打包的時候,可以有兩種選取。一種是比較省事的,就是將這個公共對象打包到每個對象中。這樣會有很多弊端:內存被浪費了;加入公共對象改變了,每個依賴對象都得重新打包。AssetBundle提供了依賴關系打包。我們通過一個簡單的例子來學習

 

//啟用交叉引用,用於所有跟隨的資源包文件,直到我們調用PopAssetDependencies
    BuildPipeline.PushAssetDependencies();

    var options =
        BuildAssetBundleOptions.CollectDependencies |
        BuildAssetBundleOptions.CompleteAssets;


    //所有后續資源將共享這一資源包中的內容,由你來確保共享的資源包是否在其他資源載入之前載入
    BuildPipeline.BuildAssetBundle(
        AssetDatabase.LoadMainAssetAtPath("assets/artwork/lerpzuv.tif"),
        null, "Shared.unity3d", options);


        //這個文件將共享這些資源,但是后續的資源包將無法繼續共享它
    BuildPipeline.PushAssetDependencies();
    BuildPipeline.BuildAssetBundle(
        AssetDatabase.LoadMainAssetAtPath("Assets/Artwork/Lerpz.fbx"),
        null, "Lerpz.unity3d", options);
    BuildPipeline.PopAssetDependencies();


    這個文件將共享這些資源,但是后續的資源包將無法繼續共享它
    BuildPipeline.PushAssetDependencies();
    BuildPipeline.BuildAssetBundle(
        AssetDatabase.LoadMainAssetAtPath("Assets/Artwork/explosive guitex.prefab"),
        null, "explosive.unity3d", options);
    BuildPipeline.PopAssetDependencies();


    BuildPipeline.PopAssetDependencies();

我們在程序加載的時候必須保證先加載公共對象。否則,只能是在各個對象加載成功后,再通過程序手動添加進來,比較繁瑣。在實際項目中,由於是團隊開發,對象間的依賴關系通常會比較凌亂,最好在開發周期就定好相關的規范約束,方便管理。

  • 總結

這一節的內容偏實際操作,官方文檔和雨松的blog中已經有更加詳細介紹。如果大家還有不明白的地方,可以結合文檔再實際操作一下。后面的章節,我將花更多的時間介紹核心的內容:資源的增量更新,和代碼程序的更新

 

  • 源碼

 

http://pan.baidu.com/s/1i3BOAPn

 

  • 參考資料

 

1.http://www.xuanyusong.com/
2.http://game.ceeger.com/Manual/DownloadingAssetBundles.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM