[Unity3d]打包Assetbundle並加載

由於我們要將模型資源放在遠程的服務器端,但如果直接放fbx模型是不可以加載的,所以我們可以將fbx做成預設或者是直接將其打包成assetbundle格式的,然後通過www來加載獲取。


說下使用方法:

1、把附件腳本放到工程文件夾下的...\Assets\Editor文件夾下。

2、在工程的Project視圖裏點擊想要保存的資源,網絡上推薦的是Prefab,右鍵點擊,選擇菜單裏最下面的兩個選項任意一個都可以,第一個選項對應的自定義屬性有一個過期了,但是不影響使用。

3、指定文件的構建路徑和文件後綴,後綴無所謂。

4、推薦製造做法:

任何形式的資源都可以,包括集合資源,比如創建一個空的GameObject,把所有想要關聯的其他GameObject都拖進去,然後在project視圖裏創建一個prefab,將這個集合資源GameObject拖進去作爲一個prefab。執行上面的第2、3步驟。


官方的講解:http://game.ceeger.com/Script/BuildPipeline/BuildPipeline.BuildAssetBundle.html


1.首先要講一下不同平臺下的一個StreamingAssets路徑,這是不同的。

        //不同平臺下StreamingAssets的路徑是不同的,這裏需要注意一下。  
        public static readonly string PathURL =  
#if UNITY_ANDROID   //安卓  
        "jar:file://" + Application.dataPath + "!/assets/";  
#elif UNITY_IPHONE  //iPhone  
        Application.dataPath + "/Raw/";  
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR  //windows平臺和web平臺  
    "file://" + Application.dataPath + "/StreamingAssets/";  
#else  
        string.Empty;  
#endif  

這就獲取到了不同平臺的一個路徑,我們可以將打包的文件放在這些路徑下,然後再從這路徑去讀取資源。

2.關於打包assetbundle的腳本

using UnityEngine;  
using System.Collections;  
using UnityEditor;  
  
public class Test : Editor  
{  
    //打包單個  
    [MenuItem("Custom Editor/Create AssetBunldes Main")]  
    static void CreateAssetBunldesMain ()  
    {  
        //獲取在Project視圖中選擇的所有遊戲對象  
        Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);  
   
        //遍歷所有的遊戲對象  
        foreach (Object obj in SelectedAsset)   
        {  
            //本地測試:建議最後將Assetbundle放在StreamingAssets文件夾下,如果沒有就創建一個,因爲移動平臺下只能讀取這個路徑  
            //StreamingAssets是隻讀路徑,不能寫入  
            //服務器下載:就不需要放在這裏,服務器上客戶端用www類進行下載。  
            string targetPath = Application.dataPath + "/StreamingAssets/" + obj.name + ".assetbundle";  
            if (BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)) {  
                Debug.Log(obj.name +"資源打包成功");  
            }   
            else   
            {  
                Debug.Log(obj.name +"資源打包失敗");  
            }  
        }  
        //刷新編輯器  
        AssetDatabase.Refresh ();     
          
    }  
      
    [MenuItem("Custom Editor/Create AssetBunldes ALL")]  
    static void CreateAssetBunldesALL ()  
    {  
          
        Caching.CleanCache ();  
   
  
        string Path = Application.dataPath + "/StreamingAssets/ALL.assetbundle";  
   
          
        Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);  
   
        foreach (Object obj in SelectedAsset)   
        {  
            Debug.Log ("Create AssetBunldes name :" + obj);  
        }  
          
        //這裏注意第二個參數就行  
        if (BuildPipeline.BuildAssetBundle (null, SelectedAsset, Path, BuildAssetBundleOptions.CollectDependencies)) {  
            AssetDatabase.Refresh ();  
        } else {  
              
        }  
    }  
      
    [MenuItem("Custom Editor/Create Scene")]  
    static void CreateSceneALL ()  
    {  
        //清空一下緩存  
        Caching.CleanCache();  
        string Path = Application.dataPath + "/MyScene.unity3d";  
        string  []levels = {"Assets/Level.unity"};  
        //打包場景  
        BuildPipeline.BuildPlayer( levels, Path,BuildTarget.WebPlayer, BuildOptions.BuildAdditionalStreamedScenes);  
        AssetDatabase.Refresh ();  
    }  
      
}  

