下面代碼列出了對於assetbundle資源的常用操作,其中有針對bundle、asset、gameobject三種類型對象的操作,實際使用中盡量保證成對使用。
這一塊的操作比較繁瑣,但只要使用正確,是可以保證資源完全沒有泄露的。
using UnityEngine; using System.Collections; public class TestAssetBundle : MonoBehaviour { public string AssetBundleName = "cube1.assetbundle"; private string dir = ""; private AssetBundle bundle = null; private UnityEngine.Object asset = null; private GameObject go = null; private void Start() { dir = Application.dataPath + "/StreamingAssets/"; } private void OnGUI() { // 這些操作一遍走下來,申請的資源是可以完全回收的 if (GUILayout.Button("LoadAssetBundle", GUILayout.Width(200), GUILayout.Height(50))) { LoadBundle(); } if (GUILayout.Button("LoadAsset", GUILayout.Width(200), GUILayout.Height(50))) { LoadAsset(); } if (GUILayout.Button("Instantiate", GUILayout.Width(200), GUILayout.Height(50))) { Instantiate(); } if (GUILayout.Button("Destroy", GUILayout.Width(200), GUILayout.Height(50))) { Destroy(); } if (GUILayout.Button("Unload", GUILayout.Width(200), GUILayout.Height(50))) { Unload(); } if (GUILayout.Button("UnloadForce", GUILayout.Width(200), GUILayout.Height(50))) { UnloadForce(); } if (GUILayout.Button("UnloadUnusedAssets", GUILayout.Width(200), GUILayout.Height(50))) { UnloadUnusedAssets(); } } // 加載AssetBundle private void LoadBundle() { bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(dir, AssetBundleName)); if (bundle == null) Debug.LogError("LoadBundle Failed"); } // 從AssetBundle加載Asset private void LoadAsset() { if (bundle == null) return; asset = bundle.LoadAsset("Cube1"); if (asset == null) Debug.LogError("LoadAsset Failed"); } // 根據Asset實例化GameObject private void Instantiate() { if (asset == null) return; go = GameObject.Instantiate(asset) as GameObject; if (go == null) Debug.LogError("Instantiate Failed"); } // 銷毀GameObject private void Destroy() { if (go == null) return; GameObject.Destroy(go); go = null; } // 弱卸載,釋放AssetBundle本身的內存 private void Unload() { if (bundle == null) return; // unload完,bundle就不能再用了,記得要置空 bundle.Unload(false); asset = null; bundle = null; } // 強卸載(無視引用的卸載),釋放AssetBundle本身的內存,同時回收從AssetBundle抽取的Asset private void UnloadForce() { if (bundle == null) return; // unload完,bundle就不能再用了,記得要置空 bundle.Unload(true); asset = null; bundle = null; } // 全局弱卸載,回收無引用Asset private void UnloadUnusedAssets() { Resources.UnloadUnusedAssets(); } }
由於bundle相互之前會有依賴,所以在使用一個bundle包之前,需要先加載其依賴的所有bundle包,這個過程需要借助全局manifest來實現,簡單代碼如下:
using UnityEngine; using System.Collections; public class TestManifest : MonoBehaviour { private string dir = ""; private GameObject go = null; private AssetBundleManifest manifest = null; private void Start() { dir = Application.dataPath + "/StreamingAssets/"; } private void OnGUI() { if (GUILayout.Button("LoadAssetBundleManifest", GUILayout.Width(200), GUILayout.Height(50))) { LoadAssetBundleManifest(); } if (GUILayout.Button("LoadBundle", GUILayout.Width(200), GUILayout.Height(50))) { LoadBundle(); } } // 加載Manifest private void LoadAssetBundleManifest() { var bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(dir, "StreamingAssets")); manifest = bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest"); // 壓縮包釋放掉 bundle.Unload(false); bundle = null; } // 加載AssetBundle private void LoadBundle() { string bundleName = "assets.resources.test.cube1.prefab.assetbundle"; // 注意:GetAllDependencies會返回直接和間接關聯的AssetBundle // 加載依賴包沒有順序要求 string[] dependence = manifest.GetAllDependencies(bundleName); for (int i = 0; i < dependence.Length; ++i ) { AssetBundle.LoadFromFile(System.IO.Path.Combine(dir, dependence[i])); // 注意:這里不需要手動LoadAsset // 只需要加載AssetBundle即可 // Asset會在加載其它關聯Asset時自動加載 } var bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(dir, bundleName)); var asset = bundle.LoadAsset("Cube1"); go = GameObject.Instantiate(asset) as GameObject; } }
