Unity3d之AssetBundle打包與讀取
一、建立Assetbundle
在Unity3D開發的遊戲中,無論模型,音訊,還是圖片等,我們都做成Prefab,然後打包成Assetbundle,方便我們後面的使用,來達到資源的更新。
一個Assetbundle可以打包一個模型(這裡的模型不單單指的是預製模型,可以是Project檢視下的任何東西),也可以是多個模型,但兩種打包方式佔用的空間不一樣。
比如我打包三個一樣的模型(只不過他們的指令碼不一樣建立三個空的GameObject(One,Two,Three),分別掛載指令碼One,Two,Three)。如果我為每個模型單獨打包生成One,Two,Three三個Assetbundle,其所佔的空間是A,B,C,但是A+B+C != D.由此可知想通的資源儘可能的打包到一起,他們共用一套資源。不相同的模型儘量分開打包。
二、分開打包(注意這個指令碼必須放在Editor資料夾內,Editor資料夾沒有的話需自己建立)
[csharp] view plain copy print?- /// <summary>
- /// 將選中的預製分別打包
- /// </summary>
- [MenuItem("AssetBundleDemo/Create AssetBundles By themselves")]
- staticvoid CreateAssetBundleThemelves(){
- //獲取要打包的物件(在Project檢視中)
- Object[] selects = Selection.GetFiltered (typeof
- //遍歷選中的物件
- foreach(Object obj in selects){
- //這裡建立一個本地測試
- //注意本地測試中可以是任意的檔案,但是到了移動平臺只能讀取路徑StreamingAssets裡面的
- //StreamingAssets是隻讀路徑,不能寫入
- string targetPath = Application.dataPath + "/AssetBundleLearn/StreamingAssets/" + obj.name + ".assetbundle"
- if(BuildPipeline.BuildAssetBundle(obj,null,targetPath,BuildAssetBundleOptions.CollectDependencies)){
- Debug.Log(obj.name + "is packed successfully!");
- }else{
- Debug.Log(obj.name + "is packed failly!");
- }
- }
- //重新整理編輯器(不寫的話要手動重新整理,否則打包的資源不能及時在Project檢視內顯示)
- AssetDatabase.Refresh ();
- }
SelectionMode.DeepAssets
這個選擇模式意味著如果選擇中包含多個檔案,那麼他將包含這個檔案檢視中的所有資源。
他還有其他的各種選項(以下是官方文件)
SelectionMode
Description
SelectionMode can be used to tweak the selection returned by Selection.GetTransforms.
The default transform selection mode is: SelectionMode.TopLevel | SelectionMode.ExcludePrefab | SelectionMode.Editable.
Return the whole selection. | |
Only return the topmost selected transform. A selected child of another selected transform will be filtered out. | |
Deep | Return the selection and all child transforms of the selection. |
Excludes any prefabs from the selection. | |
Excludes any objects which shall not be modified. | |
Only return objects that are assets in the Asset directory. | |
If the selection contains folders, also include all assets and subfolders within that folder in the file hierarchy. |
最核心的方法:BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)
引數1:它只能放一個物件,因為我們這裡是分別打包,所以通過迴圈將每個物件分別放在了這裡。
引數2:可以放入一個數組物件。
引數3:要打包到的路徑
引數4:預設情況下打的包只能在電腦上用,如果要在手機上用就要新增一個引數。
BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.android)
iOS上:
BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.iPhone)
另外,電腦上和手機上打出來的Assetbundle不能混用,不同平臺只能用自己的。
三、一起打包[csharp] view plain copy print?- /// <summary>
- /// 將選中的預製打包到一起
- /// </summary>
- [MenuItem("AssetBundleDemo/Create AssetBundles Together")]
- staticvoid CreateAssetBundleTogether(){
- //要打包的物件
- Object[] selects = Selection.GetFiltered (typeof(Object),SelectionMode.DeepAssets);
- //要打包到的路徑
- string targetPath = Application.dataPath + "/AssetBundleLearn/StreamingAssets/Together.assetbundle";
- if(BuildPipeline.BuildAssetBundle(null,selects,targetPath,BuildAssetBundleOptions.CollectDependencies)){
- Debug.Log("Packed successfully!");
- }else{
- Debug.Log("Packed failly!");
- }
- //重新整理編輯器(不寫的話要手動重新整理)
- AssetDatabase.Refresh ();
- }
四、讀取
[csharp] view plain copy print?- using UnityEngine;
- using System.Collections;
- publicclass ReanAssetbundle : MonoBehaviour {
- //不同平臺下StreamingAssets的路徑是不同的,這裡需要注意一下。
- publicstaticreadonlystring m_PathURL =
- #if UNITY_ANDROID
- "jar:file://" + Application.dataPath + "!/assets/";
- #elif UNITY_IPHONE
- Application.dataPath + "/Raw/";
- #elif UNITY_STANDALONE_WIN || UNITY_EDITOR
- "file://" + Application.dataPath + "/AssetBundleLearn/StreamingAssets/";
- #else
- string.Empty;
- #endif
- void OnGUI(){
- if(GUILayout.Button("載入分開打包的Assetbundle")){
- StartCoroutine(LoadGameObjectPackedByThemselves(m_PathURL + "One.assetbundle"));
- StartCoroutine(LoadGameObjectPackedByThemselves(m_PathURL + "Two.assetbundle"));
- StartCoroutine(LoadGameObjectPackedByThemselves(m_PathURL + "Three.assetbundle"));
- }
- if(GUILayout.Button("載入打包在一起的Assetbundle")){
- StartCoroutine(LoadGameObjectPackedTogether(m_PathURL + "Together.assetbundle"));
- }
- }
- //單獨讀取資源
- private IEnumerator LoadGameObjectPackedByThemselves(string path){
- WWW bundle = new WWW (path);
- yield return bundle;
- //載入
- yield return Instantiate (bundle.assetBundle.mainAsset);
- bundle.assetBundle.Unload (false);
- }
- IEnumerator LoadGameObjectPackedTogether (string path)
- {
- WWW bundle = new WWW (path);
- yield return bundle;
- Object one = bundle.assetBundle.Load ("One");
- Object two = bundle.assetBundle.Load ("Two");
- Object three = bundle.assetBundle.Load ("Three");
- //載入
- yield return Instantiate (one);
- yield return Instantiate (two);
- yield return Instantiate (three);
- bundle.assetBundle.Unload (false);
- }
- }
推薦一個視覺化打包工具,寫了個詳細的說明,而且可以簡單實現資源的複用,避免重複打包