Unity5 AssetBundle系列——資源加載卸載以及AssetBundleManifest的使用


  下面代碼列出了對於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;
    }
}

 


免責聲明!

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



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