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到没有什么变化,具体使用方式可以参考我以前的博客。

posted @ 2017-05-19 20:45  斯芬克斯  阅读(3240)  评论(0编辑  收藏  举报