天天看點

unity AssetBudle 的引用計數(資源優化)

 首先寫一個類包含ab和ab對應的引用以及對應的解除安裝方法,在寫一個ab的管理類,包括全局ab的加載,解除安裝,以及相關根據引用數來判斷是重記憶體中是否删除對應的依賴資源,是建立資源還是重記憶體中擷取資源重而達到在ab适度顆粒話下的記憶體優化!

腳本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class AssetBundleInfos
{
    public AssetBundle assetBundle;
    public int referencedCount;//引用數
    internal event Action unload;

    internal void OnUnload()
    {
        assetBundle.Unload(false);
        if (unload != null)
            unload();
    }
}
public class Resource_LoadManager
{
    AssetBundleManifest assetBundleManifest = null;
    Dictionary<string, string[]> dependencies = new Dictionary<string, string[]>();
    Dictionary<string, AssetBundleInfos> loadeAssetBundle = new Dictionary<string, AssetBundleInfos>();

    // Use this for initialization
    public Resource_LoadManager()
    {
        //Initalize();

    }

    //初始化加載所有的依賴項目
    public void Initalize()
    {
        AssetBundle bundle;
        switch (Application.platform)
        {
            case RuntimePlatform.Android:
                bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(DataPath, "Android"));
                break;
            case RuntimePlatform.IPhonePlayer:
                bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(DataPath, "Ios"));
                break;
            case RuntimePlatform.WindowsEditor:
                bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(DataPath, "Android"));
                break;
            case RuntimePlatform.OSXEditor:
                bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(DataPath, "Ios"));
                break;
            default:
                bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(DataPath, "StandaloneWindows"));
                break;
        }
        assetBundleManifest = bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
        // 壓縮包釋放掉
        bundle.Unload(false);
        bundle = null;
        // depengcies = manifest.GetDirectDependencies("cube.assetbundle");
        //加載所有的依賴項
    }
    public static string DataPath
    {
        get
        {
            string game = "Framework";//AppConst.AppName.ToLower();
            if (Application.isMobilePlatform)
            {
                return Application.persistentDataPath + "/" + game + "/";
            }

            if (Application.platform == RuntimePlatform.OSXEditor)//mac平台
            {
                int i = Application.dataPath.LastIndexOf('/');
                return Application.dataPath.Substring(0, i + 1) + game + "/";
            }
            //return Application.dataPath + "/" + "StreamingAssets" + "/";
            return "d:/" + game + "/";//window本地位址
        }
    }
    //加載assetBundle的操作
    public AssetBundle Load_assetBundle(string abName)
    {
        if (abName.Contains("\\"))
            abName = abName.Replace("\\", "/");
        if (abName.Contains("/."))
            abName = abName.Replace("/.", ".");
        AssetBundleInfos ab = Get_AssetBundle(abName);
        if (ab == null)
        {
            //新增加的ab處理
            AssetBundle abNew = AssetBundle.LoadFromFile(System.IO.Path.Combine(DataPath, abName));

            if (abNew == null)
            {
                Debug.LogError(abName + " isnot exist file of in" + DataPath);
                return null;
            }
            AssetBundleInfos newAssetInfo = new AssetBundleInfos();
            newAssetInfo.assetBundle = abNew;
            newAssetInfo.referencedCount++;
            loadeAssetBundle.Add(abNew.name, newAssetInfo);
            //擷取加載的ab 對應的依賴
            string[] denpengcess = assetBundleManifest.GetDirectDependencies(abName);
            for (int i = 0; i < denpengcess.Length; i++)
            {
                string depName = denpengcess[i];
                AssetBundleInfos bundleInfo = null;
                //給對應的依賴資源增加引用數
                if (loadeAssetBundle.TryGetValue(depName, out bundleInfo))
                {
                    bundleInfo.referencedCount++;
                }
                else
                {
                    Load_assetBundle(depName);
                }

            }
            dependencies.Add(abName, assetBundleManifest.GetDirectDependencies(abName));
            return abNew;
        }
        else
        {
            ab.referencedCount++;
            return ab.assetBundle;
        }
    }

    //從集合中查找對象是否已經被加載
    AssetBundleInfos Get_AssetBundle(string abName)
    {
        AssetBundleInfos abInfo = null;
        if (!loadeAssetBundle.TryGetValue(abName, out abInfo))
        {
            return null;
        }
        return abInfo;
    }

    #region 解除安裝
    /// <summary>
    /// Unloads assetbundle and its dependencies.
    /// </summary>
    public void UnloadAssetBundle(string assetBundleName)
    {

        UnloadAssetBundleInternal(assetBundleName);
    }

    protected void UnloadDependencies(string assetBundleName)
    {
        string[] dependenciesNes = null;
        if (!dependencies.TryGetValue(assetBundleName, out dependenciesNes))
            return;
        // Loop dependencies.
        foreach (var dependency in dependenciesNes)
        {
            UnloadAssetBundle(dependency);
        }
        dependencies.Remove(assetBundleName);
    }

    protected void UnloadAssetBundleInternal(string assetBundleName)
    {
        //string error;
        AssetBundleInfos bundle = Get_AssetBundle(assetBundleName);
        if (bundle == null)
            return;
        //計數減少 後對應的資源沒有引用了處理
        if (--bundle.referencedCount <= 0)
        { 
            //對依賴資源的依賴處理
            UnloadDependencies(assetBundleName);
            bundle.OnUnload();
          //移除緩存
            loadeAssetBundle.Remove(assetBundleName);
        }
        else
        {
            --bundle.referencedCount;
        }
    }
    #endregion
    #region 加載

    #endregion

}