Unity5 AssetBundle系列——簡單的AssetBundleManager


  一個AssetBundle同時只能加載一次,所以實際使用中一般會伴隨着AssetBundle包的管理。

  下面是一個簡單的AssetBundle管理器,提供了同步和異步加載函數:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class AssetBundleManager
{
    public static AssetBundleManager Instace
    {
        get
        {
            if (_instace == null) _instace = new AssetBundleManager();
            return _instace;
        }
    }
    private static AssetBundleManager _instace = null;

    private AssetBundleManifest manifest = null;
    private Dictionary<string, AssetBundle> dicAssetBundle = new Dictionary<string, AssetBundle>();

    // filename : Assets全路徑,比如Assets/Prefab/***.prefab
    public AssetBundle GetAssetBundle(string filePath)
    {
        AssetBundle ab = null;
        dicAssetBundle.TryGetValue(AssetsNameToBundleName(filePath), out ab);
        return ab;
    }

    // 加載manifest,用來處理關聯資源
    public void LoadManifest()
    {
        AssetBundle bundle = AssetBundle.LoadFromFile(MainifestFilePath());
        manifest = bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
        // 壓縮包直接釋放掉
        bundle.Unload(false);
        bundle = null;
    }

    // filename : Assets全路徑,比如Assets/Prefab/***.prefab
    public AssetBundle Load(string filename)
    {
        string bundleName = AssetsNameToBundleName(filename);
        if (dicAssetBundle.ContainsKey(bundleName))
        {
            return dicAssetBundle[bundleName];
        }

        string[] dependence = manifest.GetAllDependencies(bundleName);
        for (int i = 0; i < dependence.Length; ++i)
        {
            LoadInternal(dependence[i]);
        }

        return LoadInternal(bundleName);
    }

    // filename : Assets全路徑,比如Assets/Prefab/***.prefab
    public IEnumerator LoadAsync(string filename)
    {
        string bundleName = AssetsNameToBundleName(filename);
        if (dicAssetBundle.ContainsKey(bundleName))
        {
            yield break;
        }

        string[] dependence = manifest.GetAllDependencies(bundleName);
        for (int i = 0; i < dependence.Length; ++i)
        {
            yield return LoadInternalAsync(dependence[i]);
        }

        yield return LoadInternalAsync(bundleName);
    }

    public void Unload(string filename, bool force = false)
    {
        string bundleName = AssetsNameToBundleName(filename);

        AssetBundle ab = null;
        if (dicAssetBundle.TryGetValue(bundleName, out ab) == false) return;

        if (ab == null) return;

        ab.Unload(force);
        ab = null;
        dicAssetBundle.Remove(bundleName);
    }

    public void UnloadUnusedAssets()
    {
        Resources.UnloadUnusedAssets();
        System.GC.Collect();
    }

    public void Release()
    {
        foreach(var pair in dicAssetBundle)
        {
            var bundle = pair.Value;
            if(bundle != null)
            {
                bundle.Unload(true);
                bundle = null;
            }
        }
        dicAssetBundle.Clear();
    }

    private AssetBundle LoadInternal(string bundleName)
    {
        if (dicAssetBundle.ContainsKey(bundleName))
        {
            return dicAssetBundle[bundleName];
        }

        AssetBundle bundle = AssetBundle.LoadFromFile(BundleNameToBundlePath(bundleName));
        dicAssetBundle.Add(bundleName, bundle);
        return bundle;
    }

    private IEnumerator LoadInternalAsync(string bundleName)
    {
        if (dicAssetBundle.ContainsKey(bundleName))
        {
            yield break;
        }

        AssetBundleCreateRequest req = AssetBundle.LoadFromFileAsync(BundleNameToBundlePath(bundleName));
        yield return req;

        dicAssetBundle.Add(bundleName, req.assetBundle);
    }

    // 名字依賴於存放目錄
    private string MainifestFilePath()
    {
        return Application.dataPath + "/StreamingAssets/StreamingAssets";
    }

    // Assets/Prefab/***.prefab --> assets.prefab.***.prefab.assetbundle
    private string AssetsNameToBundleName(string file)
    {
        string f = file.Replace('/', '.');
        f = f.ToLower();
        f += ".assetbundle";
        return f;
    }

    // assets.prefab.***.prefab.assetbundle --> C:/***path***/assets.prefab.***.prefab.assetbundle
    private string BundleNameToBundlePath(string bundleFilename)
    {
        return System.IO.Path.Combine(Application.dataPath + "/StreamingAssets/", bundleFilename);
    }

}

  當然bundle也可以通過WWW或其他的方式來加載,這一塊Unity5到沒有什么變化,具體使用方式可以參考我以前的博客。


免責聲明!

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



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