前提要新手動創建一個StreamingAssets文件夾

3.讀取資源,這裏只舉例從本地讀取,跟從網絡讀取是一樣的,可以參考官方文檔:

http://game.ceeger.com/Script/WWW/WWW.html

using UnityEngine;  
using System.Collections;  
  
public class RunScript : MonoBehaviour  
{  
      
  
        //不同平臺下StreamingAssets的路徑是不同的,這裏需要注意一下。  
        public static readonly string PathURL =  
#if UNITY_ANDROID  
        "jar:file://" + Application.dataPath + "!/assets/";  
#elif UNITY_IPHONE  
        Application.dataPath + "/Raw/";  
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR  
    "file://" + Application.dataPath + "/StreamingAssets/";  
#else  
        string.Empty;  
#endif  
      
    void OnGUI()  
    {  
        if(GUILayout.Button("Main Assetbundle"))  
        {  
            //StartCoroutine(LoadMainGameObject(PathURL + "Prefab0.assetbundle"));  
            //StartCoroutine(LoadMainGameObject(PathURL +  "Prefab1.assetbundle"));  
          
            StartCoroutine(LoadMainCacheGameObject(PathURL + "Prefab0.assetbundle"));  
            StartCoroutine(LoadMainCacheGameObject(PathURL +  "Prefab1.assetbundle"));  
        }  
          
        if(GUILayout.Button("ALL Assetbundle"))  
        {  
            StartCoroutine(LoadALLGameObject(PathURL + "ALL.assetbundle"));  
        }  
          
        if(GUILayout.Button("Open Scene"))  
        {  
            StartCoroutine(LoadScene());  
        }  
          
    }  
      
    //讀取一個資源  
      
    private IEnumerator LoadMainGameObject(string path)  
    {  
         WWW bundle = new WWW(path);  
           
         yield return bundle;  
           
         //加載到遊戲中  
         yield return Instantiate(bundle.assetBundle.mainAsset);  
           
         bundle.assetBundle.Unload(false);  
    }  
      
    //讀取全部資源  
      
    private IEnumerator LoadALLGameObject(string path)  
    {  
         WWW bundle = new WWW(path);  
           
         yield return bundle;  
           
         //通過Prefab的名稱把他們都讀取出來  
         Object  obj0 =  bundle.assetBundle.Load("Prefab0");  
         Object  obj1 =  bundle.assetBundle.Load("Prefab1");  
          
         //加載到遊戲中     
         yield return Instantiate(obj0);  
         yield return Instantiate(obj1);  
         bundle.assetBundle.Unload(false);  
    }  
      
    private IEnumerator LoadMainCacheGameObject(string path)  
    {  
         WWW bundle = WWW.LoadFromCacheOrDownload(path,5);  
           
         yield return bundle;  
           
         //加載到遊戲中  
         yield return Instantiate(bundle.assetBundle.mainAsset);  
           
         bundle.assetBundle.Unload(false);  
    }  
      
      
    private IEnumerator LoadScene()  
    {  
         WWW download = WWW.LoadFromCacheOrDownload ("file://"+Application.dataPath + "/MyScene.unity3d", 1);  
              
          yield return download;  
          var bundle = download.assetBundle;  
          Application.LoadLevel ("Level");  
    }  
}  

如果assetbundle文件放在服務器端,直接用www.loadfromcacheordownload()通過版本來控制是否從服務器下載並保存到本地。本人親自測試,這個方法是能下載到本地的,至於下載在本地哪兒我就不太清楚了,我猜測應該是存在沙盒文件下(移動開發者的朋友應該知道),當然也可以自己來做版本控制,那樣更靈活,並且擺脫www.loadfromcacheordownload()方法的束縛,貌似這個方法存貯文件是有空間大小限制的,據說是50M,本人沒有親自考證,後期我會自己做一個版本控制!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章